Appending an array to a frozen array


#1

Morning all,

@dependencies.freeze
@dependencies += [“blah”, “blah”]

does not error out due to modifying a frozen array (1.8.7 p72).

Is this expected behaviour? Up until now I’ve considered freezing an
array as making the array completely read only.

Cheers,
James


#2

On Wed, Mar 25, 2009 at 4:00 PM, James F.
removed_email_address@domain.invalid wrote:

Morning all,

@dependencies.freeze
@dependencies += [“blah”, “blah”]

does not error out due to modifying a frozen array (1.8.7 p72).
[…]

+= creates a new array and assigns it to @dependencies. The original
array remains frozen but @dependencies no longer refers to it.

To illustrate:
$: irb
01> a = b = [1, 2]
–> [1, 2]
02> a.freeze
–> [1, 2]
03> b.frozen?
–> true
04> b += [3, 4]
–> [1, 2, 3, 4]
05> a.frozen?
–> true

solidarity,
lasitha


#3

Ah, I understand - thanks. My next question is - is it possible to
prevent this?


From: lasitha [removed_email_address@domain.invalid]
Sent: 25 March 2009 10:48
To: ruby-talk ML
Subject: Re: appending an array to a frozen array

On Wed, Mar 25, 2009 at 4:00 PM, James F.
removed_email_address@domain.invalid wrote:

Morning all,

@dependencies.freeze
@dependencies += [“blah”, “blah”]

does not error out due to modifying a frozen array (1.8.7 p72).
[…]

+= creates a new array and assigns it to @dependencies. The original
array remains frozen but @dependencies no longer refers to it.

To illustrate:
$: irb
01> a = b = [1, 2]
–> [1, 2]
02> a.freeze
–> [1, 2]
03> b.frozen?
–> true
04> b += [3, 4]
–> [1, 2, 3, 4]
05> a.frozen?
–> true

solidarity,
lasitha


#4

James F. wrote:

Ah, I understand - thanks. My next question is - is it possible to prevent this?

@dependencies.freeze
@dependencies += [“blah”, “blah”]

does not error out due to modifying a frozen array (1.8.7 p72).

Use an attr_reader rather than an instance variable?


#5

2009/3/25 James F. removed_email_address@domain.invalid:

Ah, I understand - thanks. My next question is - is it possible to prevent this?

Since you are using an instance variable you control how it is
accessed. So, yes. If you want to know whether there is a hard way to
prevent reassignment to instance variables, the only safe way I know
off the top of my head is to freeze the owner:

irb(main):001:0> o=Object.new
=> #Object:0x10171ed8
irb(main):002:0> o.instance_variable_set “@foo”, 1
=> 1
irb(main):003:0> o
=> #<Object:0x10171ed8 @foo=1>
irb(main):004:0> o.freeze
=> #<Object:0x10171ed8 @foo=1>
irb(main):005:0> o.instance_variable_set “@foo”, 2
RuntimeError: can’t modify frozen object
from (irb):5:in instance_variable_set' from (irb):5 from /opt/bin/irb19:12:in
irb(main):006:0>

Kind regards

robert