What is the difference between these two Ruby symbols?
Asked Answered
S

1

13

I discovered this after playing around with object ids.

ObjectSpace._id2ref(2648)
=> :**
ObjectSpace._id2ref(6688)
=> :**
ObjectSpace._id2ref(2648) == ObjectSpace._id2ref(6688)
=> false

The first one is the symbol for the exponentiation operator;

2.send(ObjectSpace._id2ref(2648), 3)
=> 8
2.send(ObjectSpace._id2ref(6688), 3)
NoMethodError: undefined method `**' for 2:Fixnum

But the second one somehow isn't? I assume they just look the same after being passed to #print. But what is the difference? Is one of them somehow a unicode symbol?

UPDATE: The second one is probably the new double splat for keyword arguments, but I can't seem to verify this.

Sambo answered 1/3, 2014 at 21:30 Comment(11)
In which Ruby version you are ? I got Range error. 2.0.0-p-353Kaleb
Weird. From pry -v I get Pry version 0.9.12.6 on Ruby 2.0.0.Sambo
Object ids aren't necessarily the same across Ruby invocations so there's not much anyone can say unless you can provide explicit steps that reproduce what you're seeing. OTOH, id = ':**'.object_id; puts ObjectSpace._id2ref(id) is suggestive so why not check the class of the _id2ref return values?Identification
@muistooshort You raised valid point.Kaleb
It indeed raise an range error as Arup says, but it further says RangeError: 0x00000000001a20 is not symbol id value, so that number seems to fit in the possible range for symbol objects.Mitosis
@muistooshort Interesting! I can't find a more deterministic way to produce the second object. I found them by running the equivalent of 10000.times{ |n| ObjectSpace._id2ref(n).inspect }.Sambo
What is the value of ObjectSpace._id2ref(6688).to_s.codepoints? It could be some odd character, possibly U+2217: ASTERISK OPERATOR (which is 8727 in decimal).Apathy
Both objects return [42, 42]. Very mysterious...Sambo
@AlexAltair Yes, I’ve managed to reproduce it now, I get them at object_id 2648 and 6728 on my machine.Apathy
I suspect this might have something to do with keyword arguments, which use ** to indicate an options hash in an arguments list. I can’t reproduce the issue on 1.9.3. It looks like there is an extra ‘hidden’ ** symbol that doesn’t appear in the symbol table but can be found by looking at ObjectSpace.Apathy
Hm... I think you're probably right. I can't find a way to verify it using #send. Are splat and double splat even proper methods? What are they called on? Mysteries abound.Sambo
R
1

These commands may be illuminating:

ObjectSpace._id2ref(2648).class.ancestors
ObjectSpace._id2ref(6688).class.ancestors
Reduction answered 15/3, 2014 at 18:9 Comment(1)
Alas, as they are both symbols, this only tells us things about all symbols.Sambo

© 2022 - 2024 — McMap. All rights reserved.