Re: [ruby-81] I guess I should have known this

From: William S.
Sent on: Tuesday, November 13, 2007 9:07 PM
On Nov 13, 2007, at 8:18 PM, Chick Markley wrote:

> Mabye this just surprises me from my Java background with it's  
> immutable strings, but it caused a problem for me in a project that  
> I am working on and it was a little hard to find.  Answer is to use  
> @a = b.dup or @a = b.clone,  I have not done that in general done  
> that in the past, but I am going to pay more attention to it now.


Your not alone, I've seen many people confused about when coming from  
Java surrounding the behavior of built-ins. Unlike in Java, Strings  
are not immutable. You can make them that way if you want using freeze.

 >> z = 'aaa'
=> "aaa"
 >> z.freeze
=> "aaa"
 >> z << 'def'
TypeError: can't modify frozen string
         from (irb):3:in `<<'
         from (irb):3

Strings are much more flexible in Ruby, you can even change the String  
instance method and subclass. As for passing variable as you  
described. If you want to make sure nobody modifies an argument you  
should dup it or freeze it. duping is a better approach since it  
doesn't make any assumptions on how the caller will be using the string.

Here is how it would look with dup:

 >> class X
 >> attr_accessor :a
 >> def initialize(b); @a = b.dup; end
 >> end
=> nil
 >> z = 'abc'
=> "abc"
 >> x = X.new(z)
=> #<X:0x56efa0 @a="abc">
 >> z << 'def'
=> "abcdef"
 >> x
=> #<X:0x56efa0 @a="abc">

Just remember that all objects are pass by reference. The only  
immutable objects in Ruby are numbers. You can't change a 1 into a 2  
nor would you want to!

Hope this helps.

Cheers,
- Will


Our Sponsors

People in this
Meetup are also in:

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy