1

For the mechanism of "pass by value", it was so that the callee cannot alter the original data. So the callee can change the parameter variable in any way, but when the function returns, the original value in the argument variable is not changed.

But in Objective-C or Ruby, since all variables for objects are references to objects, when we pass the object to any method, the method can "send a message" to alter the object. After the method returns, the caller will continue with the argument already in a different state.

Or is there a way to guarantee the passed in object not changed (its states not altered) -- is there such a mechanism?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740

2 Answers2

1

You're somewhat misusing the term "pass by value" and "pass by reference" here. What you really are discussing is const. In C++, you can refer to a const instance of a mutable class. There is no similar concept for ObjC objects (or in Ruby I believe, though I am much less familiar with Ruby than ObjC). ObjC does, via C, have the concept of const pointers, but these are a much weaker promise.

The best solution to this in ObjC is to prefer value (immutable) classes whenever possible. See Imutability in Objective-c for more discussion on that.

The next-best solution is to, as a matter of design, avoid this situation. Avoid side effects in your methods that are not obvious from the name. By avoiding this as a matter of design, callers should not need to worry about it. Remember, the caller and the called are on the same team. Neither should be trying to protected itself from the other. Good naming and good API design help the developer avoid error without compiler enforcement. ObjC has little compiler enforcement, so good naming and good API design are absolutely critical. I would say the same for Ruby, despite my limited experience there, in that it is also a highly dynamic language.

Finally, if you are dealing with a poorly behaved API that does modify your object when it shouldn't, you can resort to passing it a copy.

But if you're designing this from scratch, think hard about using an immutable class whenever possible.

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
0

I'm not sure what you are getting at. Ruby is pass-by-value. You cannot "change the argument variable":

def is_ruby_pass_by_value?(foo)
  foo = 'No, Ruby is not pass-by-value.'
  return nil
end

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

is_ruby_pass_by_value?(bar)

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

I'm not sure about Objective-C, but I would be surprised if it were different.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • it is not pass by value or pass by reference per se, it is about "not to let the callee alter the data" – nonopolarity Aug 30 '12 at 15:12
  • @ChrisRice: That's completely unrelated to pass-by-value vs. pass-by-reference. Pass-by-value vs. pass-by-reference is about whether or not you can modify the caller's *variable binding*. Whether or not you can mutate an object is a question of a pure vs. impure programming language. Ruby is not a purely functional language like Haskell, therefore you can mutate objects, at least if the author of the object's class wants you to. But that has nothing to do with pass-by-reference vs. pass-by-value. – Jörg W Mittag Aug 30 '12 at 22:03
  • Pardon me, you are quite correct. I was tripping over the fact that Ruby variables are *references* to objects, but those references are "pass by value". If anyone else is confused, [this post](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) helped me understand the distinction. – Chris Rice Aug 30 '12 at 22:45
  • since all the objects are "references to objects", so you always have pass by value which is a reference. The key here is callee not able to alter the object, to have no "side effect" – nonopolarity Aug 30 '12 at 23:22