Jef*_*rth 7 ruby abstraction numbers
>> 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
Run Code Online (Sandbox Code Playgroud)
我知道Ruby会在每次为新变量赋值时制作副本,但为什么会Numeric#dup引发错误?
这不会打破抽象,因为所有对象都应该被.dup正确地响应吗?
dup据我所知,重写方法将解决问题:
>> class Numeric
>> def dup()
>> self
>> end
>> end
Run Code Online (Sandbox Code Playgroud)
这有没有我看不到的缺点?为什么不将它内置到Ruby中?
Mar*_*une 15
Ruby中的大多数对象都是通过引用传递的,可以复制.例如:
s = "Hello"
t = s # s & t reference to the same string
t.upcase! # modifying either one will affect the other
s # ==> "HELLO"
Run Code Online (Sandbox Code Playgroud)
但Ruby中的一些对象是直接的.它们按值传递,只能有一个这个值,因此不能被欺骗.这是任何(小)整数true,false,符号和nil.在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
Run Code Online (Sandbox Code Playgroud)
由于您通常希望something.dup.name = "new name"不会影响除获得的副本之外的任何其他对象dup,因此Ruby选择不在dupimmediates 上定义.
你的问题比它看起来更复杂.有一些讨论关于Ruby核心,如何这可以更容易.此外,其他类型的数字对象(浮点数,bignums,有理数和复数)也不能被欺骗,尽管它们也不是中立的.
请注意,ActiveSupport(rails的一部分)为duplicable?所有对象提供方法
| 归档时间: |
|
| 查看次数: |
4949 次 |
| 最近记录: |