> In ruby, is there a way to get a handle of an object
reference? In
> perl, this is the \ operator:
>
> $x = 1; # \$x is a handle to change $x
> $a = [1,2,3]; # \$a-> [1] is a handle to change an element
in $a
>
> As far as I can tell, the closest that Ruby has to this is
a
> symbol. But, this only works for object references that
have an
> associated variable name. For example, there is no symbol
> associated with an element of an array (or hash).What are you trying to do? There is no equivalent to what you
want
in Ruby, but in most cases, it's not necessary. A little bit
of
rethinking, on the other hand, is necessary.
I've have various ways I can do what I need. I just wanted to
see if I could do it the perl way.
There is no way to do the following:
a = [1, 2, 3]
x = a[1]
x = 4 # a == [1, 4, 3]Variables in Ruby are simply labels for object references.
They are
not objects themselves. In Ruby, variables are transient
names --
they are effectively "weightless" and take up no space
(effectively).
Ruby variables must at least take up the space of a pointer (32
or 64 bits) and I would also imagine an entry in a symbol
table. But, that space probably isn't tracked by
ObjectSpace/GC. Not tracking that space like an object is
probably the reason why you can't have a general reference to
an object reference like perl has.
In Perl and C-like languages, variables
themselves
take up space on the call stack and may refer to other places
on the
heap.
You are probably right about perl (treat variables like
objects), but C is more like ruby in this respect. In C most
variables are on the stack and thus transient. You can make a
reference to one of those variables (i.e. a pointer to
somewhere in the stack), but that space will become invalid
once the variable goes out of scope.
Instead of having a general one-size fits-all reference to an
object reference, you could make a new class for each type of
object reference within each class. Of course you'd want a
common store/retrieve interface to all of these. For example:
class Array
def ref(*index)
Ref.new(self,*index)
end
class Ref
def initialize(a,*i)
@a = a
@i = i
end
def value
@a[*@i]
end
def value=(v)
@a[*@i]=v
end
end
end
Example:
a = [1,2,3]
x = a.ref(1)
x.value -> 2
x.value = 4
a -> [1,4,3]
y = a.ref(0..1) # reference to a slice!
y.value -> [1,4]
y.value = [6,5,4]
a -> [6,5,4,3]
I think you could do this with just about anything. Here is
the info you need for changing various object references:
* array element/slice: array, index (and length .. or range)
* string element/slice: string, index (and length .. or range)
* hash value: hash, key
* hash key: hash, key (changes)
* local variable: binding, symbol
* instance variable: object, symbol
etc.
This goes beyond what perl references do! perl can't do
references to array slices and references to hash keys!
It looks like I answered my own question...
Now, I think putting this type of thing in the libraries could
be quite useful. At a minimum, it would allow you to easily do
the pass-by-reference thing that I've seen several questions
on.
Discover Yahoo!
Find restaurants, movies, travel and more fun for the weekend. Check it out!
http://discover.yahoo.com/weekend.html