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.

Alex Altair
  • 3,246
  • 3
  • 21
  • 37
  • 4
    In which Ruby version you are ? I got **Range error**. 2.0.0-p-353 – Arup Rakshit Mar 01 '14 at 21:36
  • Weird. From `pry -v` I get `Pry version 0.9.12.6 on Ruby 2.0.0`. – Alex Altair Mar 01 '14 at 21:40
  • 1
    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? – mu is too short Mar 01 '14 at 21:44
  • @muistooshort You raised valid point. – Arup Rakshit Mar 01 '14 at 21:46
  • 1
    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. – sawa Mar 01 '14 at 22:04
  • @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 }`. – Alex Altair Mar 01 '14 at 22:21
  • 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). – matt Mar 01 '14 at 22:26
  • Both objects return `[42, 42]`. Very mysterious... – Alex Altair Mar 01 '14 at 22:44
  • @AlexAltair Yes, I’ve managed to reproduce it now, I get them at `object_id` 2648 and 6728 on my machine. – matt Mar 01 '14 at 22:59
  • 5
    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. – matt Mar 01 '14 at 23:57
  • 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. – Alex Altair Mar 02 '14 at 08:19

1 Answers1

1

These commands may be illuminating:

ObjectSpace._id2ref(2648).class.ancestors
ObjectSpace._id2ref(6688).class.ancestors
John Bachir
  • 22,495
  • 29
  • 154
  • 227