Module: DR::Meta
Instance Method Summary collapse
- #all_ancestors(obj) ⇒ Object
-
#apply(*args, method: nil, to: self, **opts, &block) ⇒ Object
If we don't want to extend a module with Meta, we can still do Meta.apply(String,method: Meta.instance_method(:include_ancestors),to: self) Note: another way is to use Symbold#to_proc which works like this: foo=:foo.to_proc; foo.call(obj,*args) #=> obj.method(:foo).call(*args) essentially apply is a 'useless' wrapper to .call, but it also works for UnboundMethod.
-
#extend_object ⇒ Object
add extend_ancestors and extend_complete to Object.
- #get_bound_method(obj, method_name, &block) ⇒ Object
-
#refined_module(klass) ⇒ Object
from http://stackoverflow.com/questions/18551058/better-way-to-turn-a-ruby-class-into-a-module-than-using-refinements convert a class into a module using refinements ex: (Class.new { include Meta.refined_module(String) { def length; super+5; end } }).new("foo").length #=> 8.
Instance Method Details
#all_ancestors(obj) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/drain/ruby_ext/meta_ext.rb', line 16 def all_ancestors(obj) obj=obj.singleton_class unless Module===obj found=[] stack=[obj] while !stack.empty? do obj=stack.shift next if found.include?(obj) found<<obj stack.push(* obj.ancestors.select {|m| !(stack+found).include?(m)}) sing=obj.singleton_class stack << sing unless sing.ancestors.select {|m| m.class==Module}.reduce(true) {|b,m| b && found.include?(m)} end return found end |
#apply(*args, method: nil, to: self, **opts, &block) ⇒ Object
If we don't want to extend a module with Meta, we can still do Meta.apply(String,method: Meta.instance_method(:include_ancestors),to: self) Note: another way is to use Symbold#to_proc which works like this: foo=:foo.to_proc; foo.call(obj,*args) #=> obj.method(:foo).call(*args) essentially apply is a 'useless' wrapper to .call, but it also works for UnboundMethod. See also dr/core_ext that add 'UnboundMethod#call'
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/drain/ruby_ext/meta_ext.rb', line 50 def apply(*args,method: nil, to: self, **opts,&block) #note, in to self is Meta, except if we include it in another #module so that it would make sense method=method.unbind if method.class==Method case method when UnboundMethod method=method.bind(to) end if opts.empty? method.call(*args,&block) else method.call(*args,**opts,&block) end end |
#extend_object ⇒ Object
add extend_ancestors and extend_complete to Object
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/drain/ruby_ext/meta_ext.rb', line 32 def extend_object include_ancestors=Meta.method(:include_ancestors) include_complete=Meta.method(:include_complete) Object.define_method(:extend_ancestors) do |m| include_ancestors.bind(singleton_class).call(m) end Object.define_method(:extend_complete) do |m| include_complete.bind(singleton_class).call(m) end end |
#get_bound_method(obj, method_name, &block) ⇒ Object
65 66 67 68 69 70 |
# File 'lib/drain/ruby_ext/meta_ext.rb', line 65 def get_bound_method(obj, method_name, &block) obj.singleton_class.send(:define_method,method_name, &block) method = obj.method method_name obj.singleton_class.send(:remove_method,method_name) method end |
#refined_module(klass) ⇒ Object
from http://stackoverflow.com/questions/18551058/better-way-to-turn-a-ruby-class-into-a-module-than-using-refinements convert a class into a module using refinements ex: (Class.new { include Meta.refined_module(String) { def length; super+5; end } }).new("foo").length #=> 8
7 8 9 10 11 12 13 14 |
# File 'lib/drain/ruby_ext/meta_ext.rb', line 7 def refined_module(klass) klass=klass.singleton_class unless Module===klass Module.new do include refine(klass) { yield if block_given? } end end |