From: Stefano Crocco Date: 2013-02-17T05:19:16+09:00 Subject: Re: How the string concatenation operator hackes(modifies) the string contents of frozen array? 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 `
' > > -- > 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