It would nice if we could the following. Then the middle portion of the #Comparable method would not be needed. But I fear it might break others code.
module Comparable def <=>(other) comparability.each do |field| cmp = send(field) <=> other.send(field); return cmp unless cmp == 0 end end end
# File lib/more/facets/class_extend.rb, line 87 87: def self.append_features(mod) 88: append_features_without_class_extension(mod) 89: end
Rename methods.
module A def a; "a"; end end B = A * { :a => :b } class X; include B; end X.new.b #=> "a"
Thomas Sawyer, Robert Dober
# File lib/core/facets/module/op.rb, line 80 80: def *(rename_map) 81: base = self 82: Module.new do 83: include base 84: rename_map.each do |from, to| 85: alias_method to, from 86: undef_method from 87: end 88: end 89: end
Combine modules.
module A def a; "a"; end end module B def b; "b"; end end C = A + B class X; include C; end X.new.a #=> "a" X.new.b #=> "b"
Note that in the old version of traits.rb we cloned modules and altered their copies. Eg.
def +(other) mod1 = other.clone mod2 = clone mod1.module_eval{ include mod2 } end
Later it was realized that this thwarted the main benefit that Ruby’s concept of modules has over traditional traits, inheritance.
CREDIT: Thomas Sawyer, Robert Dober
# File lib/core/facets/module/op.rb, line 35 35: def +(other) 36: base = self 37: Module.new do 38: include base 39: include other 40: end 41: end
Subtract modules.
TODO: Should this use all instance_methods, not just public?
CREDIT: Thomas Sawyer, Robert Dober
# File lib/core/facets/module/op.rb, line 49 49: def -(other) 50: case other 51: when Array 52: subtract = instance_methods(true) & other.collect{|m| m.to_s} 53: when Module 54: subtract = instance_methods(true) & other.instance_methods(true) # false? 55: when String, Symbol 56: subtract = instance_methods(true) & [other.to_s] 57: end 58: base = self 59: Module.new do 60: include base 61: subtract.each{ |x| undef_method x } 62: end 63: end
Automatically generate sorting definitions based on attribute fields.
include Comparable(:a, :b)
is equivalent to including a module containing:
def <=>(other) cmp = self.a <=> other.a; return cmp unless cmp == 0 cmp = self.b <=> other.b; return cmp unless cmp == 0 0 end
# File lib/core/facets/comparable/comparable.rb, line 28 28: def Comparable(*accessors) 29: define_method(:comparability){ accessors } 30: code = %{ 31: def <=>(other) 32: comparability.each do |a| 33: cmp = (send(a) <=> other.send(a)); return cmp unless cmp == 0 34: end 35: end 36: } 37: module_eval code 38: return Comparable 39: end
This function provided a “shortcut” for creating the # 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
# File lib/more/facets/equitable.rb, line 115 115: def Equitable(*accessors) 116: Equitable.identify(self, *accessors) 117: end
Create an abstract method. If it is not overridden, it will raise a TypeError when called.
class C abstract :a end c = C.new c.a #=> Error: undefined abstraction #a
CREDIT: Trans
# File lib/core/facets/module/abstract.rb, line 15 15: def abstract( *sym ) 16: sym.each { |s| 17: define_method( s ) { raise TypeError, "undefined abstraction ##{s}" } 18: } 19: end
Create aliases for flag accessors.
CREDIT: Trans
# 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
Encapsulates the common pattern of:
alias_method :foo_without_feature, :foo alias_method :foo, :foo_with_feature
With this, you simply do:
alias_method_chain :foo, :feature
And both aliases are set up for you.
Query and bang methods (foo?, foo!) keep the same punctuation:
alias_method_chain :foo?, :feature
is equivalent to
alias_method :foo_without_feature?, :foo? alias_method :foo?, :foo_with_feature?
so you can safely chain foo, foo?, and foo! with the same feature.
CREDIT: Bitsweat, Rails Team
# File lib/core/facets/module/alias_method_chain.rb, line 27 27: def alias_method_chain(target, feature) 28: # Strip out punctuation on predicates or bang methods since 29: # e.g. target?_without_feature is not a valid method name. 30: aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1 31: yield(aliased_target, punctuation) if block_given? 32: 33: with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}" 34: 35: alias_method without_method, target 36: alias_method target, with_method 37: 38: case 39: when public_method_defined?(without_method) 40: public target 41: when protected_method_defined?(without_method) 42: protected target 43: when private_method_defined?(without_method) 44: private target 45: end 46: end
Alias an accessor. This create an alias for both a reader and a writer.
class X attr_accessor :a alias_accessor :b, :a end x = X.new x.b = 1 x.a #=> 1
CREDIT: Trans
# File lib/core/facets/module/attr_setter.rb, line 49 49: def alias_setter(*args) 50: args = args - [orig] 51: args.each do |name| 52: alias_method(name, orig) 53: end 54: end
Create aliases for flag reader.
CREDIT: Trans
# 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
Create aliases for attr_toggler.
CREDIT: Trans
# 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.
# 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
# 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
List all instance methods, equivalent to
public_instance_methods + protected_instance_methods + private_instance_methods
TODO: Better name for #
CREDIT: Trans
# File lib/core/facets/module/instance_methods.rb, line 13 13: def all_instance_methods(include_super=true) 14: public_instance_methods(include_super) + 15: protected_instance_methods(include_super) + 16: private_instance_methods(include_super) 17: end
Is a given class or module an ancestor of this class or module?
class X ; end class Y < X ; end X.ancestor?(Y)
# File lib/core/facets/module/ancestor.rb, line 11 11: def ancestor?( mod ) 12: ancestors.include? mod 13: end
Override append_features to handle class-inheritable extensions.
# File lib/more/facets/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
Create an attribute method for both getting and setting an instance variable.
attr_setter :a
_is equivalent to_
def a(*args) if args.size > 0 @a = args[0] self else @a end end
CREDIT: Trans
# File lib/core/facets/module/attr_setter.rb, line 21 21: def attr_setter(*args) 22: code, made = '', [] 23: args.each do |a| 24: code << %{ 25: def #{a}(*args) 26: args.size > 0 ? ( @#{a}=args[0] ; self ) : @#{a} 27: end 28: } 29: made << "#{a}".to_sym 30: end 31: module_eval code 32: made 33: end
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
# 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
# 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
# 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: ?
# 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
# 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
Returns the root name of the module/class.
module Example class Demo end end Demo.name #=> "Example::Demo" Demo.basename #=> "Demo"
For anonymous modules this will provide a basename based on Module#inspect.
m = Module.new m.inspect #=> "#<Module:0xb7bb0434>" m.basename #=> "Module_0xb7bb0434"
CREDIT: Trans
# File lib/core/facets/module/basename.rb, line 22 22: def basename 23: if name and not name.empty? 24: name.gsub(/^.*::/, '') 25: else 26: nil #inspect.gsub('#<','').gsub('>','').sub(':', '_') 27: end 28: end
Defines an instance method within a class/module.
CREDIT: WhyTheLuckyStiff
# File lib/core/facets/module/module_def.rb, line 7 7: def class_def name, &blk 8: class_eval { define_method name, &blk } 9: end
Normally when including modules, class/module methods are not extended. To achieve this behavior requires some clever Ruby Karate. Instead # provides an easy to use and clean solution. Simply place the extending class methods in a block of the special module method #.
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 # version of this method did not extend the containing class automatically —it had to be done by hand. With #, that is no longer the case.
# File lib/more/facets/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
Detect conflicts.
module A def c; end end module B def c; end end A.conflict?(B) #=> ["c"] TODO: All instance methods, or just public?
CREDIT: Thomas Sawyer, Robert Dober
# File lib/core/facets/module/conflict.rb, line 20 20: def conflict?(other) 21: common_ancestor = (ancestors & other.ancestors).first 22: c = [] 23: c += (public_instance_methods(true) & other.public_instance_methods(true)) 24: c += (private_instance_methods(true) & other.private_instance_methods(true)) 25: c += (protected_instance_methods(true) & other.protected_instance_methods(true)) 26: c -= common_ancestor.public_instance_methods(true) 27: c -= common_ancestor.private_instance_methods(true) 28: c -= common_ancestor.protected_instance_methods(true) 29: c.empty? ? false : c 30: end
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"
# File lib/more/facets/methodspace.rb, line 108 108: def include_as(h) 109: h.each{ |name, mod| method_space(name, mod) } 110: 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 # 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.
# 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
Access method as a singleton object and retain state.
module K def hello puts "Hello World!" end end p K.instance_method!(:hello) #=> <UnboundMethod: #hello>
NOTE: This is limited to the scope of the current module/class.
# File lib/core/facets/module/instance_method.rb, line 17 17: def instance_method!(s) 18: #( @@__instance_methods__ ||= {} )[s] ||= instance_method(s) # TODO: use class vars for 1.9+ ? 19: #( @__instance_methods__ ||= {} )[s.to_sym] ||= instance_method(s.to_sym) 20: $FIRST_CLASS_INSTANCE_METHODS[self][s.to_sym] ||= instance_method(s.to_sym) 21: end
Query whether a public instance method is defined for the module.
CREDIT: Gavin Sinclair, Noah Gibbs
# File lib/core/facets/module/instance_methods.rb, line 23 23: def instance_method_defined?(meth) 24: instance_methods(true).find{ |m| m == meth.to_s } 25: end
Using integrate is just like using include except the module included is a reconstruction of the one given altered by the commands given in the block.
Convenient commands available are: #, #, #, # and #. But any module method can be used.
module W def q ; "q" ; end def y ; "y" ; end end class X integrate W do nodef :y end end x = X.new x.q #=> "q" x.y #=> missing method error
This is like #, but # only returns the reconstructred module. It does not include it.
CREDIT: Trans
# File lib/core/facets/module/revise.rb, line 51 51: def integrate(mod, &block) 52: #include mod.revisal( &blk ) 53: m = Module.new{ include mod } 54: m.class_eval(&block) 55: include m 56: end
An alias for #.
class X is Enumerable end
CREDIT: Trans
# File lib/core/facets/module/is.rb, line 25 25: def is(*mods) 26: mods.each do |mod| 27: if mod.const_defined?(:Self) 28: extend mod::Self 29: # pass it along if module 30: if instance_of?(Module) 31: const_set(:Self, Module.new) unless const_defined?(:Self) 32: const_get(:Self).send(:include, mod::Self) 33: end 34: end 35: end 36: include(*mods) 37: end
Is a given class or module an ancestor of this class or module?
class X ; end class Y < X ; end Y.is?(X) #=> true
CREDIT: Trans
# File lib/core/facets/module/is.rb, line 13 13: def is?(base) 14: Module===base && ancestors.slice(1..1).include?(base) 15: 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
# 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.module_eval %{ 74: def #{m}(*a,&b) 75: super(*a,&b) 76: end 77: } 78: #mod.instance_eval do 79: #define_method(m) 80: # super 81: #end 82: #end 83: end 84: 85: # Add a method for the namespace that delegates 86: # via the Functor to the saved instance methods. 87: define_method(name) do 88: mtab = methods 89: Functor.new do |op, *args| 90: mtab[op].bind(self).call(*args) 91: end 92: end 93: end
Translate a module name to a suitable method name.
My::CoolClass.methodize => "my__cool_class"
# File lib/core/facets/module/methodize.rb, line 9 9: def methodize 10: name.methodize 11: end
Returns the module’s container module.
module Example class Demo end end Example::Demo.modspace #=> Example
See also Module#basename.
CREDIT: Trans
# File lib/core/facets/module/modspace.rb, line 16 16: def modspace 17: space = name[ 0...(name.rindex( '::' ) || 0)] 18: space.empty? ? Object : eval(space) 19: end
Defines an instance method within a class/module.
CREDIT: WhyTheLuckyStiff
# File lib/core/facets/module/module_def.rb, line 15 15: def module_def name, &blk 16: module_eval { define_method name, &blk } 17: end
Load file directly into module/class namespace.
Please use this with careful consideration. It is best suited to loading plugin-type scripts, and should generally not be used as a substitue for Ruby’s standard load system.
CREDIT: Trans
# File lib/core/facets/module/module_load.rb, line 12 12: def module_load( path ) 13: if path =~ /^[\/~.]/ 14: file = File.expand_path(path) 15: else 16: $LOAD_PATH.each do |lp| 17: file = File.join(lp,path) 18: break if File.exist?(file) 19: file = nil 20: end 21: end 22: raise LoadError, "no such file to load -- #{path}" unless file 23: module_eval(File.read(file)) 24: end
Require file into module/class namespace.
Unlike load this keeps a per-module cache and will not load the same file into the same module more than once despite repeated attempts.
The cache is kept in a global var called +$module_require+.
Please use this with careful consideration. It is best suited to loading plugin-type scripts, and should generally not be used as a substitue for Ruby’s standard load system.
CREDIT: Trans
# File lib/core/facets/module/module_load.rb, line 41 41: def module_require( path ) 42: if path =~ /^[\/~.]/ 43: file = File.expand_path(path) 44: else 45: $LOAD_PATH.each do |lp| 46: file = File.join(lp,path) 47: break if File.exist?(file) 48: file += '.rb' 49: break if File.exist?(file) 50: file = nil 51: end 52: end 53: raise LoadError, "no such file to load -- #{path}" unless file 54: # per-module load cache 55: $module_require ||= {} 56: $module_require[self] ||= {} 57: loaded = $module_require[self] 58: if loaded.key?(file) 59: false 60: else 61: loaded[file] = true 62: script = File.read(file) 63: module_eval(script) 64: true 65: end 66: end
Show a modules nesting in module namespaces.
A::B::C.nesting #=> [ A, A::B ]
CREDIT: Trans
# File lib/core/facets/module/nesting.rb, line 9 9: def nesting 10: n = [] 11: name.split(/::/).inject(self) do |mod, name| 12: c = mod.const_get(name) ; n << c ; c 13: end 14: return n 15: end
Converts a class name to a unix path
Examples
CoolClass.pathize #=> "cool_class" My::CoolClass.pathize #=> "my/cool_class"
# File lib/core/facets/module/pathize.rb, line 11 11: def pathize 12: name.pathize 13: #to_s. 14: # gsub(/::/, '/'). 15: # gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). 16: # gsub(/([a-z\d])([A-Z])/,'\1_\2'). 17: # tr("-", "_"). 18: # downcase 19: end
Prepend an aspect module to a module. This only works at the module level.
module X def x; "x"; end end module U def x; '{' + super + '}'; end end X.prepend U X.x # => "{x}"
CREDIT Trans
# File lib/core/facets/module/prepend.rb, line 20 20: def prepend(aspect) 21: aspect.__send__(:include, self) 22: extend aspect 23: end
Like #, but checks only private methods.
# File lib/core/facets/module/conflict.rb, line 46 46: def private_conflict?(other) 47: common_ancestor = (ancestors & other.ancestors).first 48: c = private_instance_methods(true) & other.private_instance_methods(true) 49: c -= common_ancestor.private_instance_methods(true) 50: c.empty? ? false : c 51: end
Like #, but checks only protected methods.
# File lib/core/facets/module/conflict.rb, line 54 54: def protected_conflict?(other) 55: common_ancestor = (ancestors & other.ancestors).first 56: c = protected_instance_methods(true) & other.protected_instance_methods(true) 57: c -= common_ancestor.protected_instance_methods(true) 58: c.empty? ? false : c 59: end
Like #, but checks only public methods.
# File lib/core/facets/module/conflict.rb, line 38 38: def public_conflict?(other) 39: common_ancestor = (ancestors & other.ancestors).first 40: c = public_instance_methods(true) & other.public_instance_methods(true) 41: c -= common_ancestor.public_instance_methods(true) 42: c.empty? ? false : c 43: end
Return a new module based on another. This includes the original module into the new one.
CREDIT: Trans
# File lib/core/facets/module/revise.rb, line 13 13: def revise(&blk) 14: base = self 15: nm = Module.new{ include base } 16: nm.class_eval(&blk) 17: nm 18: end
Sets an option to the given value. If the value is a proc, the proc will be called every time the option is accessed.
CREDIT: ? (Sinatra)
# File lib/core/facets/module/set.rb, line 10 10: def set(option, value=self, &block) 11: raise ArgumentError if block && value != self 12: value = block if block 13: if value.kind_of?(Proc) 14: if value.arity == 1 15: yield self 16: else 17: (class << self; self; end).module_eval do 18: define_method(option, &value) 19: define_method("#{option}?"){ !!__send__(option) } 20: define_method("#{option}="){ |val| set(option, Proc.new{val}) } 21: end 22: end 23: elsif value == self 24: option.each{ |k,v| set(k, v) } 25: elsif respond_to?("#{option}=") 26: __send__("#{option}=", value) 27: else 28: set(option, Proc.new{value}) 29: end 30: self 31: end
Query whether a normal (singleton) method is defined for the module.
CREDIT: Gavin Sinclair, Noah Gibbs
# File lib/core/facets/module/instance_methods.rb, line 31 31: def singleton_method_defined?(meth) 32: singleton_methods(true).find{ |m| m == meth.to_s } 33: end
Returns the name of module’s container module.
module Example class Demo end end Demo.name #=> "Example::Demo" Demo.spacename #=> "Example"
This used to be called dirname.
See also Module#basename.
CREDIT: Trans
# File lib/core/facets/module/spacename.rb, line 19 19: def spacename 20: name[0...(name.rindex('::') || 0)] 21: #name.gsub(/::[^:]*$/, '') 22: end
Creates a new method wrapping the previous of the same name. Reference to the old method is passed into the new definition block as the first parameter.
wrap_method( sym ) { |old_meth, *args| old_meth.call ... }
Keep in mind that this can not be used to wrap methods that take a block.
CREDIT: Trans
# File lib/core/facets/module/wrap_method.rb, line 20 20: def wrap_method( sym, &blk ) 21: old = instance_method(sym) 22: define_method(sym) { |*args| blk.call(old.bind(self), *args) } 23: end
As with alias_method, but alias both reader and writer.
attr_accessor :x self.x = 1 alias_accessor :y, :x y #=> 1 self.y = 2 x #=> 2
# File lib/core/facets/module/alias_accessor.rb, line 14 14: def alias_accessor(*args) 15: orig = args.last 16: args = args - [orig] 17: args.each do |name| 18: alias_method(name, orig) 19: alias_method("#{name}=", "#{orig}=") 20: end 21: end
Alias a module function so that the alias is also a module function. The typical # does not do this.
module Demo module_function def hello "Hello" end end Demo.hello #=> Hello module Demo alias_module_function( :hi , :hello ) end Demo.hi #=> Hello
# File lib/core/facets/module/alias_module_function.rb, line 24 24: def alias_module_function(new, old) 25: alias_method(new, old) 26: module_function(new) 27: end
As with alias_accessor, but just for the reader. This is basically the same as alias_method.
# File lib/core/facets/module/alias_accessor.rb, line 26 26: def alias_reader(*args) 27: orig = args.last 28: args = args - [orig] 29: args.each do |name| 30: alias_method(name, orig) 31: end 32: end
As with alias_method but does the writer instead.
# File lib/core/facets/module/alias_accessor.rb, line 36 36: def alias_writer(*args) 37: orig = args.last 38: args = args - [orig] 39: args.each do |name| 40: alias_method("#{name}=", "#{orig}=") 41: end 42: end
Include module and apply module_fuction to the included methods.
module Utils module_function def foo; "foo"; end end module UtilsPlus include_function_module Utils end
CREDIT: Trans
# File lib/core/facets/module/include_function_module.rb, line 19 19: def include_function_module *mod 20: include(*mod) 21: module_function(*mod.collect{|m| m.private_instance_methods & m.methods(false)}.flatten) 22: end
Creates a new method for a pre-existing method.
If aka is given, then the method being redefined will first be aliased to this name.
class Greeter def hello ; "Hello" ; end end Greeter.new.hello #=> "Hello" class Greeter redefine_method( :hello, :hi ) do hi + ", friend!" end end Greeter.new.hello #=> "Hello, friend!"
CREDIT: Trans
# File lib/core/facets/module/redefine_method.rb, line 26 26: def redefine_method(sym, aka=nil, &blk) 27: raise ArgumentError, "method does not exist" unless method_defined?( sym ) 28: alias_method( aka, sym ) if aka 29: undef_method( sym ) 30: define_method( sym, &blk ) 31: end
Redirect methods to other methods. This simply defines methods by the name of a hash key which calls the method with the name of the hash’s value.
class Example redirect_method :hi => :hello, :hey => :hello def hello(name) puts "Hello, #{name}." end end e = Example.new e.hello("Bob") #=> "Hello, Bob." e.hi("Bob") #=> "Hello, Bob." e.hey("Bob") #=> "Hello, Bob."
The above class definition is equivalent to:
class Example def hi(*args) hello(*args) end def hey(*args) hello(*args) end def hello puts "Hello" end end
CREDIT: Trans
# File lib/core/facets/module/redirect_method.rb, line 37 37: def redirect_method( method_hash ) 38: method_hash.each do |targ,adv| 39: define_method(targ) { |*args| send(adv,*args) } 40: end 41: end
Aliases a method and undefines the original.
rename_method( :to_method, :from_method )
CREDIT: Trans
# File lib/core/facets/module/rename_method.rb, line 11 11: def rename_method( to_sym, from_sym ) 12: raise ArgumentError, "method #{from_sym} does not exist" unless method_defined?( from_sym ) 13: alias_method( to_sym, from_sym ) 14: undef_method( from_sym ) 15: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.