Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - Parameters by reference or by value? [duplicate]

Tags:

ruby

I don't understand why they say Ruby passes all parameters by value and at the same time the following code proves the opposite:

class MyClass1
  @var1 = 123

  def get1
    @var1
  end

  def set1=value
    @var1 = value
  end
end

c1 = MyClass1.new
c1.set1 = 444
p c1.get1 # 444

def test1 mc
  mc.set1 = 999
end

test1 c1
p c1.get1 # 999

If it were by value, it would print out 444, not 999.

like image 939
Incerteza Avatar asked Apr 03 '14 03:04

Incerteza


People also ask

Does Ruby pass by reference or value?

Everything in Ruby is an object, so Ruby is neither pass by value nor pass by reference, at least in the sense those terms are used in C++. "pass by object reference" might be a better way to describe what Ruby does.

How are the arguments in Ruby passed?

In ruby, arguments inside a method are passed by reference In ruby, we have a different situation, the variable that we have inside the method stores a reference to an object. Thus, if we will change an object inside the method, then it will be changed also outside the method.

Are Ruby variables mutable?

In Ruby, numbers and boolean values are immutable. Once we create an immutable object, we cannot change it.

What is :& in Ruby?

In a method argument list, the & operator takes its operand, converts it to a Proc object if it isn't already (by calling to_proc on it) and passes it to the method as if a block had been used.


1 Answers

This question confuses people because there is a thing called a reference type and there is a thing called pass-by-reference, but they don't actually have all that much to do with each other.

References and values and values that are references: A (sorta) brief overview

In a pass-by-reference scenario, the parameters of a function are references to the variables that were passed into the function, and modifying the parameters modifies the original variables. This is not what Ruby is. For example, let's look at the following code:

def inc(val)
  val += 1
end

a = 1
inc a
puts a

If Ruby were a pass-by-reference language, this program would print 2, because the val += 1 in inc would increment the value of a. But that isn't what happens. The variable val is not a reference to the variable a — it's an independent variable that is given the same value.

"But wait!" you say. "What if we were dealing with objects? Surely object variables are passed by reference, right?"

Nope.

def change_string(str)
  str << " I can insult you all you want"
  str << " because you'll never see this"
  str << " because I'm going to replace the whole string!"
  str << " Haha you smell bad!"
  str = "What? I didn't say anything." # I'm so sneaky
end

be_nice_to_me = "hello"
change_string(be_nice_to_me)
puts be_nice_to_me

If Ruby were pass-by-reference, you'd never see how mean the change_string method is, because the str = "What, I didn't say anything." would totally replace the value of be_nice_to_me with the string "What? I didn't say anything." But in fact change_string's sins are laid bare for all to see. How is this possible if Ruby doesn't pass by reference?

Well, remember those reference types I talked about earlier? Well, that's what objects are in Ruby. A reference type is a type whose value is a reference to something else. In this case, the variable's value is a reference to the string "hello". When you pass the string, the variable's value — which is a reference — is copied into the variable str. So now they both hold references to the same object, but str is not a reference to be_nice_to_me. So when you modify the object, those changes show up because they're both referring to the same object. But when you modify one variable, the other doesn't see it because neither variable is a reference to the other.

So is Ruby pass-by-reference or pass-by-value? It's pass-by-value, but all the values are references.

like image 183
Chuck Avatar answered Oct 24 '22 16:10

Chuck