Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between string operators + and << in Ruby

Tags:

ruby

I am new to Ruby and to this site.

The following two functions are different, one alters the variable outside the function and one does not.

def m1 (x)
  x << "4"
end

def m2 (x)
  x = x + "4"
end


str="123"

m2(str)   #str remains unchanged 123

m1(str)   #str is changed to 1234

I would like to make sure I understand this correctly -

When m1 is called, the reference to str is copied and passed to the function which sees it as x. Operator << changes x which references the origial str so str is changed by this operation.

When m2 is called, the reference to str is copied and passed to the function which sees it as x. Operator + creates a new string, and the assignment x = x + "4" simply redirects x to the new string leaving the original str variable untouched.

Right?

Thanks

method declarations and invokation

like image 980
yonso Avatar asked Mar 17 '13 14:03

yonso


1 Answers

String#+ :: str + other_str → new_str Concatenation—Returns a new String containing other_str concatenated to str.

String#<< :: str << integer → str : Append—Concatenates the given object to str.

<< doesn't create the new object, where as + does.

a = "str"
#=> "str"
a.object_id
#=> 14469636
b = a << "ing"
#=> "string"
a.object_id
#=> 14469636
b.object_id
#=> 14469636

a=  "str"
#=> "str"
b = a + "ing"
#=> "string"
a.object_id
#=> 16666584
b.object_id
#=> 17528916

EDIT

From your comment, got your point. See below:

def m1 (x)
 x << "4"
end
#=> nil
def m2 (x)
 x = x + "4"
end
#=> nil

str="123"
#=> "123"

m2(str)
#=> "1234"

str
#=> "123"

Here str didn't change as you passed the value inside the method m2(), all the changes local to the method as per the above call. Thus below str not showing that change.To see the change you have to call it as below.

str = m2(str)
#=> "1234"

str
#=> "1234"

OR

You could do the stuff as below :- where I passed reference address of str but not the value.

str = "abc"
#=> "abc"
str.object_id
#=> 16250484
ObjectSpace._id2ref(16250484)
#=> "abc"
def m1 (x)
ObjectSpace._id2ref(x) << "4"
end
#=> nil
m1(16250484)
#=> "abc4"
str
#=> "abc4"

Hope it make sense :)

Cheers!

like image 83
Arup Rakshit Avatar answered Oct 21 '22 03:10

Arup Rakshit