On Sat, 25 Aug 2007, John D. wrote:
really need to use containers. You could do something like:
still thinking of a ‘local variable’ as really some chunk of memory, and
seems sort of silly in this case. I could design an object that
represented a line in some fashion, and let it hold m and b, but that’s
not always what you’d want, either.
Maybe I’m not thinking in terms of objects enough yet?
I agree my answer was sort of “You can’t do the thing you just said
you can’t do” But that is sort of how it is. It’s axiomatic in
Ruby that local variables are local. By “bindings” I mean:
a = 3 # a is bound to 3
a = 1 # this (different) a is bound to 1
puts a # still 1
The call to x does not change the existing binding of a.
The only kind of change you can do in a situation like this is when a
variable is bound to a mutable object – or, more accurately, a
variable contains a reference to a mutable object (since basically
Ruby variables traffic in references). That’s where you get into
array = [1,2,3]
p array # [1,2,3,“New element”]
If I use ‘a’ instead of ‘array’ for my array, the fact that
add_to_array also uses ‘a’ is just coincidence. There’s no connection
between the two. It just happens that the identifier ‘a’ is used in
two local scopes to handle references to the same object.
The usual patterns you see in Ruby are either container-based,
object-based (where you have an object with an attribute; you pass the
object into the method and it does something to the attribute), or
assignment-based but in the same scope:
a + 2
a = 1
a = change_me(a) # a is now 3
I’ve pushed the assignment out of the method – where it doesn’t have
any effect except to set or change the method’s local variables –
into the calling context. That way, I can do whatever I want with my
identifiers in each scope.