Class Module
In: lib/more/facets/module/attr_tester.rb
lib/more/facets/module/attr_toggler.rb
lib/more/facets/module/attr.rb
lib/more/facets/module/class_extend.rb
lib/more/facets/module/attr_validator.rb
lib/more/facets/capsule.rb
lib/more/facets/methodspace.rb
lib/more/facets/equitable.rb
lib/more/facets/instance_function.rb
Parent: Object

TODO Is autoimport bets name for this?

Methods

Classes and Modules

Module Module::InstanceFunction

External Aliases

attr_accessor! -> attr_toggler
append_features -> append_features_without_class_extension
const_missing -> const_missing_before_autoimport
  $autoimport_activated = true

Public Class methods

[Source]

    # File lib/more/facets/module/class_extend.rb, line 87
87:       def self.append_features(mod)
88:         append_features_without_class_extension(mod)
89:       end

Public Instance methods

This function provided a "shortcut" for creating the identity method based on given accessors and returns the Equitable module for inclusion.

 include Equitable(:a, :b)

is equivalent to including a module containing:

  def ==(other)
    self.a == other.a && self.b == other.b
  end

  def eql?(other)
    self.a.eql?(other.a) && self.b.eql?(other.b)
  end

  def hash()
    self.a.hash ^ self.b.hash
  end

[Source]

     # File lib/more/facets/equitable.rb, line 115
115:   def Equitable(*accessors)
116:     Equitable.identify(self, *accessors)
117:   end

Create aliases for flag accessors.

CREDIT: Trans

[Source]

    # File lib/more/facets/module/attr.rb, line 32
32:   def alias_accessor!(*args)
33:     orig = args.last
34:     args = args - [orig]
35:     args.each do |name|
36:       alias_method("#{name}?", "#{orig}?")
37:       alias_method("#{name}!", "#{orig}!")
38:     end
39:   end
alias_reader?(*args)

Alias for alias_tester

alias_switcher(*args)

Alias for alias_accessor!

Create aliases for flag reader.

CREDIT: Trans

[Source]

    # File lib/more/facets/module/attr_tester.rb, line 34
34:   def alias_tester(*args)
35:     orig = args.last
36:     args = args - [orig]
37:     args.each do |name|
38:       alias_method("#{name}?", "#{orig}?")
39:     end
40:   end
alias_toggler(*args)

Alias for alias_accessor!

Create aliases for attr_toggler.

CREDIT: Trans

[Source]

    # File lib/more/facets/module/attr_toggler.rb, line 49
49:   def alias_toggler(*args)
50:     orig = args.last
51:     args = args - [orig]
52:     args.each do |name|
53:       alias_method("#{name}!", "#{orig}!")
54:       alias_method("#{name}?", "#{orig}?")
55:     end
56:   end

Create aliases for validators.

[Source]

    # File lib/more/facets/module/attr_validator.rb, line 24
24:   def alias_validator(*args)
25:     orig = args.last
26:     args = args - [orig]
27:     args.each do |name|
28:       #alias_method(name, orig)
29:       alias_method("#{name}=", "#{orig}=")
30:     end
31:   end

Create aliases for flag writer.

CREDIT: Trans

[Source]

    # File lib/more/facets/module/attr.rb, line 74
74:   def alias_writer!(*args)
75:     orig = args.last
76:     args = args - [orig]
77:     args.each do |name|
78:       alias_method("#{name}!", "#{orig}!")
79:     end
80:   end

Override append_features to handle class-inheritable extensions.

[Source]

     # File lib/more/facets/module/class_extend.rb, line 103
103:   def append_features(mod)
104:     append_features_without_class_extension(mod)
105:     mod.extend(class_extend)
106:     if mod.instance_of? Module
107:       mod.__send__(:class_extend).__send__(:include, class_extend)
108:     end
109:   end
attr_reader?(*args)

Alias for attr_tester

Create a toggle attribute. This creates two methods for each given name. One is a form of tester and the other is used to toggle the value.

  attr_accessor! :a

is equivalent to

  def a?
    @a
  end

  def a!(value=true)
    @a = value
    self
  end

CREDIT: Trans

[Source]

    # File lib/more/facets/module/attr.rb, line 22
22:   def attr_switch_accessor(*args)
23:     attr_reader!(*args) + attr_writer!(*args)
24:   end

Create an tester attribute. This creates a single method used to test the attribute for truth.

  attr_tester :a

is equivalent to

  def a?
    @a ? true : @a
  end

[Source]

    # File lib/more/facets/module/attr_tester.rb, line 14
14:   def attr_tester(*args)
15:     code, made = '', []
16:     args.each do |a|
17:       code << %{
18:         def #{a}?(truth=nil)
19:           @#{a} ? truth || @#{a} : @#{a}
20:         end
21:       }
22:       made << "#{a}?".to_sym
23:     end
24:     module_eval code
25:     made
26:   end

Create a flaggable attribute. This creates a single methods used to set an attribute to "true".

  attr_toggler :a

is equivalent to

  def a?
    @a ? true : @a
  end

  def a!(value=Exception)
    if Exception
      @a = @a ? false : true
    else
      @a = value
    end
    self
  end

[Source]

    # File lib/more/facets/module/attr_toggler.rb, line 25
