簡體   English   中英

在Ruby的方法鏈末尾獲取對象

[英]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

一些其他限制:

  • 我不想在KidTeacher類中都放一個compute方法。 這是因為:
    • 我想讓東西盡可能干燥,其他幾個類的對象也都與Calculators相關聯
    • 這樣做將需要對我正在使用的舊代碼進行大規模的重構(在代碼周圍散布着很多calculator.compute調用,通常以不那么明顯的方式調用)

原始版本

如果我有

object.foo

那么foo上下文中self的值就是object 但是,如果我有:

object.foo.bar

如何從bar的定義中引用object self顯然不起作用,因為它僅等於object.foo的返回值。

我無法更改foo的實現。 並且foobar不能在同一類的對象上調用。

您描述的方法鏈接類型要求方法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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM