Search code examples
ruby-on-railsrubyirb

Why does `object_id` of symbols vary between rails console and pry/irb?


While I was debugging BasicObject#method_missing (I had a No Id Given error), I came to the conclusion that the first argument of rb_method_missing(int argc, const VALUE *argv, VALUE obj) is mapped to a method name (with the help of :symbol.object_id).

I wanted to check it, so I typed :symbol.object_id in rails console (Rails 4.2/Ruby 2.2):

:symbol.object_id
# => 771548

Then I checked in IRB (Ruby 2.2):

:symbol.object_id
# => 771548

and everything looked awesome. I tried in IRB:

:michał_kulesza.object_id
# => 2531228

and then in rails console:

:michał_kulesza.object_id
# => 7816668

Why does :symbol have the same object_id in both cases while :michał_kulesza has a different one?


Solution

  • Why does :symbol have the same object_id in both cases while :michał_kulesza has a different one?

    This is because the symbol :symbol was already generated (by a 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
    

    If you start IRB without loading any gems, you get a different result:

    $ 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
    

    Generating another symbol before :symbol results in a different object id:

    $ ruby --disable-gems -S irb
    
    irb(main):001:0> :foo.object_id
    #=> 833308
    
    irb(main):002:0> :symbol.object_id
    #=> 833628
    

    Rails generates many symbols, that's why :michał_kulesza has a much higher object id in rails console.