1

Here was the behavior that somewhat surprised me:

1.9.3-p392 :001 > n = 1
 => 1
1.9.3-p392 :002 > n.frozen?
 => false
1.9.3-p392 :003 > 1.freeze
 => 1
1.9.3-p392 :004 > n.frozen?
 => true

I tried grepping through the RubySpec source code for frozen and I didn't see anything about Fixnums at all.

Is this behavior the same as what would be expected on non-MRI Ruby implementations? If I run n = 1; 1.freeze; n.frozen?, will the final result always be true on any Ruby implementation? Why or why not?

Mark Rushakoff
  • 249,864
  • 45
  • 407
  • 398
  • I am definitely surprised to see this. Definitely a +1! – vgoff May 18 '13 at 07:05
  • The behavior changes from 1.8 to 1.9 (and possibily 1.9 to 2.0) – Shawn Balestracci May 18 '13 at 07:06
  • So you're really asking if the uniqueness of a Fixnum (i.e. there is only one `1` just like there is only one `:s`) is specific to the MRI implementation or if it is a language feature? – mu is too short May 18 '13 at 07:07
  • @muistooshort: Is my question (re. frozenness) just a specific case of the question you've described? I'm not totally sure. But I would like to hear the answer to the question as you've phrased it, too. – Mark Rushakoff May 18 '13 at 07:15
  • Because of the uniqueness, the fact that it is an un-`allocate`-able object, surprises me that it can be frozen. You can't even add a singleton method to a Fixnum. I am sure you weren't asking me, but this is why I was surprised. – vgoff May 18 '13 at 07:17
  • Is the question about being able to freeze a Fixnum? Or is the root of the problem that `1.object_id` and `n = 1; n.object_id` will produce the same thing whereas `'pancakes'.object_id` and `s = 'pancakes';s.object_id` will not? I think you need to clarify what the actual question is. – mu is too short May 18 '13 at 07:27
  • I think that is another question. His question stated here from my interpretation is directly what is before the question marks. In other words, is this just an MRI expectaction, or does this survive (consciously) in other implementations? At least that is how I read the question. – vgoff May 18 '13 at 08:02
  • possible duplicate of [What is the use or effect of freezing Symbols and Numbers in Ruby?](http://stackoverflow.com/questions/4235238/what-is-the-use-or-effect-of-freezing-symbols-and-numbers-in-ruby) – sawa May 18 '13 at 08:29

2 Answers2

0

It looks like it is an intended feature. In Ruby Forum, a question is raised:

Isn't technically all Fixnums "frozen" (because you can't modify the state)?

to which matz answers:

Not really, since fixnums could have instance variables.

Thus, theoretically, there's room for freezing fixnums. I don't think it's worth the cost though.

There seems to have been unintended inconsistency between different MRI Ruby versions, but as far as MRI is concerned, they look like they were identified as bugs, and were fixed. The specification you observed seems to be the intended one.

sawa
  • 165,429
  • 45
  • 277
  • 381
0

Since everything in Ruby is an object, it perhaps shouldn't be surprising that you can freeze 1. Symbol has the same behavior. As mentioned in the comments, this behavior changed from 1.8.7 (freezing didn't do anything) to 1.9+ (freezing works).

What might be more surprising is that freezing 1 also freezes n. According to the documentation for Fixnum,

There is effectively only one Fixnum object instance for any given integer value

This means that n and 1 are references to the same object, and modifying one will modify the other.

You can check this for yourself by looking at the object_id.

1.object_id
 => 3

n=1
n.object_id
 => 3

n.equal? 1
 => true

I tried this code in MRI 1.8.7, MRI 2.0.0, JRuby, and Rubinius and got the same result.

davogones
  • 7,321
  • 31
  • 36