From: Robert Klemme Date: 2012-05-17T00:04:44+09:00 Subject: Re: Passing by reference - modifying instance variables On Wed, May 16, 2012 at 4:51 PM, John Cooper wrote: > Hi all, > > I'm new to Ruby and I've been working through the book "Programming > Ruby: The Pragmatic Programmer's Guide" > > Working through their jukebox example, I have come across a couple of > things that don't quite make sense to me. > > First, if I have a class with accessor methods but no mutator methods, I > can still modify the instance variables. The code in the attachment > reference.rb has the output: > > Blur - Song 2 (180) > Blur - song 2 (180) > > The instance variable title of song2 has been modified. This makes sense > to me, since the variables are passed by reference - I guess I'd need to > return a copy from my accessor method to avoid this happening. Is there > a neat way to do this? Dunno whether you find that neat def foo @foo.dup # ultra save: @foo.dup rescue @dup end You could even create a custom variant of attr_reader which generates this. Or you freeze instance variables. > To add further confusion, the code in the attachment reference2.rb - > with an identical definition of the class Song, with a call to > .downcase! in WordIndex::index does not modify the instance variables in > the Song class, even though, to my eyes, the title and artist strings > are being passed around just the same as in the previous simpler > example. word.downcase! works on the scan result which is not the original string. irb(main):001:0> s = "FOO" => "FOO" irb(main):002:0> s.scan(/../) {|m| p m; m.downcase!; p m} "FO" "fo" => "FOO" irb(main):003:0> s => "FOO" Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/