root/trunk/activesupport/lib/active_support/core_ext/module/delegation.rb
| Revision 8311, 2.0 kB (checked in by marcel, 7 months ago) |
|---|
| 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.