Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Array and instance variable problem?

Reply
Thread Tools

Array and instance variable problem?

 
 
Maxime Guilbot
Guest
Posts: n/a
 
      01-24-2007
Look at the code below, I got strange results, I know that there is a
problem in the code but I can't find it. I expect to have an array like
this:

[[4, 4], [8, 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024,
1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024, 1024]]

at the ouput of get_next_10...

Does someone has the idea?

Thanks a lot,
Maxime.

class Dummy
def initialize
@indexes = Array.new(2, 1)
end

def get_next
@indexes[0] = @indexes[0]*2
@indexes[1] = @indexes[1]*2

@indexes
end

def get_next_10
all = []
for i in 0..9
all << get_next
end
all
end
end
=> nil

d = Dummy.new
=> #<Dummy:0x33b198 @indexes=[1, 1]>

d.get_next_10
=> [[1024, 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024,
1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024,
1024]]

d.get_next
=> [2048, 2048]

d.get_next
=> [4096, 4096]

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

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      01-24-2007
On 24.01.2007 11:34, Maxime Guilbot wrote:
> Look at the code below, I got strange results, I know that there is a
> problem in the code but I can't find it. I expect to have an array like
> this:
>
> [[4, 4], [8, 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024,
> 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024, 1024]]
>
> at the ouput of get_next_10...
>
> Does someone has the idea?


Your problem is aliasing: you're reusing the same @indexes over and over
again.

> Thanks a lot,
> Maxime.
>
> class Dummy
> def initialize
> @indexes = Array.new(2, 1)
> end
>
> def get_next
> @indexes[0] = @indexes[0]*2
> @indexes[1] = @indexes[1]*2
>
> @indexes


Make that @indexes.dup or do get_next.dup in get_next_10.

> end
>
> def get_next_10
> all = []
> for i in 0..9
> all << get_next
> end
> all
> end
> end
> => nil
>
> d = Dummy.new
> => #<Dummy:0x33b198 @indexes=[1, 1]>
>
> d.get_next_10
> => [[1024, 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024,
> 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024, 1024], [1024,
> 1024]]
>
> d.get_next
> => [2048, 2048]
>
> d.get_next
> => [4096, 4096]


Kind regards

robert
 
Reply With Quote
 
 
 
 
Wolfgang Nádasi-Donner
Guest
Posts: n/a
 
      01-24-2007
Maxime Guilbot schrieb:
> def get_next
> @indexes[0] = @indexes[0]*2
> @indexes[1] = @indexes[1]*2
>
> @indexes
> end


Use "@indexes.dup" istead of "@indexes" as the last Statement,...

> def get_next_10
> all = []
> for i in 0..9
> all << get_next
> end
> all
> end
> end


....or "all << get_next.dup" instead of "all << get_next".

In both cases you will end up with:


pp d.get_next_10

=>

[[2, 2],
[4, 4],
[8, 8],
[16, 16],
[32, 32],
[64, 64],
[128, 128],
[256, 256],
[512, 512],
[1024, 1024]]

The reason is, that you refer the same object in all Array positions othewise.

Wolfgang Nádasi-Donner
 
Reply With Quote
 
Maxime Guilbot
Guest
Posts: n/a
 
      01-24-2007
Thanks a lot for your answers, I got it

I guessed that it was that kind of problem...
but I still don't understand why it's working if @indexes is not an
Fixnum, not an Array..

Anyway, your answers solved my problem,
Thanks again,
Maxime.

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

 
Reply With Quote
 
Wolfgang Nádasi-Donner
Guest
Posts: n/a
 
      01-24-2007
Maxime Guilbot schrieb:
> but I still don't understand why it's working ...


Take a look to the following example.

>>>>> Code >>>>>


require 'pp'
class Dummy
def initialize
@indexes = Array.new(2, 1)
end

def get_next
@indexes[0] = @indexes[0]*2
@indexes[1] = @indexes[1]*2

@indexes
end

def get_next_10
all = []
for i in 0..9
all << get_next
end
all
end

def show_id
puts @indexes.object_id
end
end
d = Dummy.new

x = d.get_next_10
puts '##### show contents #####'
pp x
puts '##### show @indexes-id #####'
d.show_id
puts '##### show ids of Array elements #####'
x.each{|e|puts e.object_id}

>>>>> Output >>>>>


##### show contents #####
[[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024],
[1024, 1024]]
##### show @indexes-id #####
24861230
##### show ids of Array elements #####
24861230
24861230
24861230
24861230
24861230
24861230
24861230
24861230
24861230
24861230

