Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > ridiculous behavoir of Array#push and Array#clear

Reply
Thread Tools

ridiculous behavoir of Array#push and Array#clear

 
 
hongseok.yoon@gmail.com
Guest
Posts: n/a
 
      03-08-2006
See bellow code please.

1 obj1 = "object1"
2 obj2 = "object2"
3 obj3 = "object3"
4
5 arr1 = Array.new
6 arr2 = Array.new
7
8 arr1 << obj1
9 arr1 << obj2
10
11 arr2 << obj3
12
13 puts "<arr1>"
14 arr1.each {
15 | element |
16 puts element
17 }
18
19 puts "<arr2>"
20 arr2.each {
21 | element |
22 puts element
23 }
24
25 arr1.push( arr2 )
26 puts "<arr1 << arr2>"
27 arr1.each {
28 | element |
29 puts element
30 }
31
32 arr2.clear
33 puts "<arr2.clear>"
34
35 puts "<arr2>"
36 arr2.each {
37 | element |
38 puts element
39 }
40
41 puts "<arr1>"
42 arr1.each {
43 | element |
44 puts element
45 }

result is...

<arr1>
object1
object2
<arr2>
object3
<arr1 << arr2>
object1
object2
object3
<arr2.clear>
<arr2>
<arr1>
object1
object2

In the last list of arr1, there's no object3. Why? Does Array#push()
method append the array as a refrence? If so, why it does? And after
arr2 had been cleared, I still can access to 3rd member of arr1 without
exceptions or errors.

Yes, I can use clone() method for Array#push. But before, I hope to
know the reason why RUBY's Array#push method works like above.

Thanks.

 
Reply With Quote
 
 
 
 
Hannes Wyss
Guest
Posts: n/a
 
      03-08-2006
inspect will give you the answer:

On 3/8/06, http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:
> 1 obj1 =3D "object1"
> 2 obj2 =3D "object2"
> 3 obj3 =3D "object3"
> 4
> 5 arr1 =3D Array.new
> 6 arr2 =3D Array.new
> 7
> 8 arr1 << obj1
> 9 arr1 << obj2
> 10
> 11 arr2 << obj3
> 12
> 13 puts "<arr1>"

14 puts arr1.inspect
-> [ "object1", "object2" ]

> 19 puts "<arr2>"

20 puts arr2.inspect
-> [ "object3" ]

> 25 arr1.push( arr2 )
> 26 puts "<arr1 << arr2>"

