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 `<main>'

···

--
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 Sunday 17 February 2013 Love U Ruby wrote

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 `<main>'

--
Posted via http://www.ruby-forum.com/\.

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

···

--
Posted via http://www.ruby-forum.com/.

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 `<main>'

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

Cheers

robert

···

On Sat, Feb 16, 2013 at 9:46 PM, Love U Ruby <lists@ruby-forum.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme wrote in post #1097429:

···

On Sat, Feb 16, 2013 at 9:46 PM, Love U Ruby <lists@ruby-forum.com> > wrote:

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

Humm. Sorry @Robert - I misspoken.

--
Posted via http://www.ruby-forum.com/\.