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

···

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

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

···

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

--Ken

···

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

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

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

···

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.

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

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

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

···

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.

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

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