【问题标题】:Over-riding the substring update operator in Ruby's String class覆盖 Ruby String 类中的子字符串更新运算符
【发布时间】:2011-07-03 23:26:12
【问题描述】:

我想实现 String 类的功能版本。 具体来说,如果你更新一个我想克隆字符串的子字符串,执行更新 并返回生成的新字符串,以便我可以链接/伸缩操作。 该功能易于编码:

class FString < String
  alias zap []=
  def update( i, v )
    print "\"#{self}\".update( #{i}, #{v} )\n"
    (c = self.dup).zap( i, v )
    c
  end
  def []=( i, v )
    print "\"#{self}\"[#{i}] = #{v}\n"
    self.update(i,v)
  end
end

a = FString.new "test"
b = a.update( 2..3, 'XX' )
c = (a[2..3] = 'XX')

print "#{a}\n#{b}\n#{c}\n"

我坚持的是我想使用我的更新方法而不是默认的 []= 运算符。 但是如果你运行上面的代码,你会得到以下输出:

"test".update( 2..3, XX )
"test"[2..3] = XX
"test".update( 2..3, XX )
test
teXX
XX

有人可以解释为什么直接使用 update 方法与使用 []= (立即调用 update)产生不同的结果吗?

【问题讨论】:

  • 惊人的问题。这是一种奇怪的行为。我还没有答案并且已经玩了一段时间,但只是想指出您的代码看起来不错。以下效果很好: range = Range.new(2, 3); c = (a.send :[]=, range, 'XX');
  • This other recent * question 看起来很相似。一个答案是 setter 方法总是返回正确的操作数。我猜[]= 与常规二传手属于同一类别。

标签: ruby string variable-assignment operator-keyword overriding


【解决方案1】:

错误很简单。见:

c = (a[2..3] = 'XX')

方法 []= 总是返回第二个参数 'XX'(就像任何以 = 结尾的方法一样),因为它是一个赋值运算符。您可能需要取消定义 []= 以避免此错误。

【讨论】:

  • 但是我覆盖了 FString 类中的定义?
  • 我在别名后面加了一个 undef []= ,但没有区别。 :-/
  • 你删除了def []=(i, v) ... end吗?如果没有,您只是在重新定义方法。我尝试了undef []=,它可以工作。
最近更新 更多