Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/trunk/activesupport/lib/active_support/core_ext/module/delegation.rb

Revision 8311, 2.0 kB (checked in by marcel, 7 months ago)

Document that the delegate method can delegate to things other than just methods. Closes #7184 [dcmanges, jeremymcanally]

Line 
1 class Module
2   # Provides a delegate class method to easily expose contained objects' methods
3   # as your own. Pass one or more methods (specified as symbols or strings)
4   # and the name of the target object as the final :to option (also a symbol
5   # or string).  At least one method and the :to option are required.
6   #
7   # Delegation is particularly useful with Active Record associations:
8   #
9   #   class Greeter < ActiveRecord::Base
10   #     def hello()   "hello"   end
11   #     def goodbye() "goodbye" end
12   #   end
13   #
14   #   class Foo < ActiveRecord::Base
15   #     belongs_to :greeter
16   #     delegate :hello, :to => :greeter
17   #   end
18   #
19   #   Foo.new.hello   # => "hello"
20   #   Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
21   #
22   # Multiple delegates to the same target are allowed:
23   #   class Foo < ActiveRecord::Base
24   #     belongs_to :greeter
25   #     delegate :hello, :goodbye, :to => :greeter
26   #   end
27   #
28   #   Foo.new.goodbye # => "goodbye"
29   #
30   # Methods can be delegated to instance variables, class variables, or constants
31   # by providing the variable as a symbol:
32   #   class Foo
33   #     CONSTANT_ARRAY = [0,1,2,3]
34   #     @@class_array  = [4,5,6,7]
35   #     
36   #     def initialize
37   #       @instance_array = [8,9,10,11]
38   #     end
39   #     delegate :sum, :to => :CONSTANT_ARRAY
40   #     delegate :min, :to => :@@class_array
41   #     delegate :max, :to => :@instance_array
42   #   end
43   #
44   #   Foo.new.sum # => 6
45   #   Foo.new.min # => 4
46   #   Foo.new.max # => 11
47   #
48   def delegate(*methods)
49     options = methods.pop
50     unless options.is_a?(Hash) && to = options[:to]
51       raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
52     end
53
54     methods.each do |method|
55       module_eval(<<-EOS, "(__DELEGATION__)", 1)
56         def #{method}(*args, &block)
57           #{to}.__send__(#{method.inspect}, *args, &block)
58         end
59       EOS
60     end
61   end
62 end
Note: See TracBrowser for help on using the browser.