问题描述
>> 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
引发错误?
I understand that Ruby will make a copy every time you assign an integer to a new variable, but why does Numeric#dup
raise an error?
这种中断抽象不是吗,因为应该期望所有对象都响应 .dup
正确吗?
Wouldn't this break abstraction, since all objects should be expected to respond to .dup
properly?
重写 dup
方法将解决此问题,告诉:
Rewriting the dup
method will fix the problem, as far as I can tell:
>> class Numeric
>> def dup()
>> self
>> end
>> end
这没有不利之处吗?为什么它不内置在Ruby中?
Does this have a downside I'm not seeing? Why isn't this built into Ruby?
推荐答案
Ruby中的大多数对象都是通过引用传递的,可以被复制。例如:
Most objects in Ruby are passed by reference and can be dupped. Eg:
s = "Hello"
t = s # s & t reference to the same string
t.upcase! # modifying either one will affect the other
s # ==> "HELLO"
Ruby中的一些对象是即时的。它们是通过值传递的,该值只能是其中一个,因此不能被复制。这些是任何(小)整数, true
, false
,符号和 nil
。在64位系统上的Ruby 2.0中,许多浮点数也是立即数。
A few objects in Ruby are immediate, though. They are passed by value, there can only be one of this value and it therefore cannot be duped. These are any (small) integers, true
, false
, symbols and nil
. Many floats are also immediates in Ruby 2.0 on 64 bit systems.
在这个(荒谬的)示例中,任何 42都将保留相同的实例变量。
In this (preposterous) example, any "42" will hold the same instance variable.
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选择不定义 dup
。
Since you would normally expect something.dup.name = "new name"
to not affect any other object than the copy obtained with dup
, Ruby chooses not to define dup
on immediates.
您的问题比看起来要复杂。在ruby-core上有关于如何使它变得更容易。同样,其他类型的数值对象(浮点数,大数,有理数和复数)也不能被复制,尽管它们也不是立即数。
Your question is more complex than it appears. There was some discussion on ruby-core as to how this can be made easier. Also, other types of Numeric objects (floats, bignums, rationals and complex numbers) can not be duped although they are not immediates either.
请注意,ActiveSupport(导轨的一部分) )在所有对象上提供方法 duplicable?
Note that ActiveSupport (part of rails) provide the method duplicable?
on all objects
这篇关于为什么数字不支持.dup?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!