25:   def attr_toggler(*args)
26:     code, made = '', []
27:     args.each do |a|
28:       code << %{
29:         def #{a}!(value=Excception)
30:           if Exception
31:             @a = @a ? false : true
32:           else 
33:             @a = value
34:           end
35:           self
36:         end
37:       }
38:       made << "#{a}!".to_sym
39:     end
40:     module_eval code
41:     made.concat(attr_tester(*args))
42:     made
43:   end

Like attr_writer, but the writer method validates the setting against the given block.

CREDIT: ?

[Source]

    # File lib/more/facets/module/attr_validator.rb, line 8
 8:   def attr_validator(*symbols, &validator)
 9:     made = []
10:     symbols.each do |symbol|
11:       define_method "#{symbol}=" do |val|
12:         unless validator.call(val)
13:           raise ArgumentError, "Invalid value provided for #{symbol}"
14:         end
15:         instance_variable_set("@#{symbol}", val)
16:       end
17:       made << "#{symbol}=".to_sym
18:     end
19:     made
20:   end

Create a flaggable attribute. This creates a single methods used to set an attribute to "true".

  attr_writer! :a

is equivalent to

  def a!(value=true)
    @a = value
    self
  end

[Source]

    # File lib/more/facets/module/attr.rb, line 55
55:   def attr_writer!(*args)
56:     code, made = '', []
57:     args.each do |a|
58:       code << %{
59:         def #{a}!(value=true)
60:           @#{a} = value
61:           self
62:         end
63:       }
64:       made << "#{a}!".to_sym
65:     end
66:     module_eval code
67:     made
68:   end

Normally when including modules, class/module methods are not extended. To achieve this behavior requires some clever Ruby Karate. Instead class_extension provides an easy to use and clean solution. Simply place the extending class methods in a block of the special module method class_extension.

  module Mix
    def inst_meth
      puts 'inst_meth'
    end

    class_extend do
      def class_meth
        "Class Method!"
      end
    end
  end

  class X
    include Mix
  end

  X.class_meth  #=> "Class Method!"

NOTE: This old class_extension version of this method did not extend the containing class automatically —it had to be done by hand. With class_extend, that is no longer the case.

[Source]

    # File lib/more/facets/module/class_extend.rb, line 85
85:   def class_extend(*mods, &block)
86:     @class_extension ||= Module.new do
87:       def self.append_features(mod)
88:         append_features_without_class_extension(mod)
89:       end
90:     end
91:     @class_extension.__send__(:include, *mods)
92:     @class_extension.module_eval(&block) if block_given?
93:     extend(@class_extension)  # extend this module too
94:     @class_extension
95:   end
class_extension(*mods, &block)

Alias for class_extend

Include a module via a specified space.

  module T
    def t ; "HERE" ; end
  end

  class X
    include_as :test => T
    def t ; test.t ; end
  end

  X.new.t  #=> "HERE"

[Source]

     # File lib/more/facets/methodspace.rb, line 103
103:   def include_as(h)
104:     h.each{ |name, mod| method_space(name, mod) }
105:   end

Converts module methods into instance methods such that the first parameter is passed self. This promotes DRY programming when wishing to offer both inheritable and module callable procedures.

This method is modeled after module_function which essentially has the the opposite effect. Due to implementation limitations, this must use the callback singleton_method_added to emulate module_function when no method names are given.

  module MyModule
    instance_function

    def self.jumble( obj, arg )
      obj + arg
    end
  end

  class String
    include MyModule
  end

  MyModule.jumble( "Try", "Me" )  #=> "TryMe"

  "Try".jumble( "Me" )            #=> 'TryMe'

Note: This used to be a module called PromoteSelf and later Instantize, before becoming a method.

[Source]

    # File lib/more/facets/instance_function.rb, line 30
30:   def instance_function(*meths)
31:     if meths.empty?
32:       extend InstanceFunction
33:     else
34:       meths.each do |meth|
35:         class_eval %{
36:           def #{meth}(*args)
37:             #{self.name}.#{meth}(self,*args)
38:           end
39:         }
40:       end
41:     end
42:   end

Define a simple method namespace.

  class A
    attr_writer :x
    method_space :inside do
      def x; @x; end
    end
  end

  a = A.new
  a.x = 10
  a.inside.x #=> 10
  a.x  # no method error

[Source]

    # File lib/more/facets/methodspace.rb, line 48
48:   def method_space(name, mod=nil, &blk)
49: 
50:     # If block is given then create a module, otherwise
51:     # get the name of the module.
52:     if block_given?
53:       name = name.to_s
54:       raise ArgumentError if mod
55:       mod  = Module.new(&blk)
56:     else
57:       if Module === name
58:         mod = name
59:         name = mod.basename.downcase
60:       end
61:       mod  = mod.dup
62:     end
63: 
64:     # Include the module. This is neccessary, otherwise
65:     # Ruby won't let us bind the instance methods.
66:     include mod
67: 
68:     # Save the instance methods of the module and
69:     # replace them with a "transparent" version.
70:     methods = {}
71:     mod.instance_methods(false).each do |m|
72:       methods[m.to_sym] = mod.instance_method(m)
73:       mod.instance_eval do
74:         define_method(m) do
75:           super
76:         end
77:       end
78:     end
79: 
80:     # Add a method for the namespace that delegates
81:     # via the Functor to the saved instance methods.
82:     define_method(name) do
83:       mtab = methods
84:       Functor.new do |op, *args|
85:         mtab[op].bind(self).call(*args)
86:       end
87:     end
88:   end

[Validate]