[英]get object at end of method chain in ruby
假設我有以下代碼:
class Kid < ActiveRecord::Base
has_one :calculator
attr_accessible :favorite_num
end
class Teacher < ActiveRecord::Base
has_one :calculator
# does not have a favorite_num
end
class Calculator < ActiveRecord::Base
belongs_to :kid
belongs_to :teacher
def compute(number)
# takes the number passed in and multiplies it by
# the favorite_num if it exists, otherwise returns 42
end
end
我需要做的是在上面定義compute
,以便像下面的工作這樣的調用。
kid = Kid.first
=> #<User id: 1, favorite_num: 4, . . . >
kid.calculator.compute(5)
=> 20
teacher = Teacher.first
=> #<Teacher id: 1, . . . >
teacher.calculator.compute(5)
=> 42
一些其他限制:
Kid
和Teacher
類中都放一個compute
方法。 這是因為:
Calculators
相關聯 calculator.compute
調用,通常以不那么明顯的方式調用) 原始版本
如果我有
object.foo
那么foo
上下文中self
的值就是object
。 但是,如果我有:
object.foo.bar
如何從bar
的定義中引用object
? self
顯然不起作用,因為它僅等於object.foo
的返回值。
我無法更改foo
的實現。 並且foo
和bar
不能在同一類的對象上調用。
您描述的方法鏈接類型要求方法foo
返回self
。 為此,您必須更改方法定義或對其進行猴子修補。 更改方法定義很容易,只需將self
編寫為方法的最后一條語句即可。 當然,這意味着您無法從該方法返回任何其他內容,因此這不是每種方法的可行模式。 我強烈建議不要使用猴子補丁程序,因為我認為由此產生的丑陋代碼不值得。
但是,有一些方法可以解決此問題,而無需修改原始方法。 最簡單的解決方案是在彼此之間編寫方法調用。 它可能不像“性感”,但可以完成工作。
object.foo
object.bar
如果您想省略重復的object
,則可以使用Object#tap
。
object.tap{|o| o.foo }.bar
使用Symbol#to_proc
可以將其縮短一點。
object.tap(&:foo).bar
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.