Robert Klemme
12/10/2007 10:33:00 AM
2007/12/10, Saladin Mundi <saladin.mundi@gmx.de>:
> hey folks, perhaps I'm too overtired, but I've got an array problem
> where I can't see my error
>
> class Main
> $someArray=[]
> $someArraytmp=[]
>
>
> def someMethod(elem,k)
> $someArraytmp[k] = elem
> if(k==0)
> $someArray.push($someArraytmp)
> $someArray.each {|e| p e}
> end
> end
> end
>
> t= Main.new
> t.someMethod("hello", 0)
> t.someMethod("bye", 0)
>
>
> From my opinion there must two arrays in the global (array)variable
> $someArray.
> The first array element should contain a String hello at the first
> position.
>
> The second array element (in $someArray) should be a String bye also at
> the first position.
>
> So:
> $someArray[0]
> -> []
> -> "hello"
> -> []
> -> "bye"
>
>
> But after compiling it there is
>
> $someArray[0]
> -> []
> -> "bye"
> -> []
> -> "bye"
>
> can someone explain to me why this happens?
This is a typical aliasing issue. You insert the same tmp array two
times into the global one and just overwrite the first element.
Basically the same what happens if you do
irb(main):018:0> Array.new(2,["bye"])
=> [["bye"], ["bye"]]
irb(main):019:0> a=Array.new(2,["bye"])
=> [["bye"], ["bye"]]
irb(main):020:0> a.map {|o| o.object_id}
=> [1073420070, 1073420070]
irb(main):021:0> a.map {|o| o.object_id}.uniq
=> [1073420070]
There are a lot of ways to improve your code. Since your method and
variable naming is generic there is no way to guess what you want to
achieve. The easiest fix to the code you show is to reinitialize
$someArraytmp=[] every time you pushed it into the other Array. But
ultimately you should use instance and local variables.
Cheers
robert
--
use.inject do |as, often| as.you_can - without end