Class: Class
Instance Method Summary collapse
-
#alias_attribute(aliaz, attribute) ⇒ Object
private
Creates an alias for each accessor method of the given attribute.
-
#attr_create_on_demand_accessor(symbol) {|obj| ... } ⇒ Object
private
Defines an instance variable accessor attribute whose reader calls the block given to this method to create a new instance variable on demand, if necessary.
-
#class_hierarchy ⇒ Object
Returns an Enumerable on this class and its ancestors.
-
#each_class_in_hierarchy {|klass| ... } ⇒ Object
private
Enumerates each class in the hierarchy.
-
#offset_attr_accessor(hash, offset = nil) ⇒ Object
private
Creates new accessor methods for each method => original hash entry.
-
#redefine_method(method) {|old_method| ... } ⇒ Symbol
private
Redefines method using the given block.
Instance Method Details
#alias_attribute(aliaz, attribute) ⇒ Object (private)
Creates an alias for each accessor method of the given attribute.
30 31 32 33 34 |
# File 'lib/jinx/helpers/class.rb', line 30 def alias_attribute(aliaz, attribute) alias_method(aliaz, attribute) if method_defined?(attribute) writer = "#{attribute}=".to_sym alias_method("#{aliaz}=".to_sym, writer) if method_defined?(writer) end |
#attr_create_on_demand_accessor(symbol) {|obj| ... } ⇒ Object (private)
Defines an instance variable accessor attribute whose reader calls the block given to this method to create a new instance variable on demand, if necessary.
For example, the declaration
class AlertHandler
attr_create_on_demand_accessor(:pings) { Array.new }
end
is equivalent to:
class AlertHandler
attr_writer :pings
def pings
instance_variable_defined?(@pings) ? @pings : Array.new
end
end
This method is useful either as a short-hand for the create-on-demand idiom as shown in the example above, or when it is desirable to dynamically add a mix-in attribute to a class at runtime whose name is not known when the class is defined.
94 95 96 97 98 99 100 101 102 |
# File 'lib/jinx/helpers/class.rb', line 94 def attr_create_on_demand_accessor(symbol) attr_writer(symbol) wtr = "#{symbol}=".to_sym iv = "@#{symbol}".to_sym # the attribute reader creates a new value on demand define_method(symbol) do instance_variable_defined?(iv) ? instance_variable_get(iv) : send(wtr, yield(self)) end end |
#class_hierarchy ⇒ Object
Returns an Enumerable on this class and its ancestors.
5 6 7 |
# File 'lib/jinx/helpers/class.rb', line 5 def class_hierarchy @class__hierarchy ||= Enumerable::Enumerator.new(self, :each_class_in_hierarchy) end |
#each_class_in_hierarchy {|klass| ... } ⇒ Object (private)
Enumerates each class in the hierarchy.
108 109 110 111 112 113 114 |
# File 'lib/jinx/helpers/class.rb', line 108 def each_class_in_hierarchy current = self until current.nil? yield current current = current.superclass end end |
#offset_attr_accessor(hash, offset = nil) ⇒ Object (private)
Creates new accessor methods for each method => original hash entry. The new method offsets the existing Number original attribute value by the given offset (default -1).
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/jinx/helpers/class.rb', line 47 def offset_attr_accessor(hash, offset=nil) offset ||= -1 hash.each do |method, original| define_method(method) { value = send(original); value + offset if value } if method_defined?(original) original_writer = "#{original}=".to_sym if method_defined?(original_writer) then define_method("#{method}=".to_sym) do |value| adjusted = value - offset if value send(original_writer, adjusted) end end end end |
#redefine_method(method) {|old_method| ... } ⇒ Symbol (private)
Redefines method using the given block. The block argument is a new alias for the old method. The block creates a proc which implements the new method body.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/jinx/helpers/class.rb', line 125 def redefine_method(method) # Make a new alias id method__base for the existing method. # Disambiguate with a counter suffix if necessary. counter = 2 # Make a valid alias base. The base includes this class's object id in order # to ensure uniqueness within the class hierarchy. This alias uniqueness # guards against a superclass occluding a subclass redefinition. old, eq = /^([^=]*)(=)?$/.match(method.to_s).captures old.tr!('|', 'or') old.tr!('&', 'and') old.tr!('+', 'plus') old.tr!('*', 'mult') old.tr!('/', 'div') old.gsub!(/[^\w]/, 'op') base = "redefined__#{object_id}_#{old}" # Make a unique method alias for the old method. old_sym = "#{base}#{eq}".to_sym while method_defined?(old_sym) old_sym = "#{base}#{counter}#{eq}".to_sym counter = counter + 1 end # Alias the old method before it is replaced. alias_method(old_sym, method) # The body defines the new method given the old method. body = yield old_sym define_method(method, body) old_sym end |