Freeze method doesn't work

S

Sergey U.

Freeze should prevent further modifications to 'var'...

mac-undrgrnd:~ yspro$ irb
ruby-1.9.2-p0 > var = 4
=> 4
ruby-1.9.2-p0 > var.frozen?
=> false
ruby-1.9.2-p0 > var.freeze
=> 4
ruby-1.9.2-p0 > var.frozen?
=> true
ruby-1.9.2-p0 > var = 5
=> 5
ruby-1.9.2-p0 > var.frozen?
=> false
ruby-1.9.2-p0 >

What's wrong?
 
J

Jesús Gabriel y Galán

Freeze should prevent further modifications to 'var'...

mac-undrgrnd:~ yspro$ irb
ruby-1.9.2-p0 > var =3D 4
=A0=3D> 4
ruby-1.9.2-p0 > var.frozen?
=A0=3D> false
ruby-1.9.2-p0 > var.freeze
=A0=3D> 4
ruby-1.9.2-p0 > var.frozen?
=A0=3D> true
ruby-1.9.2-p0 > var =3D 5
=A0=3D> 5
ruby-1.9.2-p0 > var.frozen?
=A0=3D> false
ruby-1.9.2-p0 >

What's wrong?

Variables reference objects. It's the object you can freeze, not the
variable. If you make the variable point to a different object, the
original one is still frozen, but the new one maybe not.

Jesus.
 
J

Jeremy Bopp

Freeze should prevent further modifications to 'var'...

mac-undrgrnd:~ yspro$ irb
ruby-1.9.2-p0 > var = 4
=> 4
ruby-1.9.2-p0 > var.frozen?
=> false
ruby-1.9.2-p0 > var.freeze
=> 4
ruby-1.9.2-p0 > var.frozen?
=> true
ruby-1.9.2-p0 > var = 5
=> 5
ruby-1.9.2-p0 > var.frozen?
=> false
ruby-1.9.2-p0 >

What's wrong?

The freeze method doesn't operate on var itself. It operates on the
object that var references, so the Fixnum object for 4 was frozen in
your test. However, you are allowed to replace that object with another
any time you please. The freeze method only prevents you from changing
the object itself:

irb(main):001:0> var = 'abc123'
=> "abc123"
irb(main):002:0> var.frozen?
=> false
irb(main):003:0> var.freeze
=> "abc123"
irb(main):004:0> var.frozen?
=> true
irb(main):005:0> var.sub!(/\d/, 'n')
TypeError: can't modify frozen string
from (irb):5:in `sub!'
from (irb):5
from :0
irb(main):006:0> var
=> "abc123"
irb(main):007:0> var = 'abcn23'
=> "abcn23"
irb(main):008:0> var.frozen?
=> false


-Jeremy
 
S

Stefano Crocco

|Freeze should prevent further modifications to 'var'...

No. freeze prevents modifications to the object contained in var. For example:

str = "hello"
str.upcase!
puts str
=> HELLO
str.freeze
str.downcase!
=> RuntimeError: can't modify frozen string

str1 = str
str1.downcase!
=> RuntimeError: can't modify frozen string

Note that freeze is useless on classes (like Integer or Symbol) which don't
have destructive methods.

The nearest you can come to prevent modifications to a variable is to use a
constant instead (but remember that ruby allows you to assign a different
value to a constant, it just emits a warning). However, the object the
constant contains can be freely modified:

CONST="hello"
CONST.upcase!
puts CONST
"HELLO"
CONST="bye"
=> warning: already initialized constant CONST
puts CONST
=> "bye"

If you also want to prevent modifications to the object in the constant,
freeze it.

I hope this helps

Stefano
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,144
Messages
2,570,823
Members
47,369
Latest member
FTMZ

Latest Threads

Top