What I think ya'll are misunderstanding (and contrary to what most programming tutorials say,) about Ruby, is that Ruby DOES NOT really have TRUE VARIABLES.

'True variables', I mean in the sense that other languages such as the old BASIC or Pascal had variables, that were declared to 'BE' a certain datatype (int, real, string, etc.) AND kept a table in memory of those (variable) identifiers along with the current VALUE that was 'HELD' by them.

Ruby doesn't do this. EVERYTHING in Ruby is an OBJECT, including objects of the BASE classes (ie: Integer, Float, String, etc.) So when you code:aVar = 8in Ruby, you are NOT assigning the integer value 8 to a variable identifier, ... you are instead creating a reference, with the name aVar that POINTS at the first class object 8. The object 8 is an instance of class Integer, and so inherits methods from it's class, and superclasses, ie:8.id>> an id numberaVar.id>> the same id number since it points at object 8bVar = aVarbVar.id>> the same id number since it points at object 8And as Chris said, Fixnum is special in that there can be ONLY 1 object for each ordinal in the Fixnum set.

The same is not true for other more complex types, such as Array, String, etc.The best illustration of "how thinking" of Ruby references as variables (like in other languages,) can lead you to 'hair-pulling' frustration, was given in the forum over at Google Groups. (I answered and solved the poster's problem, but refered in my answer, to his 'reference' as 'an alias'; perhaps not so good as alias is a special kind of reference in Ruby for methods and don't work for "variables".)Any how.. read that post, and examineflesk's code, and the solution TIG and I gave him (TIG and I are about 5/6 hours apart and posted about the same time, I think.)Google Groups (Sketchup ruby API): Variable value error

So how would you 'pass by value'? (In the sense that you would in Pascal. You should have an idea, after reading that post.)Let's modify Chris' code a bit:

Or if you wish to paste into the console, then (1 line at a time):def m2(a); puts 'a in m2 has id: '+a.id.to_s; enddef m1; a = "hi"; puts 'a in m1 has id: '+a.id.to_s; m2(a.dup); endand then type: m1You'll see the id numbers differ.NOTE: If you think this will save time or memory, it won't. Ruby will create an anonymous reference to the duplicated object, so there is still a 'reference assignment' behind the scenes. In fact if you look up at the modified code, at the 2 puts statements, the String arguments 'a in m1 has id: ' are also transparently assigned an anonymous reference, so I might just as well have stored the string in a named reference of my own, so both methods could use the same String object, but change the method name. Of course it's not necessary, as these objects will not 'live' long.

(We also discussed this in another thread.) EDIT ( got confused for a min; removed previous statement.)My advice is, for less confusion, use the proper Stringappend operator: (It's the same work for typing!)a << 'bar'

ADD: IMHO, the interpreter should raise a SyntaxError when it sees += for Strings. I wonder if a Warning is output?UPDATE: No, I tested += with $VERBOSE set to true, and no warning is output.

(1) the reference a, is at method start, pointing at the same string object 'foo' that the reference x is pointing at; ..and

(2) then the expression on the right of the '=', in both cases, results in the creation of a *new* string object by Ruby...(a) In case 1, Ruby calls String.new('bar') (we'll call it: newbarstr.)..(b) In case 2, Ruby first expands a += 'bar', into a = a + 'bar', then (as in case 1,) evaluates the right-hand expression, transparently passing literal string args to String.new, keeping track of the anonymous pointers to the new string objects. In this example there is only one (we'll call it newbarstr.) Then, it calls a.+(newbarstr) which is the string concatenation method, that returns yet another *new* string object created by Ruby (we'll call it foobarstr, but remember Ruby uses temporary numerical identifiers.) So at this point the right-hand expression is now done and set to temp string object foobarstr.

(3) NOW.. both cases make a REFERENCE assignment, which assigns the referencea to point at the newString objects created from their evaluations.

(4) Lacking any specific return expression, the method returns the last result, which is the value of the object that a was made to point at, which is NOT the object 'foo'.

(5) Since the method call was made "stand-alone" and it's result not referenced, when the method exits, a will disposed of by Garbage Collection, along with any temporary objects Ruby used within the method.

+=vs.<<Looking back at (2)(b) above, and realizing all the work that is going on, and string objects being created, just to glue two substrings together.. we should all want to use << (the String append method,) instead.The main reason is, that it only creates one temporary string, IF the argument is a literal; otherwise NO temporary string, IF the argument is a reference to an existing string object. String.<< instead directly modifies the receiver string object by appending the string argument object onto it.

In this case, your calling a 'method operator' ie: Geom::Point3d.x= that happens to have a '=' character in the method name. It's not the same as the Ruby hard-coded = operator.

Your getting confused because the interpreter allows you to insert a space into the method call.

Also.. Geom::Point3d.x= is more similar to String.<<, in that the method doesn't replace an entire object, it only modifies part of the object.Specifically, Geom::Point3d.x= is an attribute setter method, involving Numerics, so no temporary Integer, and p is still pointing at the same object n is, so naturally, yes the common object gets modified.

Since Geom::Point3d has no dup method, you'll have to use clone to create a copy.

Interesting link. I think I need to read further into that book.Did remind me of another thing about Ruby - true/false, why they don't equal to 1 and 0. I've burned myself a couple of times on that one.