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.

···

--
Iñaki Baz Castillo
<ibc@aliax.net>

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.

-- Iñaki Baz Castillo
<ibc@aliax.net>

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?

···

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

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.

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

···

From: "Iñaki Baz Castillo" <ibc@aliax.net>

> 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.
>
>
> -- Iñaki Baz Castillo
> <ibc@aliax.net>
>

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.

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, Mikael Høilund <mikael@hoilund.org>:

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

--
Iñaki Baz Castillo
<ibc@aliax.net>

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, Bill Kelly <billk@cts.com>:

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"

--
Iñaki Baz Castillo
<ibc@aliax.net>

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, Iñaki Baz Castillo <ibc@aliax.net>:

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

--
Iñaki Baz Castillo
<ibc@aliax.net>

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 !!!

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 Haines

···

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

* Iñaki Baz Castillo <ibc@aliax.net> (18:24) schrieb:

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

* Iñaki Baz Castillo <ibc@aliax.net> (18:30) schrieb:

a2 = array[2]._something_

a2="QWE"

array[2]
=> "QWE"

You can't redefine =.

mfg, simon .... l

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

···

On 4/24/08, Iñaki Baz Castillo <ibc@aliax.net> wrote:

Isn't there any mehotd more "normal"? something as:

a2 = array[2]._something_

a2="QWE"

array[2]
=> "QWE"

---
-Adam

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?

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:

···

2008/4/24, khaines@enigo.com <khaines@enigo.com>:

--
Iñaki Baz Castillo
<ibc@aliax.net>

It seems magic, thanks a lot.

···

El Jueves, 24 de Abril de 2008, Adam Shelly escribió:

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

--
Iñaki Baz Castillo

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 Haines

···

On Fri, 25 Apr 2008, [UTF-8] Iñaki Baz Castillo 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:

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.

···

El Jueves, 24 de Abril de 2008, khaines@enigo.com escribió:

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.

--
Iñaki Baz Castillo

Iñaki Baz Castillo 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

···

--
NP: Depeche Mode - Little 15
Jabber: sepp2k@jabber.org
ICQ: 205544826

Thanks for the explanation.

I tryed doing:

  a2.object_id = array[2].object_id

but obviously is not permitted XDDD

···

2008/4/25, Sebastian Hungerecker <sepp2k@googlemail.com>:

Iñaki Baz Castillo 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.

--
Iñaki Baz Castillo
<ibc@aliax.net>