>>>>> EOE >>>>>


Your original program pushes always the same object into the final array (here
named "d", and it ist the object, "@indexes" refers to. As a temporary help
think in "Pointers", than it shoud be clear.

Wolfgang Nádasi-Donner
 
Reply With Quote
 
Maxime Guilbot
Guest
Posts: n/a
 
      01-25-2007
Wolfgang, Thanks a lot for your detailed answer.

What I meant in my second message, is that when @indexes is a FixNum
(not an Array).
This code is working as expected:

#!/usr/local/bin/ruby

require 'pp'
class Dummy
def initialize
@indexes = 1
end

def get_next
@indexes = @indexes*2

@indexes
end

def get_next_10
all = []
for i in 0..9
all << get_next
end
all
end

def show_id
puts @indexes.object_id
end
end
d = Dummy.new

x = d.get_next_10
puts '##### show contents #####'
pp x
puts '##### show @indexes-id #####'
d.show_id
puts '##### show ids of Array elements #####'
x.each{|e|puts e.object_id}





The output I got is:

##### show contents #####
[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
##### show @indexes-id #####
2049
##### show ids of Array elements #####
5
9
17
33
65
129
257
513
1025
2049


I am curious about this result, why is it not the same behaviour?

It's also always the same @indexes which got into the array, right?

Thanks a lot for your patience!
Maxime.

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

 
Reply With Quote
 
Wolfgang Nádasi-Donner
Guest
Posts: n/a
 
      01-25-2007
Maxime Guilbot schrieb:
> What I meant in my second message, is that when @indexes is a FixNum
> (not an Array).
> This code is working as expected:


In the code

def get_next
@indexes[0] = @indexes[0]*2
@indexes[1] = @indexes[1]*2

@indexes
end

the contents of "@indexes" will be changed, but the "Array" object will be the
same. In

def get_next
@indexes = @indexes*2

@indexes
end

"@indexes*2" will create a new object, which will be assigned to "@indexes"
afterwards.

Conclusion: in case of the Array object you will end with the same object with
changed contents (the same is valid for Hash objects, and may be valid for
strings - see below), in case of the Fixnum object a new object will be created
and referenced.

An example for class String to clarify this.

>>>>> Code >>>>>


require 'pp'
class Dummy
def initialize
@indexes = "a"
end

def get_next
@indexes[0,1] = @indexes[0,1].succ

@indexes
end

def get_next_10
all = []
for i in 0..9
all << get_next
end
all
end

def show_id
puts @indexes.object_id
end
end
d = Dummy.new

x = d.get_next_10
puts '##### show contents #####'
pp x
puts '##### show @indexes-id #####'
d.show_id
puts '##### show ids of Array elements #####'
x.each{|e|puts e.object_id}

>>>>> Output >>>>>


##### show contents #####
["k", "k", "k", "k", "k", "k", "k", "k", "k", "k"]
##### show @indexes-id #####
24861400
##### show ids of Array elements #####
24861400
24861400
24861400
24861400
24861400
24861400
24861400
24861400
24861400
24861400

>>>>> EoE >>>>>


If you change a line of code a little bit, something completely different will
happen.

>>>>> Parts of Code >>>>>


def get_next
# @indexes[0,1] = @indexes[0,1].succ
@indexes = @indexes.succ # <<<<<< Here is the minor change

@indexes
end

>>>>> Output >>>>>


##### show contents #####
["b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]
##### show @indexes-id #####
24861380
##### show ids of Array elements #####
24861470
24861460
24861450
24861440
24861430
24861420
24861410
24861400
24861390
24861380

>>>>> EoE >>>>>


Wolfgang Nádasi-Donner
 
Reply With Quote
 
Maxime Guilbot
Guest
Posts: n/a
 
      01-25-2007
Thanks a lot Wolfgang, I completely understood!

Your explanation are great and very detailed, if I would have to score,
I would say 10/10

Bests regards,
Maxime.


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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Instance variable and pointer variable Prasanth C++ 5 05-17-2010 08:10 AM
Index of an array containing an instance, from this instance Paul A. Ruby 2 12-30-2009 10:56 PM
including instance methods and setting an instance variable Leon Bogaert Ruby 19 03-23-2008 09:29 PM
Problem when subclass instance changes base class instance variable Gerry Sutton Python 1 04-16-2005 06:06 AM
accessing class instance variable from instance method David Garamond Ruby 5 06-08-2004 02:26 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57