[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Problem with Array#delete ?

Daniel Berger

6/24/2008 8:44:00 PM

Hi all,

In messing around with Array#delete I think I've uncovered a problem.
Consider this example:

class Foo
def ==(other)
$array.clear
false
end
end

arr = [1, 2, 3]
arr << Foo.new
Arr << 'b'

$array = arr

arr.delete('a')

p arr # => []
p $array # => []

That's what I would expect. It did the comparison, and called the
Foo#== method, which in turn cleared the receiver.

But if you do this instead:

arr.delete(1)

You end up with:

[nil, nil, #<Foo:0x2865ff4>]
[nil, nil, #<Foo:0x2865ff4>]

What's happening?

Thanks,

Dan

3 Answers

Rick DeNatale

6/24/2008 9:54:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Tue, Jun 24, 2008 at 4:43 PM, Daniel Berger <djberg96@gmail.com> wrote:

> Hi all,
>
> In messing around with Array#delete I think I've uncovered a problem.
> Consider this example:
>
> class Foo
> def ==(other)
> $array.clear
> false
> end
> end
>
> arr = [1, 2, 3]
> arr << Foo.new
> Arr << 'b'
>
> $array = arr
>
> arr.delete('a')
>
> p arr # => []
> p $array # => []
>
> That's what I would expect. It did the comparison, and called the
> Foo#== method, which in turn cleared the receiver.
>
> But if you do this instead:
>
> arr.delete(1)
>
> You end up with:
>
> [nil, nil, #<Foo:0x2865ff4>]
> [nil, nil, #<Foo:0x2865ff4>]
>
> What's happening?


Well, I haven't dug into the implementation of Array#delete enough to fully
explain the results but.

You do know that after the assignment

$array = arr

You've made the global variable $array reference the same object to which
you are sending delete.

So the $array.clear in the Foo#== method is clearing that object which is
the receiver of the delete method.

Now in general ruby iterator methods don't expect the enumerated object to
change during the iteration and that's just what's happening.

This is no doubt confusing the delete method.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Rick DeNatale

6/24/2008 10:30:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Tue, Jun 24, 2008 at 5:53 PM, Rick DeNatale <rick.denatale@gmail.com>
wrote:

>
>
> Well, I haven't dug into the implementation of Array#delete enough to fully
> explain the results but.
>

And having now looked at the Ruby 1.8 implementation of Array#delete, I
think I know exactly what's going on.

Here's a pseudo-ruby translation of the C code:

class Array
def delete(obj)
i1 = i2 = 0
while i1 < self.length
e = self[i1]
unless e == obj
self[i2] = e
i2 += 1
end
i1 += 1
end
if i2 = self.length # We didn't find any matches
return yield(obj) if block_given?
else
self.length = i2
end
end

def length=(l)
# A method to set the length of the array and make any necessary
internal adjustments
end
end

So, you start out with arr = $array = [1, 2, 3, aFoo, 'b']

And then call
arr.delete(1)


Now lets's step through the delete method

i1 i2 self e e == 1 Action
0 0 [1, 2, 3, aFoo, 'b'] 1 true so we just
increment i1 giving
1 0 [1, 2, 3, aFoo, 'b'] 2 false so we
change self[i0] and increment i2 giving
2 1 [2, 2, 3, aFoo, 'b'] 3 false so we change
self[i0] and increment i2 giving
3 2 [2, 3, 3, aFoo, 'b'] Foo BANG! this clears
$array which is also self which is also arr, since all reference the same
object. The state is now:
3 2 [nil, nil, nil, nil] Foo false Foo#==
returns false so we set self[i2] = e and increment i2 giving:
4 3 [nil, nil, aFoo, nil]

And the loop ends and self.length = 3 adjusts things so that self == arr ==
$array == [nil, nil, aFoo]

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Mike stone

2/23/2009 7:42:00 AM

0



"Rich Rostrom" <rrostrom.21stcentury@rcn.com> wrote in message
news:f4d2da15-dfc4-47ac-a638-0a6cf7256e7c@h5g2000yqh.googlegroups.com...
>
> If Germany does not declare war on Russia, then
> Germany is standing aside while Russia attacks
> Austria.
>



If Russia does so.

OTL the Tsar never declared war on Austria-Hungary. They remained officially
at peace until August 6, when AH declared war on Russia under pressure from
her German ally.

He may never do so. It's a much bigger decision than mobilisation, and he
hesitated even over that. If he does, then Germany can declare war on him at
that point with (assuming Germany is mobilised) nothing in particular lost
by the delay.

Ironically, Austria-Hungary might actually have fared _better_ in these
circs. Lacking German support, Conrad would probably be forced to fight a
purely defensive war in Galicia, rather than the attempted offensive which
led to disaster at Lemberg.
Ironi

--


Mike Stone - Peterborough, England

"Freddie experienced the sort of abysmal soul-sadnesswhich afflicts one of
Tolstoy's Russian peasants when, after putting in a heavy day's work
strangling his father, beating his wife, and dropping the baby in the
reservoir, he turns to the cupboard only to find the vodka bottle empty".


P G Wodehouse - Jill the Reckless