How the string concatenation operator hackes(modifies) the string contents of frozen array?

Hi,

Find the below code:

b = %w[foo bar gis]
=> [“foo”, “bar”, “gis”]

b.frozen?
=> false

b.object_id
=> 7298560

b.freeze
=> [“foo”, “bar”, “gis”]

b.object_id
=> 7298560

b[0] << “lish”
=> “foolish”

b.object_id
=> 7298560

#How the “<<” operator made the change to the string where as being a
concatenation operator “+” on string couldn’t do that,rather prevented
by the array?

b[0]=b[0] + “lish”
RuntimeError: can’t modify frozen Array
from (irb):16:in []=' from (irb):16 from /usr/bin/irb:12:in

On Sunday 17 February 2013 Love U Ruby wrote

=> 7298560
concatenation operator “+” on string couldn’t do that,rather prevented
Posted via http://www.ruby-forum.com/.
Writing
b[0] = b[0] + “lish”
you are changing the array: you take the string which was in position 0
in the
array, throw it away and put another string in its place. Since the
array was
frozen, ruby doesn’t allow you to do these things.

When you write
b[0] << “lish”
you’re taking the string in position 0 in the array and modifying it,
not the
array. To see this, you have to look at the object_id of the string
itself not
of the array. Let’s see what happens for a non frozen array:

b = %w[foo bar gis]
=> [“foo”, “bar”, “gis”]

b[0].object_id
=> 16686000

b[0] << “lish”
=> “foolish”

b[0].object_id
=> 16686000

The array still contains the original object, but the string contents
have
changed. Now, let’s see what happens with the other method:

b[0] = b[0] + “lish”
=> “foolish”

b[0].object_id
=> 15515100

As you can see, the object_id has changed, which means that you stored a
new
object in the array, which you can’t do if it’s frozen.

I hope this helps

Stefano

On Sat, Feb 16, 2013 at 9:46 PM, Love U Ruby [email protected]
wrote:

That’s why array#replace allowed on the frozen array, but none of the

It isn’t

irb(main):001:0> a=10.times.to_a.freeze
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
irb(main):002:0> a.replace [10,20]
RuntimeError: can’t modify frozen Array
from (irb):2:in replace' from (irb):2 from /usr/bin/irb:12:in

array#pop,array#push,array#rotate! etc not allowed.

Cheers

robert

humm, You are correct.

That’s why array#replace allowed on the frozen array, but none of the
array#pop,array#push,array#rotate! etc not allowed.

Thanks

Robert K. wrote in post #1097429:

On Sat, Feb 16, 2013 at 9:46 PM, Love U Ruby [email protected]
wrote:

That’s why array#replace allowed on the frozen array, but none of the

Humm. Sorry @Robert - I misspoken.