27 puts arr1.inspect
-> [ "object1", "object2", [ "object3* ] ]
# notice that the third Element of arr1 is not obj3, but arr2!

> 32 arr2.clear

# fine, emptying arr2...
> 33 puts "<arr2.clear>"
> 34
> 35 puts "<arr2>"

36 puts arr2.inspect
-> [ ]

> 41 puts "<arr1>"

42 puts arr1.inspect
-> [ "object1", "object2", [ ] ]
# the third Element of arr1 is still arr2, it just has been cleared=
,
# so not a trace of obj3...

> Yes, I can use clone() method for Array#push. But before, I hope to
> know the reason why RUBY's Array#push method works like above.

...or you could do:
25 arr1.concat( arr2 )
-> [ "object1", "object2", "object3" ]

for any questions like that: try irb - I can only recommend it..

hth

Hannes


 
Reply With Quote
 
 
 
 
Martin Traverso
Guest
Posts: n/a
 
      03-08-2006
------=_Part_3258_30018097.1141809959323
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

> In the last list of arr1, there's no object3. Why? Does Array#push()
> method append the array as a refrence?



Yes, array elements are just references to objects pretty much in the same
way a variable points to an object. In your case, when you push arr2 into
arr1, what you're doing is making the 3rd element of the array be a
reference to the object pointed to by the variable arr2:

irb(main):006:0> arr1 =3D[]
=3D> []
irb(main):007:0> arr2 =3D[]
=3D> []
irb(main):008:0> arr1 << "object1"
=3D> ["object1"]
irb(main):009:0> arr1 << "object2"
=3D> ["object1", "object2"]
irb(main):010:0> arr2 << "object3"
=3D> ["object3"]
irb(main):011:0> arr1.push(arr2)
=3D> ["object1", "object2", ["object3"]]

irb(main):015:0> arr2.object_id # <=3D=3D=3D=3D arr2 and arr1[2] poi=
nt to the
same object
=3D> 22439224
irb(main):018:0> arr1[2].object_id
=3D> 22439224


> If so, why it does? And after
> arr2 had been cleared, I still can access to 3rd member of arr1 without
> exceptions or errors.




The call to arr2.clear() clears the contents of the array object referenced
by arr2, which happens to be the same array the 3rd element of arr1 points
to:

irb(main):012:0> arr2.clear
=3D> []
irb(main):013:0> arr1
=3D> ["object1", "object2", []]


The 3rd element is still in arr1, but now it just points to an empty array.

Hope this helps,

Martin

------=_Part_3258_30018097.1141809959323--


 
Reply With Quote
 
Pete Yandell
Guest
Posts: n/a
 
      03-08-2006
Changing your code to output the actual arrays:

> obj1 = "object1"
> obj2 = "object2"
> obj3 = "object3"
>
> arr1 = Array.new
> arr2 = Array.new
>
> arr1 << obj1
> arr1 << obj2
>
> arr2 << obj3
>
> puts "<arr1>"
> p arr1
>
> puts "<arr2>"
> p arr2
>
> arr1.push( arr2 )
> puts "<arr1 << arr2>"
> p arr1
>
> arr2.clear
> puts "<arr2.clear>"
>
> puts "<arr2>"
> p arr2
>
> puts "<arr1>"
> p arr1


gives you:

> <arr1>
> ["object1", "object2"]
> <arr2>
> ["object3"]
> <arr1 << arr2>
> ["object1", "object2", ["object3"]]
> <arr2.clear>
> <arr2>
> []
> <arr1>
> ["object1", "object2", []]


which should give you a hint as to what's going on.

Pete Yandell


 
Reply With Quote
 
Timothy Goddard
Guest
Posts: n/a
 
      03-08-2006
This is because arr1 is storing a _reference_ to arr2. If you want to
avoid this behaviour you could use any of the following:

arr1 += arr2 (generates new array, old arr1 is now garbage)
arr1 << arr2.dup (copies arr2, the copy is stored as an element of
arr1)
(arr1 << arr2).flatten! (ideal, but most verbose)

The first two generate new objects. I believe the third doesn't (I may
be wrong). Take your pick.

 
Reply With Quote
 
YANAGAWA Kazuhisa
Guest
Posts: n/a
 
      03-08-2006
In Message-Id: <(E-Mail Removed) .com>
"Timothy Goddard" <(E-Mail Removed)> writes:

> (arr1 << arr2).flatten! (ideal, but most verbose)
>
> The first two generate new objects. I believe the third doesn't (I may
> be wrong). Take your pick.


Or use Array#concat to concatenate two arrays destructively.

irb(main):001:0> a1 = [0, 1, 2]
=> [0, 1, 2]
irb(main):002:0> a2 = [3, 4, 5]
=> [3, 4, 5]
irb(main):003:0> a1.concat(a2)
=> [0, 1, 2, 3, 4, 5]
irb(main):004:0> a1
=> [0, 1, 2, 3, 4, 5]


--
(E-Mail Removed) March 9, 2006
Dreams come true --- excepting yours.



 
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
modify "Close Group" behavoir in X64? MsFriendly Windows 64bit 5 02-28-2008 04:26 PM
modify "Close Group" behavoir in X64? MsFriendly Windows 64bit 0 02-26-2008 08:19 AM
sscanf behavoir Joachim Schmitz C Programming 7 04-20-2007 06:41 AM
Processes with strange behavoir Markus Franz Python 2 04-04-2004 08:29 PM
Strange .avi file behavoir Croos Bustamunky Computer Support 2 02-03-2004 06:54 AM



Advertisments