Array Difference

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] ?

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

On 17.08.2007 21:00, Gordon T. 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)]
=> [#, #]
irb(main):005:0> p2 = [Prova.new(2)]
=> [#]
irb(main):006:0> p1 - p2
=> [#]

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

On Fri, 17 Aug 2007 22:17:25 +0200, Robert K. 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

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

end

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

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

Thanks for the tip, I’ve tried to do things like
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

On 18.08.2007 01:05, Ken B. wrote:

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