Aryeh M. Frierdman said:
Thanks for the answers so far but "none" of them actually do what I want.
What I want to do is declare some instance/var/whatever as being invariant
and any attemt to vary it will result in an error. I am convinced their
has to be some generic way to do this *without* the caller to the "test"
being "aware" that they are asking for it to be froozen. The int example
I gave was only that an example it could of very well been a String,
MyClass, EvilDictator, etc.
Apparently you want two things:
- freeze an instance
- make an object reference unchangeable
It's important to not confuse these two issues. The first is a property
of an instance while the latter is a property of an object reference. In
Ruby there are only references. There is no distinction between pointers,
references and values like one might know from C++. And there's a subtle
difference between C++ references and Ruby references: C++ references
can't be changed and always refer to the instance they were initialized
with, Ruby references can be changed. Thus Ruby references do have a
little similarity with C++ pointers - but not too much, since pointer
arithmetic is missing.
The first is achieved by doing obj.freeze as you determined correctly,
while the latter is not possible with local references as Brian pointed
out. The closest you can get is to declare a constant (first letter
uppercase) and then get a warning on reassignment like in:
irb(main):001:0> This_is_const = "foo"
"foo"
irb(main):002:0> This_is_const.freeze
"foo"
irb(main):003:0> This_is_const << "foo"
TypeError: can't modify frozen string
from (irb):3:in `<<'
from (irb):3
irb(main):004:0> This_is_const = "bar"
(irb):4: warning: already initialized constant This_is_const
"bar"
irb(main):005:0>
Regards
robert