为什么rails对象和pry / irb之间的`object_id`符号有所不同?

时间:2015-09-02 13:46:04

标签: ruby-on-rails ruby irb

当我调试sharepoint.server.com AND data.server.com 时(我有一个BasicObject#method_missing错误),我得出的结论是No Id Given的第一个参数被映射到一个方法名称(借助于rb_method_missing(int argc, const VALUE *argv, VALUE obj))。

我想检查它,所以我在rails控制台(Rails 4.2 / Ruby 2.2)中键入:symbol.object_id

:symbol.object_id

然后我检查了IRB(Ruby 2.2):

:symbol.object_id
# => 771548

一切看起来都很棒。我在IRB尝试过:

:symbol.object_id
# => 771548

然后在rails console中:

:michał_kulesza.object_id
# => 2531228

为什么:michał_kulesza.object_id # => 7816668 :symbol有不同的情况下object_id具有相同的:michał_kulesza

2 个答案:

答案 0 :(得分:2)

为什么不呢? object_id只有四个属性:

  • object_idInteger
  • 每个对象都有object_id
  • 没有两个对象同时具有相同的object_id(但请注意,两个不同的对象在不同的时间可能具有相同的object_id,即{{1可能会被重复使用)
  • 某个对象的object_id在其生命周期内没有变化

您的观察并未违反这四个属性中的任何一个,因此,它完全有效。

可能会进行一些优化和/或缓存,因此某些object_id始终具有相同的Symbol。无论如何,这纯粹是YARV的内部实现细节,而不是 Ruby的语义。

例如,YARV优化适合n-1位的object_idnilfalsetrue s(Fixnum s,其中n为机器字的大小),flonums(Integer s适合n-2位,n> = 64)和某些Float s,其中一个副作用是那些对象始终具有相同的Symbol。但是,这并不能保证,例如,当引入flonums时,object_id object_idnil更改为4

答案 1 :(得分:2)

  

为什么object_id:michał_kulesza有不同的情况下:symbol具有相同的$ 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

这是因为符号$ 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

如果您在未加载任何宝石的情况下启动IRB,则会得到不同的结果:

$ ruby --disable-gems -S irb

irb(main):001:0> :foo.object_id
#=> 833308

irb(main):002:0> :symbol.object_id
#=> 833628

:michał_kulesza之前生成另一个符号会产生不同的对象ID:

{{1}}

Rails生成许多符号,这就是为什么{{1}}在rails控制台中具有更高的对象ID。