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.