ruby – 为什么数字不支持.dup?

>> a = 5
=> 5
>> b = "hello,world!"
=> "hello,world!"
>> b.dup
=> "hello,world!"
>> a.dup
TypeError: can't dup Fixnum
    from (irb):4:in `dup'
    from (irb):4

我知道Ruby会在每次为新变量分配一个整数时复制,但为什么Numeric#dup引发错误

这不会破坏抽象,因为所有对象都应该被正确地响应.dup吗?

重写dup方法解决问题,据我所知:

>> class Numeric
>>   def dup()
>>     self
>>   end
>> end

这有没有我看不到的缺点?为什么不将它内置到Ruby中?

解决方法

Ruby中的大多数对象都是通过引用传递的,可以复制.例如:
s = "Hello"
t = s      # s & t reference to the same string
t.upcase!  # modifying either one will affect the other
s # ==> "HELLO"

但Ruby中的一些对象是即时的.它们按值传递,只能有一个这个值,因此不能被欺骗.这些是任何(小)整数,真,假,符号和零.在64位系统上的Ruby 2.0中,许多浮点数也是最重要的.

在这个(荒谬的)示例中,任何“42”都将保存相同的实例变量.

class Fixnum
  attr_accessor :name
  alias_method :original_to_s,:to_s
  def to_s
    name || original_to_s
  end
end
42.name = "The Answer"
puts *41..43  # =>  41,The Answer,43

由于您通常希望something.dup.name =“new name”不会影响使用dup获得的副本之外的任何其他对象,因此Ruby选择不在immediates上定义dup.

你的问题比它看起来更复杂.关于如何使这更容易,ruby-core上有some discussion.此外,其他类型的数字对象(浮点数,bignums,有理数和复数)也不能被欺骗,尽管它们也不是中立的.

请注意,ActiveSupport(rails的一部分)提供了可重复的方法?在所有对象上

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...