[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Array Difference

Matteo Gottardi

8/17/2007 6:27:00 PM

Hi all. Why this don't work??

# Begin code
class Prova
attr_accessor :n
def initialize(n)
@n = n
end
def to_s
"#{@n}"
end
def ==(other)
@n == other.n
end
end

p1 = [Prova.new(1), Prova.new(2)]
p2 = [Prova.new(2)]
puts (p1 - p2)
# End code

Why the difference doesn't work like [1, 2] - [2] ?
--
* Matteo Gottardi | matgott@tin.it
* ICQ UIN 20381372
* Linux - the choice of a GNU generation
* GPG Fingerprint:
* B9EE 108F 52C8 D50C B667 B1F2 AB56 8A01 BA3D 36A1
6 Answers

Gordon Thiesfeld

8/17/2007 7:01:00 PM

0

> Why the difference doesn't work like [1, 2] - [2] ?
> --

Prova.new(2) and Prova.new(2) are two different objects. But with
Fixnums, there is only ever one 2.

?> p1 = [Prova.new(1), Prova.new(2)]
=> [#<Prova:0x2e91c34 @n=1>, #<Prova:0x2e91c20 @n=2>]
>> p2 = [Prova.new(2)]
=> [#<Prova:0x2e8fcf4 @n=2>]
>> puts (p1 - p2)
1
2
=> nil
>>

Robert Klemme

8/17/2007 8:17:00 PM

0

On 17.08.2007 21:00, Gordon Thiesfeld wrote:
>> Why the difference doesn't work like [1, 2] - [2] ?
>> --
>
> Prova.new(2) and Prova.new(2) are two different objects. But with
> Fixnums, there is only ever one 2.

That's not the reason: you have to implement the right methods:

irb(main):001:0> class Foo; def eql?(o) true end; def hash() 0 end end
=> nil
irb(main):002:0> [Foo.new, Foo.new]-[Foo.new]
=> []

Matteo, it's easier when you use Struct. In that case your class
becomes a one liner:

Prova = Struct.new :n

irb(main):003:0> Prova = Struct.new :n
=> Prova
irb(main):004:0> p1 = [Prova.new(1), Prova.new(2)]
=> [#<struct Prova n=1>, #<struct Prova n=2>]
irb(main):005:0> p2 = [Prova.new(2)]
=> [#<struct Prova n=2>]
irb(main):006:0> p1 - p2
=> [#<struct Prova n=1>]

If you need more methods you can use a block:

Prova = Struct.new :n do
def your_method(x)
x + n
end
end

Kind regards

robert

Ken Bloom

8/17/2007 8:38:00 PM

0

On Fri, 17 Aug 2007 20:26:33 +0200, Matteo Gottardi wrote:

> Hi all. Why this don't work??
>
> # Begin code
> class Prova
> attr_accessor :n
> def initialize(n)
> @n = n
> end
> def to_s
> "#{@n}"
> end
> def ==(other)
> @n == other.n
> end
> end
>
> p1 = [Prova.new(1), Prova.new(2)]
> p2 = [Prova.new(2)]
> puts (p1 - p2)
> # End code
>
> Why the difference doesn't work like [1, 2] - [2] ?

A hash is used internally, and hash keys are compared for equality using
#eql?. You also need to override #hash.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Ken Bloom

8/17/2007 11:05:00 PM

0

On Fri, 17 Aug 2007 22:17:25 +0200, Robert Klemme wrote:
> If you need more methods you can use a block:
>
> Prova = Struct.new :n do
> def your_method(x)
> x + n
> end
> end

Thanks for the tip, I've tried to do things like

class Foo < Struct.new(:a,:b)
def method
end
end

and while it works, it felt sorta hackish.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Robert Klemme

8/19/2007 11:22:00 AM

0

On 18.08.2007 01:05, Ken Bloom wrote:
> On Fri, 17 Aug 2007 22:17:25 +0200, Robert Klemme wrote:
>> If you need more methods you can use a block:
>>
>> Prova = Struct.new :n do
>> def your_method(x)
>> x + n
>> end
>> end
>
> Thanks for the tip, I've tried to do things like
>
> class Foo < Struct.new(:a,:b)
> def method
> end
> end
>
> and while it works, it felt sorta hackish.

If by "hackish" you mean that this creates one additional class then
yes, sort of. Other than that it's ok, but I usually prefer the non
inheritance version in these cases since only one class is needed.

Kind regards

robert

Ken Bloom

8/19/2007 4:38:00 PM

0

On Sun, 19 Aug 2007 13:22:13 +0200, Robert Klemme wrote:

> On 18.08.2007 01:05, Ken Bloom wrote:
>> On Fri, 17 Aug 2007 22:17:25 +0200, Robert Klemme wrote:
>>> If you need more methods you can use a block:
>>>
>>> Prova = Struct.new :n do
>>> def your_method(x)
>>> x + n
>>> end
>>> end
>>
>> Thanks for the tip, I've tried to do things like
>>
>> class Foo < Struct.new(:a,:b)
>> def method
>> end
>> end
>>
>> and while it works, it felt sorta hackish.
>
> If by "hackish" you mean that this creates one additional class then
> yes, sort of. Other than that it's ok, but I usually prefer the non
> inheritance version in these cases since only one class is needed.
>
> Kind regards
>
> robert

I've tried two ways actually

Foo=Struct.new(:bar,:baz)
class Foo
def method
end
end

and the inheritance method I've described above.

You know what really makes it seem hackish? RDoc.
I'd like RDoc to document both the attributes of a Struct on normal class
listing, and also document the methods that I create on those Structs in
the same page.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...