0

Possible Duplicate:
Is Ruby pass by reference or by value?

Working with Ruby, when passing an object to a method, how is the memory of this object handled?

Coming from a C background, I can think of several things which may be happening:

  1. A copy of the memory associated with the according object and is made available to the method being called. In which case the modification of the object would only be reflected in the context of method being called, and not the calling method.

  2. A reference to the memory of the object is passed the method being called (essentially a pointer). Hence any changes made by the object by the method being called or the calling method would be reflected in both contexts. As well, should this program be multithreaded, some kind of mechanism (mutex, semaphore, etc.) must be used to ensure mutually exclusive access to that memory performing write operations.

  3. Something else I am unable to think of... maybe a memory model similar to that of Go... Pipes... MessagePassing...?

What is actually happening?

Community
  • 1
  • 1
rudolph9
  • 8,021
  • 9
  • 50
  • 80

2 Answers2

2

Ruby uses your second option, passes the parameter by reference.

Nucc
  • 1,031
  • 6
  • 20
  • Could you point me to some documentation describing this? – rudolph9 Sep 07 '12 at 18:20
  • http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html#S4 – Nucc Sep 07 '12 at 18:26
  • Variables always store references... – Nucc Sep 07 '12 at 18:27
  • http://www.ruby-forum.com/topic/41160 – artm Sep 07 '12 at 18:27
  • @Nucc You are correct and I appreciate the link, but this a terribly lazy response... – rudolph9 Sep 07 '12 at 19:05
  • @rudolph9 Hows this lazy? It contains all relevant information. Is there anything missing? – Cubic Sep 07 '12 at 19:33
  • @cubic This is a perfect first sentence, your right it contains all relevant information. Following this, a restatement of the question, inclusion of a reference, code example, and additional explanation would just be nice. I agree things should be made as simple as possible and all bare essential information should be statement up front but should further explanation be desired then the reader can keep reading, I suggested a very nice edit but I don't know what happened to it. – rudolph9 Sep 07 '12 at 23:22
  • 1
    Oh, jeez, do we need to go over this *again*? Ruby *does not* pass by reference. Never. No ifs, no buts, no corner cases, no exceptions. It *always* passes by value. Always. It behaves just like Java, Smalltalk, Python, C, C# (by default), C++ (by default) and pretty much every other object-oriented or procedural language in this regard. – Jörg W Mittag Sep 07 '12 at 23:24
  • Can you tell me a language that uses pass by reference by default? Because parameter handling in C++ and Ruby differs by default, but you wrote pass by value in both cases. – Nucc Sep 08 '12 at 07:46
  • I guess you are right, if we consider the C implementation of variable uses VALUE. But if we say pass by value because we pass VALUE when calling a method, then I guess this thinking is wrong because it's just an implementation of pass by reference on the level of Ruby. Can you tell me one behavior that is present in pass by reference definition but not works in Ruby for objects? – Nucc Sep 08 '12 at 08:52
  • Ohh, I guess I know the answer. The assign operator should change the object but it doesn't do in Ruby. You are right, I learnt something new today. – Nucc Sep 08 '12 at 08:57
2

Ruby uses pass-by-value, or more precisely, a special case of pass-by-value where the value being passed is always a pointer. This special case is also sometimes known as call-by-sharing, call-by-object-sharing or call-by-object.

It's the same convention that is used by more or less every object-oriented language ever created.

Note: on all existing Ruby implementations Symbols, Fixnums and Floats are actually passed directly by value and not with an intermediary pointer. However, since those three are immutable, there is no observable behavioral difference between pass-by-value and call-by-object-sharing in this case, so you can greatly simplify your mental model by simply treating everything as call-by-object-sharing. Just interpret these three special cases as internal compiler optimizations that you don't need to worry about.

Here's a simple example you can run to determine the argument passing convention of Ruby (or any other language, after you translate it):

def is_ruby_pass_by_value?(foo)
  foo.replace('More precisely, it is call-by-object-sharing!')
  foo = 'No, Ruby is pass-by-reference.'
  return nil
end

bar = 'Yes, of course, Ruby *is* pass-by-value!'

is_ruby_pass_by_value?(bar)

p bar
# 'More precisely, it is call-by-object-sharing!'

In short: it's your option 2.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653