Randy Kramer wrote:
> So, what is the net effect?  With any of the three syntaxes (a[2] = 3, 
> a.[]=(2,4), a.send(:[]=, 2, 5)), I change (assign a new value to) the 
> 3rd element of the array a.
> 
> What is the practical point of saying it is not an assignment?

It just so happens that the semantics of the []= method on an Array 
object are to replace the x'th element with a pointer to y. However 
there is no requirement for any object to behave in such a way.

  class Foo
    def []=(x,y)
      puts "Hello #{x}, today is #{y}"
    end
  end
  a = Foo.new
  a["Randy"] = "Friday"

It's just a method call. Objects can, in response to method calls, 
mutate (normally that means change what their instance variables point 
to; in the case of Array, which is a special built-in class, it means 
change the underlying hidden data structure)

But objects mutating is completely different to assignment.

  var = expr

means calculate the value of 'expr' (which *always* results in a 
reference to some object), and store this reference in the local 
variable 'var' (which is a slot on the stack)

This is something I find great about Ruby: everything is a reference. In 
C you have to decide whether you are passing a value or a pointer; in 
C++ you have to decide whether you are passing a value, a pointer or a 
reference :-(

> Yes, I 
> know that the underlying thing is a method, and somehow a[2] = 3 is 
> syntactic sugar (I guess), for a.[]=(2,3), but in the end, it 
> accomplishes an assignment.

In the case of an Array object, it accomplishes a modification to that 
object's internal state.

>> Yes, that's very important too. You are assigning to a local variable, 
>> which is just a slot on the stack. A local variable is in fact one of 
>> the few things which is *not* an object in Ruby. It *holds* a reference 
>> to an object, but is not an object itself.
> 
> I'm assuming the same is true for any variable in Ruby, not just local 
> variables?

Sure: global variables, instance variables and class variables all live 
in different places, but they are just holders of references and are not 
objects in themselves.

>>   a = malloc(123);  /* a points to some memory */
>>   c = a;            /* c points to the same memory */
> 
> Ok, is there still some magic here?.  Compare (thinking in C):
> 
> Given:
> 
> char *a;
> char *c;
> 
> Would both of these assignments (in C) work as they would in Ruby:
> 
> a = [1, 2, 3]
> c = a

You can't do exactly that in C. One possibility is

  char a[3] = { 1, 2, 3 };
  char *c;

  c = a;

Here a and c are not exactly the same. Arrays in C are just pointers to 
memory, and you could use 'a' and 'c' in any context that a 'char *' 
pointer would be expected, but whilst you can modify 'c' to point 
somewhere else, you cannot modify 'a' (e.g. a++ is illegal, as is a = b)

A bit closer to Ruby is:

  char *a;
  char *c;

  a = malloc(3);
  memcpy(a, "\x01\x02\x03", 3);

  c = a;

Note that in Ruby, the expression [1, 2, 3] creates a new object every 
time it executes. Try for example,

  10.times { puts [1, 2, 3].object_id }

The same even applies for Strings:

  10.times { puts "Hello".object_id }

There are only a few cases where you get the same object each time round 
(e.g. Fixnums, some Regexp literals, symbols, nil, true, false)

B.
-- 
Posted via http://www.ruby-forum.com/.