Pointer concept in Ruby?

Hi, I’d like to have a variable pointing to a Hash/Array element, so
if I modify the variable then the Hash/Array element is modified too.

AFAIK this is not possible with Ruby since the abscense of pointer
concept. I want the following:

array = [ “aaa”, “bbb”, “ccc” ]

a1 = array[1].some_method
=> “bbb”

a1 = “BBB”
=> “BBB”

a[1]
=> “BBB”

Is it possible in some way? Thanks a lot.

On Apr 24, 2008, at 18:01, Iñaki Baz C. wrote:

Iñaki Baz C.
[email protected]

Quoth irb:

array = [ “aaa”, “bbb”, “ccc” ]
=> [“aaa”, “bbb”, “ccc”]
a1 = array[1]
=> “bbb”
a1.upcase!
=> “BBB”
array
=> [“aaa”, “BBB”, “ccc”]

You never pass by value, so you’re in essence always dealing with
pointers.
With your example, you merely made a1 point at a different object, a
new string, instead of the second string in the array.

If you however call a self-modifying method on a1 while it’s pointing
at the array string, it’ll also change in the array, as it’s still
pointing at the same object.

What are you trying to achieve in practice?

From: “Iñaki Baz C.” [email protected]

=> “bbb”

a1 = “BBB”
=> “BBB”

a[1]
=> “BBB”

Is it possible in some way? Thanks a lot.

In general this not easily possible with Ruby, and you’ll probably want
to
rethink your design so that you don’t need to do that.

However, there is a String#replace method, which may be useful if you’re
sure this is what you want to do:

=> [“aaa”, “bbb”, “ccc”]

a1 = array[1]
=> “bbb”
a1.replace “BBB”
=> “BBB”
array[1]
=> “BBB”

Regards,

Bill

2008/4/24, Mikael Høilund [email protected]:

array = [ “aaa”, “bbb”, “ccc” ]
Is it possible in some way? Thanks a lot.

a1 = array[1]
=> “bbb”
a1.upcase!
=> “BBB”
array
=> [“aaa”, “BBB”, “ccc”]

You never pass by value, so you’re in essence always dealing with pointers.
With your example, you merely made a1 point at a different object, a new
string, instead of the second string in the array.

Yes, I know that since object_id is the same until a write
operation is done.

If you however call a self-modifying method on a1 while it’s pointing at
the array string, it’ll also change in the array, as it’s still pointing at
the same object.

No, that’s not true. Demostration:

array=[000,111,222,33]
=> [0, 111, 222, 33]

a1=a[1]
=> 1

a[1].object_id
=> 345

a1.object_id
=> 345

a1=“NEW VALUE”
=> “NEW VALUE”

a1.object_id
=> -606081098 <----------- Has changed !!!

a[1].object_id <-------- Remains the same
=> 345

a1
=> “NEW VALUE”

a[1]
=> 1 <----------- Original value not changed

What are you trying to achieve in practice?

In fact just the code I wrote as example :slight_smile:

2008/4/24, Bill K. [email protected]:

=> “BBB”
Oh, really curious but I don’t like it since it’s just valid for
strings (why??) and it requires variable to be already defined. Isn’t
there any mehotd more “normal”? something as:

a2 = array[2].something

a2=“QWE”

array[2]
=> “QWE”

Thanks a lot.

2008/4/24, Iñaki Baz C. [email protected]:

No, that’s not true. Demostration:

array=[000,111,222,33]
=> [0, 111, 222, 33]

Sorry, it was:

a=[0,1,2,3]

2008/4/24, [email protected] [email protected]:

a[1] calls a method [] on the object pointed to by ‘a’. That method
pointed to by ‘a’, you need to be operating on that Array.

b = a
b[1] = “another new string”
puts a[1]

another new string

Make sense?

Sure, but I already kwen it, note that I was answering to Mikael that
said:

If you however call a self-modifying method on a1 while it’s pointing at the array string, it’ll also
change in the array, as it’s still pointing at the same object.

But thanks for the explanation :slight_smile:

On Fri, 25 Apr 2008, [UTF-8] Iñaki Baz C. wrote:

Sure, but I already kwen it, note that I was answering to Mikael that said:

If you however call a self-modifying method on a1 while it’s pointing at the array string, it’ll also
change in the array, as it’s still pointing at the same object.

But thanks for the explanation :slight_smile:

If you already knew it, what is the confusion? You misunderstood what
he
said. He said:

“If you however call a self-modifying method on a1 while it’s pointing
at
the array string, it’ll also change in the array, as it’s still pointing
at the same object.”

