【问题标题】:Setter method (assignment) with multiple arguments具有多个参数的 Setter 方法(赋值)
【发布时间】:2012-02-14 16:37:18
【问题描述】:

我有一个自定义类并希望能够覆盖赋值运算符。 这是一个例子:

class MyArray < Array
  attr_accessor :direction
  def initialize
    @direction = :forward
  end
end
class History
  def initialize
    @strategy = MyArray.new
  end
  def strategy=(strategy, direction = :forward)
    @strategy << strategy
    @strategy.direction = direction
  end
end

这目前无法按预期工作。使用时

h = History.new
h.strategy = :mystrategy, :backward

[:mystrategy, :backward] 被分配给策略变量,方向变量保持为:forward
重要的是我希望能够为方向参数分配一个标准值。

非常感谢任何使这项工作的线索。

【问题讨论】:

    标签: ruby


    【解决方案1】:

    由于名称以=结尾的方法的语法糖,实际上可以将多个参数传递给方法的唯一方法是绕过语法糖并使用send...

    h.send(:strategy=, :mystrategy, :backward )
    

    ...在这种情况下,您还不如使用具有更好名称的普通方法:

    h.set_strategy :mystrategy, :backward
    

    但是,如果您知道数组对于参数永远不合法,您可以重写您的方法以自动取消数组值:

    def strategy=( value )
      if value.is_a?( Array )
        @strategy << value.first
        @strategy.direction = value.last
      else
        @strategy = value
      end
    end
    

    然而,这对我来说似乎是一个严重的黑客攻击。如果需要,我会使用带有多个参数的非赋值方法名称。


    另一种建议:如果唯一的方向是:forward:backward 呢:

    def forward_strategy=( name )
      @strategy << name
      @strategy.direction = :forward
    end
    
    def reverse_strategy=( name )
      @strategy << name
      @strategy.direction = :backward
    end
    

    【讨论】:

    • 编辑添加另一个替代实施的建议。
    • 我喜欢您检查值是否为数组的建议。你说这是一个严重的黑客攻击。在哪里使用它会造成麻烦?
    • @FlyingFoX 这是一个“粗俗的黑客”,因为它不是惯用的,不是自我记录的,并且通常不适用(在有人可能希望将数组作为第一个参数传递的情况下)。
    【解决方案2】:

    问题是

    def strategy=(strategy, direction = :forward)
      @strategy = strategy
      @strategy.direction = direction
    end
    

    当你设置时

    h.strategy = :mystrategy, :backward
    

    您实际上是在覆盖原始的 @strategy 实例。在那次调用之后,@strategySymbol 的一个实例,而不是MyArray

    你想做什么?替换对象还是更新它?

    【讨论】:

    • 哦,对不起,好像我搞砸了方法。应该是@strategy &lt;&lt; strategy
    • 哦;所以策略没有方向,而是你有一个策略列表和当前方向?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多