delegate
Rails2.3.8のドキュメントのざっくり意訳。
delegateの使い方
delegeteで指定したメソッドを、toで指定したオブジェクトに委譲する。
class Greeter < ActiveRecord::Base def hello() "hello" end def goodbye() "goodbye" end end class Foo < ActiveRecord::Base belongs_to :greeter delegate :hello, :to => :greeter end Foo.new.hello # => "hello" Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
複数メソッドを一度に委譲することも出来る
class Foo < ActiveRecord::Base belongs_to :greeter delegate :hello, :goodbye, :to => :greeter end Foo.new.goodbye # => "goodbye"
定数やクラス変数やインスタンス変数に移譲先を指定することも出来る。
class Foo CONSTANT_ARRAY = [0,1,2,3] @@class_array = [4,5,6,7] def initialize @instance_array = [8,9,10,11] end delegate :sum, :to => :CONSTANT_ARRAY delegate :min, :to => :@@class_array delegate :max, :to => :@instance_array end Foo.new.sum # => 6 Foo.new.min # => 4 Foo.new.max # => 11
prefixオプションをtrueにすると、"移譲先のオブジェクト名_メソッド名"のメソッド呼び出し時に委譲する。既に同名のメソッドを定義してるときとかに使うのかな?
Person = Struct.new(:name, :address) class Invoice < Struct.new(:client) delegate :name, :address, :to => :client, :prefix => true end john_doe = Person.new("John Doe", "Vimmersvej 13") invoice = Invoice.new(john_doe) invoice.client_name # => "John Doe" invoice.client_address # => "Vimmersvej 13"
シンボルを渡すことでprefix名を変更することも出来る。
class Invoice < Struct.new(:client) delegate :name, :address, :to => :client, :prefix => :customer end invoice = Invoice.new(john_doe) invoice.customer_name # => "John Doe" invoice.customer_address # => "Vimmersvej 13"
allow_nilオプションをtrueにすると、移譲先がnilでもエラーにならなくなる
class Foo attr_accessor :bar def initialize(bar = nil) @bar = bar end delegate :zoo, :to => :bar end Foo.new.zoo # raises NoMethodError exception (you called nil.zoo) class Foo attr_accessor :bar def initialize(bar = nil) @bar = bar end delegate :zoo, :to => :bar, :allow_nil => true end Foo.new.zoo # returns nil