【问题标题】:ruby how to define writer method with "<<"ruby 如何用“<<”定义编写器方法
【发布时间】:2023-04-03 19:07:01
【问题描述】:

我有一个骨架类:

class Foo
   def bar
    # returns some sort of array
   end
end

但是如何将 'writer' 方法添加到 'bar' 以启用 Array#push 行为?

Foo.new.bar<<['Smile']
_.bar #=> ['Smile']

编辑: 我应该进一步扩展我的问题。 有两个班。 Foo 和 Bar,很像 ActiveRecord has_many 关系,其中 Foo has_many Bars

但我实际上将 Bar 的 id 存储在 Foo 的方法中。我将该方法命名为 bar_ids

所以@foo = Foo.new(:bar_ids => [1,2,3])

如你所想,如果我想查看哪些 Bars 属于 @foo,我实际上必须执行类似 Bar.where(:id => @foo.bar_ids) 之类的操作

所以我决定创建另一个名为 bar 的方法来做到这一点 Foo 类 #... 定义栏 Bar.where(:id => bar_ids) 结尾 结束

成功了。现在我可以做@foo.bar #=> 所有属于@foo 的酒吧

现在我也想拥有像 ActiveRecord 关联这样的推送方法,只是为了在将另一个 bar 对象关联到 foo 对象时去掉“id”输入

目前,这有效: @foo.bar_ids

但我想要: @foo.bar

感谢您的所有帮助,非常感谢您对此的想法!

【问题讨论】:

  • 您对 bar 方法有什么期望?它应该只作为 Array 对象的 getter 吗?
  • @David 完全正确。我想要实现的就像 ActiveRecord has_many 关系,您可以在其中执行 @project.line_items
  • @Nik, @project.line_items &lt;&lt; ... 返回 Array,而不是 @projectFoo.new.bar 不可能返回一个可以同时调用 &lt;&lt;Foo 对象的数组!
  • 您确定只支持&lt;&lt; 吗?如果有人执行 @foo.bar.insert(position, 'Smile') 会发生什么?
  • 你知道,这是一个很好的观点。虽然这个特定阵列的位置幸运的是并不重要,但它确实让我们看到了未来可能带来麻烦的不可预见的需求。

标签: ruby


【解决方案1】:
class Foo
   attr_reader :bar
   def initialize
     @bar = Array.new
     def @bar.<< arg
       self.push arg.id
     end
   end

end

class Bar
  attr_accessor :id
  def initialize id
    self.id = id
  end
end


f = Foo.new
bars = (1..5).map{|i| Bar.new i}

f.bar << bars[2]
f.bar << bars[4]

p f.bar  #=> [3, 5]

【讨论】:

  • @Ormuriauga。这看起来很酷,你能解释一下为什么 def @bar.
  • @Nik,是的 ormuriauga 的解决方案非常酷。 def @bar.&lt;&lt;Fooinitialize 方法中,因为他正在那里自定义 @bar (Array) 对象(通过使用单例方法覆盖普通数组 &lt;&lt; 方法)。
  • @Ormuriauga & @Banister 谢谢。
  • 感谢@banister +1,您需要更详尽的解释吗@nik?
  • 据我了解,因为 @bar 现在被定义为一个数组,它会自动“继承”
【解决方案2】:

返回一个定义了&lt;&lt; 方法的对象。

【讨论】:

  • 所以基于我的例子, bar /does/ 返回一个数组,它确实定义了
  • 当然,如果你总是返回相同的数组对象,你就完成了。否则,_.bar #=&gt; ['Smile'] 将不起作用
【解决方案3】:

除非我误解了您想要的内容,否则为什么不将 bar 方法设为内部数组成员的 getter?

class Foo
  attr_reader :bar

  def initialize
    @bar = []
  end
end

f = Foo.new
f.bar << 'abc'
# f.bar => ['abc']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2020-10-16
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    相关资源
    最近更新 更多