Delegate is a mechanism that uses composite to replace extend, which can effectively reduceCodeCoupling.
The delegate method is added to rails 2.2 to implement the delegate mechanism conveniently. Let's take a look at the source code:
Def delegate (* methods) Options = methods. Pop unless options. is_a? (Hash) & to = options [: To] Raise argumenterror, "delegation needs a target. supply an options hash with a: to key as the last argument (e.g. delegate: Hello,: To =>: greeter ). "End if options [: prefix] = true & options [: To]. to_s = ~ /^ [^ A-Z _]/raise argumenterror, "can only automatically set the delegation prefix when delegating to a method. "End prefix = options [: prefix] &" # {options [: prefix] = true? To: options [: prefix]} _ "methods. each do | method | module_eval (<-Eos, "(_ delegation _)", 1) def # {prefix }#{ method} (* ARGs, & Block) # {}. _ Send _ (# {method. inspect}, * ARGs, & Block) end EOS endend
The delegate method first checks the passed parameters. The correct parameter format is: Method1,: method2,...,: methodn,: To => Klass [,: prefix => prefix]
Delegate requires that the parameter end must be a hash: To indicates the class to be proxy, prefix indicates whether the proxy method should be prefixed, if: prefix
=> True, the proxy method is named klass_method1, klass_method2 ,...,
Klass_methodn. If: prefix => prefix
(Prefix is string), the proxy method name is prefix_method1, prefix_method2 ,...,
Prefix_methodn.
Finally, each method definition is dynamically generated through module_eval. PassSendMethod call: the method of the to class.
Let's take a look at the call example:
Simple call:
Class greeter activerecord: Base def Hello () "Hello" End def goodbye () "goodbye" endendclass Foo activerecord: Base delegate: Hello,: Goodbye,: To =>: greeterendfoo. new. hello # => "hello" foo. new. goodbye # => "Goodbye"
Added: prefix = true:
Class Foo activerecord: Base delegate: Hello,: Goodbye,: To =>: greeter,: prefix => trueendfoo. new. greeter_hello # => "hello" foo. new. greeter_goodbye # => "Goodbye"
Custom prefix Name:
Class Foo activerecord: Base delegate: Hello,: Goodbye,: To =>: greeter,: prefix =>: fooendfoo. new. foo_hello # => "hello" foo. new. foo_goodbye # => "Goodbye"
The dynamic nature of Ruby has once again played a powerful role!