# Array Difference

**URL:** <https://www.ruby-forum.com/t/array-difference/112352>\
**Category:** Ruby\
**Created:** [August 17, 2007, 8:32pm UTC](https://www.ruby-forum.com/t/array-difference/112352 "2007-08-17T20:32:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 17, 2007, 8:32pm UTC](https://www.ruby-forum.com/t/array-difference/112352/1 "2007-08-17T20:32:27Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 17, 2007, 9:05pm UTC](https://www.ruby-forum.com/t/array-difference/112352/2 "2007-08-17T21:05:32Z")

</div>

> ## 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

---

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 17, 2007, 10:22pm UTC](https://www.ruby-forum.com/t/array-difference/112352/3 "2007-08-17T22:22:39Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 19, 2007, 4:41am UTC](https://www.ruby-forum.com/t/array-difference/112352/4 "2007-08-19T04:41:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 17, 2007, 10:41pm UTC](https://www.ruby-forum.com/t/array-difference/112352/5 "2007-08-17T22:41:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 19, 2007, 6:40pm UTC](https://www.ruby-forum.com/t/array-difference/112352/6 "2007-08-19T18:40:43Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fire-fly](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/a88e57/32.png) [@fire-fly](https://www.ruby-forum.com/u/fire-fly)\
**Post date:** [August 19, 2007, 1:26pm UTC](https://www.ruby-forum.com/t/array-difference/112352/7 "2007-08-19T13:26:11Z")

</div>

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