Note the “self-modifying” words there.

In your example, you weren’t changing what a1 pointed to; you were not
changing anything about the object itself.

irb(main):001:0> a = [‘0’,‘1’,‘2’,‘3’]
=> [“0”, “1”, “2”, “3”]
irb(main):002:0> a[1]
=> “1”
irb(main):003:0> a1 = a[1]
=> “1”
irb(main):004:0> a1 << ‘abc’
=> “1abc”
irb(main):005:0> a[1]
=> “1abc”

This is what he meant by “self-modifying” methods. Methods that change
something about the object itself.

Kirk H.

If you however call a self-modifying method on a1 while it’s pointing at
the array string, it’ll also change in the array, as it’s still pointing at
the same object.

No, that’s not true. Demostration:

You aren’t calling a “self-modifying method”.

mfg, simon … l

a2 = array[2].something

a2=“QWE”

array[2]
=> “QWE”

You can’t redefine =.

mfg, simon … l

On Fri, 25 Apr 2008, [UTF-8] Iñaki Baz C. wrote:

array=[000,111,222,33]

a1=“NEW VALUE”
=> “NEW VALUE”

a1.object_id
=> -606081098 <----------- Has changed !!!

Because you changed the object that a1 points to.

a[1].object_id <-------- Remains the same
=> 345

a[1] points to an object.
a1 points to an object.

They were the same object, until you pointed a1 at a different object.

This is the important distinction that you are missing.

To recap:

a = [1,2,3,4]

a points to an Array that contains 4 objects, the Fixnums 1, 2, 3, and
4.

a[1] calls a method [] on the object pointed to by ‘a’. That method
returns the object in the 1 position in the array.

a1 = a[1] points ‘a1’ at that object. a1 is just a pointer, though, to
an
object.

You can’t change what the Array pointed to by ‘a’ contains by pointing
‘a1’ at a different object, which is what your assignment of “NEW
STRING”
to ‘a1’ did.

If you want to change what is stored in the 1 index position in the
Array
pointed to by ‘a’, you need to be operating on that Array.

b = a
b[1] = “another new string”
puts a[1]

another new string

Make sense?

Kirk H.

El Jueves, 24 de Abril de 2008, [email protected] escribió:

=> “1abc”
irb(main):005:0> a[1]
=> “1abc”

This is what he meant by “self-modifying” methods. Â Methods that change
something about the object itself.

Really thanks. You are right, I didn’t understand the meaning
of “self-modifying” method, I thought that “=” was also a
“self-modifying”
method.

Sorry for the confusion and thanks a lot.

On 4/24/08, Iñaki Baz C. [email protected] wrote:

Isn’t there any mehotd more “normal”? something as:

a2 = array[2].something

a2=“QWE”

array[2]
=> “QWE”

There are probabaly a million reasons this is a bad idea, but what
about:

require ‘ptrclass’
=> true
a = [0,1,2,3]
=> [0, 1, 2, 3]
ap = a.ptr(3)
=> 3
ap.val=4
=> 4
a
=> [0, 1, 2, 4]
r=a.ptr(6)
=> nil
r.val=4
=> 4
a
=> [1, 34, 3, nil, nil, nil, 4]

— ptrclass.rb----
class PtrClass < DelegateClass(Object)
def initialize v
super
setobj v
end
def val= v
setobj v
end
end
class Array
def ptr n
v= self[n]
self[n] = v.is_a?(PtrClass) ? v : PtrClass.new(v)
end
end


-Adam

Iñaki Baz C. wrote:

I thought that “=” was also a “self-modifying”
method.

= isn’t a method. If it was a method, x=y could not result in x having a
different object_id than before. It could also not result in x having a
different class than before.
What x = y does, is that it makes x point to the same object as y which
doesn’t affect the old object x pointed to at all.
Basically methods change the object (or not) and = changes the variable.
I don’t think it’s possible to have a = method without static typing.

Note though that in “foo.bar = baz” bar= actually is a method on foo and
not
an assignment operation.

HTH,
Sebastian

El Jueves, 24 de Abril de 2008, Adam S.
escribió:> a

def initialize v
self[n] = v.is_a?(PtrClass) ? v : PtrClass.new(v)
end
end

It seems magic, thanks a lot.

2008/4/25, Sebastian H. [email protected]:

Basically methods change the object (or not) and = changes the variable.
I don’t think it’s possible to have a = method without static typing.

Note though that in “foo.bar = baz” bar= actually is a method on foo and not
an assignment operation.

Thanks for the explanation.

I tryed doing:

a2.object_id = array[2].object_id

but obviously is not permitted XDDD