为什么 `object_id` 的符号在 rails 控制台和 pry/irb 之间有所不同?
Why does `object_id` of symbols vary between rails console and pry/irb?
当我在调试 BasicObject#method_missing
时(我有一个 No Id Given
错误),我得出的结论是 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
的第一个参数被映射到一个方法名(带有:symbol.object_id
).
的帮助
我想检查一下,所以我在rails控制台输入:symbol.object_id
(Rails 4.2/Ruby 2.2):
:symbol.object_id
# => 771548
然后我检查了 IRB (Ruby 2.2):
:symbol.object_id
# => 771548
一切看起来都很棒。我在 IRB 试过:
:michał_kulesza.object_id
# => 2531228
然后在 rails 控制台中:
:michał_kulesza.object_id
# => 7816668
为什么 :symbol
在两种情况下具有相同的 object_id
而 :michał_kulesza
具有不同的?
为什么不呢? object_id
s 只有四个属性:
object_id
是一个 Integer
- 每个对象都有一个
object_id
- 没有两个对象同时具有相同的
object_id
(但是,请注意,两个不同的对象可能在不同的次具有相同的object_id
,即 object_id
s 可能会被重新使用)
- 对象的
object_id
在其生命周期内不会改变
您的观察没有违反这四个属性中的任何一个,因此,它是完全有效的。
可能正在进行一些优化 and/or 缓存,因此某些 Symbol
始终具有相同的 object_id
。无论如何,这纯粹是 YARV 的内部实现细节, 不是 Ruby.
的语义
例如,YARV优化了nil
、false
、true
、Fixnum
s(Integer
s适合n-1位,其中n 是一个机器字的大小),flonums(Float
s 适合 n-2 位,对于 n >= 64)和某些 Symbol
s,这个的一个副作用是这些对象总是具有相同的 object_id
。但是,这并不能保证,例如,当引入 flonums 时,nil
的 object_id
从 4
更改为 8
。
Why does :symbol
have the same object_id
in both cases while :michał_kulesza
has a different one?
这是因为符号 :symbol
已经生成(由 gem):
$ irb
irb(main):001:0> Symbol.all_symbols.grep /sym/
#=> [:to_sym, :all_symbols, :symlink?, :symlink, :sym, :symbol, :@post_symbeg]
# ^^^^^^^
irb(main):002:0> :symbol.object_id
#=> 771548
如果你启动 IRB 而没有加载任何 gems,你会得到不同的结果:
$ ruby --disable-gems -S irb
irb(main):001:0> Symbol.all_symbols.grep /sym/
#=> [:to_sym, :all_symbols, :symlink?, :symlink, :@post_symbeg]
irb(main):002:0> :symbol.object_id
#=> 833308
在 :symbol
之前生成另一个符号会导致不同的对象 ID:
$ ruby --disable-gems -S irb
irb(main):001:0> :foo.object_id
#=> 833308
irb(main):002:0> :symbol.object_id
#=> 833628
Rails 生成许多符号,这就是为什么 :michał_kulesza
在 rails 控制台中具有更高的对象 ID。
当我在调试 BasicObject#method_missing
时(我有一个 No Id Given
错误),我得出的结论是 rb_method_missing(int argc, const VALUE *argv, VALUE obj)
的第一个参数被映射到一个方法名(带有:symbol.object_id
).
我想检查一下,所以我在rails控制台输入:symbol.object_id
(Rails 4.2/Ruby 2.2):
:symbol.object_id
# => 771548
然后我检查了 IRB (Ruby 2.2):
:symbol.object_id
# => 771548
一切看起来都很棒。我在 IRB 试过:
:michał_kulesza.object_id
# => 2531228
然后在 rails 控制台中:
:michał_kulesza.object_id
# => 7816668
为什么 :symbol
在两种情况下具有相同的 object_id
而 :michał_kulesza
具有不同的?
为什么不呢? object_id
s 只有四个属性:
object_id
是一个Integer
- 每个对象都有一个
object_id
- 没有两个对象同时具有相同的
object_id
(但是,请注意,两个不同的对象可能在不同的次具有相同的object_id
,即object_id
s 可能会被重新使用) - 对象的
object_id
在其生命周期内不会改变
您的观察没有违反这四个属性中的任何一个,因此,它是完全有效的。
可能正在进行一些优化 and/or 缓存,因此某些 Symbol
始终具有相同的 object_id
。无论如何,这纯粹是 YARV 的内部实现细节, 不是 Ruby.
例如,YARV优化了nil
、false
、true
、Fixnum
s(Integer
s适合n-1位,其中n 是一个机器字的大小),flonums(Float
s 适合 n-2 位,对于 n >= 64)和某些 Symbol
s,这个的一个副作用是这些对象总是具有相同的 object_id
。但是,这并不能保证,例如,当引入 flonums 时,nil
的 object_id
从 4
更改为 8
。
Why does
:symbol
have the sameobject_id
in both cases while:michał_kulesza
has a different one?
这是因为符号 :symbol
已经生成(由 gem):
$ irb
irb(main):001:0> Symbol.all_symbols.grep /sym/
#=> [:to_sym, :all_symbols, :symlink?, :symlink, :sym, :symbol, :@post_symbeg]
# ^^^^^^^
irb(main):002:0> :symbol.object_id
#=> 771548
如果你启动 IRB 而没有加载任何 gems,你会得到不同的结果:
$ ruby --disable-gems -S irb
irb(main):001:0> Symbol.all_symbols.grep /sym/
#=> [:to_sym, :all_symbols, :symlink?, :symlink, :@post_symbeg]
irb(main):002:0> :symbol.object_id
#=> 833308
在 :symbol
之前生成另一个符号会导致不同的对象 ID:
$ ruby --disable-gems -S irb
irb(main):001:0> :foo.object_id
#=> 833308
irb(main):002:0> :symbol.object_id
#=> 833628
Rails 生成许多符号,这就是为什么 :michał_kulesza
在 rails 控制台中具有更高的对象 ID。