From: Xavier Noria Date: 2010-10-04T04:15:11+09:00 Subject: Re: Pass by reference and copy on write We can't just let our imagination go and build our own mental model of this stuff. The public contract of Java and Ruby says you only manipulate references to objects, not the objects themselves. For example, the JLS says in section 4.3.1: An object is a class instance or an array. The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object. ... There may be many references to the same object. Most objects have state, stored in the fields of objects that are instances of classes or in the variables that are the components of an array object. If two variables contain references to the same object, the state of the object can be modified using one variable's reference to the object, and then the altered state can be observed through the reference in the other variable. So it is not that Java leaves room for us to interpret that a variable "user" can hold a real User instance and that these opaque references are implementation details. You can't store a real user instance in a variable in Java. Period. The language only allows you to store references (modulus primitive types etc.). The contract is clear, and from it stuff follows. Same for Ruby. The Ruby Specification says for instance: A variable is denoted by a name, and refers to an object, which is called the value of the variable. A variable itself is not an object. While a variable can refer to only one object at a time, an object can be referred to by more than one variable at a time. So it belongs to their contract that we are not storing objects, rather we store some opaque things that *refer* to them. Having that in mind assignments are crystal clear. Given a = b = [] # (1) the situation is that a and b hold a reference to the same array object. We all agree with this. And it is imporatant because when we are talking about initializing method parameters conceptually something very similar to assignment is happening. The JLS says about this for example: When the method or constructor is invoked (ยง15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared Type, before execution of the body of the method or constructor. That's pass-by-value. And what is copied if we are passing object references, is object references. They are kinda opaque, but they belong to the public contract nonetheless and there's no doubt that's what you're passing around. And that is what let you clearly understand the implications of (1). And whay let you square why pass-by-value and being able to modify a mutable object are unrelated things. In Perl the difference is obvious because for example @a holds an actual array. We do not have actual arrays in Ruby or Python. If we have in Perl @a = (1); @b = @a; pushing to @b does *not* affect @a. They are actual arrays, not references to arrays, and assignment copies. You can create references with the backslash, which are scalar values akin to C pointers. And more interestingly for this thread, you can create aliases: @a = (1); *b = *a; Now @a and @b are variables that hold the same actual array. They are aliases. It's been a very long time since I did C++, but if I am not mistaken it offers both semantics, pass-by-value (which may involve a copy constructor), and pass-by-reference, which creates aliases as depicted in my post.