From: noreply@... Date: 2007-05-30T12:41:11+09:00 Subject: [ ruby-Patches-1923 ] Forwardable, reworked Patches item #1923, was opened at 2005-05-17 07:50 You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=1700&aid=1923&group_id=426 Category: Ruby1.8 >Group: v1.8.x Status: Open Resolution: None Priority: 3 Submitted By: Daniel Berger (djberg96) Assigned to: Nobody (None) Summary: Forwardable, reworked Initial Comment: The following code is a reworked version of the current Forwardable module. It eliminates SingleForwardable altogther and adds the "delegate" method, at the suggestion of Florian Gross. I didn't provide a unified diff because I wasn't sure what additional documentation folks would want to include at the top of the file (and because there are so many code and doc changes). Attached is a corresponding test suite that should probably go under test/forwardable (which would need to be created). Regards, Dan # forwardable.rb # # == Synopsis # Provides a mechanism to allow classes to delegate named method calls # to other objects. # # == Usage # class Foo # extend Forwardable # delegate :length => :@str # delegate [:first, :last] => :@arr # def initialize # @arr = ["foo","bar","baz"] # @str = "hello" # end # end # # f = Foo.new # puts f.length # 5, length of @str # puts f.first # "foo", first element of @arr # puts f.last # "baz", last element of @arr # # == Author # Keiju Ishitsuka # # Revised by: Daniel J. Berger with suggestions from Florian Gross. # module Forwardable FORWARDABLE_VERSION = "1.0.0" # Takes a hash as its argument. The key is a symbol or an array of # symbols. These symbols correspond to method names. The value is # the accessor to which the methods will be delegated. # # :call-seq: # delegate method => accessor # delegate [method, method, ...] => accessor # def delegate(hash) hash.each{ |methods, accessor| methods = methods.to_s unless methods.respond_to?(:each) methods.each{ |method| def_instance_delegator(accessor, method) } } end # Delegates +methods+ to the given +accessor+. # # :call-seq: # def_delegators(accessor, *methods) # def def_instance_delegators(accessor, *methods) methods.delete("__send__") methods.delete("__id__") methods.each{ |method| def_instance_delegator(accessor, method) } end # Delegates a single +method+ to the given +accessor+. # # :call-seq: # def_delegator(accessor, method, alias=nil) # # If an alias is provided, the accessor will respond to that alias instead # of the original method. def def_instance_delegator(accessor, method, ali = method) str = %Q{ def #{ali}(*args, &block) #{accessor}.send(:#{method}, *args, &block) end } # If it's not a class or module, it's an instance begin module_eval(str) rescue instance_eval(str) end end alias def_delegators def_instance_delegators alias def_delegator def_instance_delegator end ---------------------------------------------------------------------- You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=1700&aid=1923&group_id=426