7stud2
(7stud --)
6 May 2013 07:01
1
class Router
attr_accessor :make, :model
def initialize(make, model)
@make = make
@model = model
end
def ==(other)
return false unless other.is_a?(Router)
make == other.make && model == other.model
end
end
frequency = Hash.new(0)
models = %w(2000 3000 2000 3200)
models.each{|m| frequency[Router.new('Linksys',m)] += 1}
puts frequency[Car.new('Linksys','2000')]
puts should be '2' but I am getting 'zero'
···
--
Posted via http://www.ruby-forum.com/ .
No the output is correct. Your mistake is assuming that Router.new will
return the same object for the same input parameters. For example:
frequency = Hash.new(0)
models = %w(2000 3000 2000 3200)
models.each{|m| frequency[Router.new('Linksys',m)] += 1}
p frequency => {
#<Router:0x10f80ae70 @model="3000", @make="Linksys">=>1,
#<Router:0x10f80ae20 @model="2000", @make="Linksys">=>1,
#<Router:0x10f80aec0 @model="2000", @make="Linksys">=>1,
#<Router:0x10f80add0 @model="3200", @make="Linksys">=>1
}
Note each entry is a different object. This is the normal and
correct behaviour. When you do:
puts frequency[Router.new('Linksys','2000')]
I assume you meant this and not Car.new it creates yet another object which
of course is not in the hash and so returns 0.
7stud2
(7stud --)
6 May 2013 09:57
3
Ruby Mania wrote in post #1107907:
def ==(other)
return false unless other.is_a?(Router)
make == other.make && model == other.model
That should be eql?, and @make /@model :
def eql?(other)
return false unless other.is_a?(Router)
@make.eql ?(other.make) && @model.eql ?(other.model)
end
end
You also need to override the hash method, e.g.:
def hash()
@make.hash ^ @model.hash
end
end
frequency = Hash.new(0)
models = %w(2000 3000 2000 3200)
models.each{|m| frequency[Router.new('Linksys',m)] += 1}
puts frequency[Car.new('Linksys','2000')]
As noted, should be Router:
puts frequency[Router.new('Linksys','2000')]
···
--
Posted via http://www.ruby-forum.com/\ .
Maybe the example in the Hash docs could be useful to the OP:
Quoting:
"
Hash Keys
Two objects refer to the same hash key when their hash value is
identical and the two objects are eql? to each other.
A user-defined class may be used as a hash key if the hash and eql?
methods are overridden to provide meaningful behavior. By default,
separate instances refer to separate hash keys.
A typical implementation of hash is based on the object’s data while
eql? is usually aliased to the overridden == method:
(...)
"
I hope this helps.
e.
···
On Mon, May 6, 2013 at 9:19 AM, Peter Hickman <peterhickman386@googlemail.com> wrote:
No the output is correct. Your mistake is assuming that Router.new will
return the same object for the same input parameters. For example:
frequency = Hash.new(0)
models = %w(2000 3000 2000 3200)
models.each{|m| frequency[Router.new('Linksys',m)] += 1}
p frequency => {
#<Router:0x10f80ae70 @model="3000", @make="Linksys">=>1,
#<Router:0x10f80ae20 @model="2000", @make="Linksys">=>1,
#<Router:0x10f80aec0 @model="2000", @make="Linksys">=>1,
#<Router:0x10f80add0 @model="3200", @make="Linksys">=>1
}
Note each entry is a different object. This is the normal and correct
behaviour. When you do:
puts frequency[Router.new('Linksys','2000')]
I assume you meant this and not Car.new it creates yet another object which
of course is not in the hash and so returns 0.
7stud2
(7stud --)
6 May 2013 17:22
5
All,
Thanks a lot !
Damm I forgot the simple concept of contract between eql and hashcode
Again thanks !!
Per-erik Martin wrote in post #1107918:
···
Ruby Mania wrote in post #1107907:
def ==(other)
return false unless other.is_a?(Router)
make == other.make && model == other.model
That should be eql?, and @make /@model :
def eql?(other)
return false unless other.is_a?(Router)
@make.eql ?(other.make) && @model.eql ?(other.model)
end
end
You also need to override the hash method, e.g.:
def hash()
@make.hash ^ @model.hash
end
end
frequency = Hash.new(0)
models = %w(2000 3000 2000 3200)
models.each{|m| frequency[Router.new('Linksys',m)] += 1}
puts frequency[Car.new('Linksys','2000')]
As noted, should be Router:
puts frequency[Router.new('Linksys','2000')]
--
Posted via http://www.ruby-forum.com/\ .
I blogged about this a long time ago - in case you need a page for your
bookmarks
http://blog.rubybestpractices.com/posts/rklemme/018-Complete_Class.html
Cheers
robert
···
On Mon, May 6, 2013 at 7:22 PM, Ruby Mania <lists@ruby-forum.com> wrote:
Damm I forgot the simple concept of contract between eql and hashcode
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
**REALLY** great blog post! Information like this is rather invaluable.
···
On Mon, May 6, 2013 at 4:14 PM, Robert Klemme <shortcutter@googlemail.com> wrote:
I blogged about this a long time ago - in case you need a page for your
bookmarks
http://blog.rubybestpractices.com/posts/rklemme/018-Complete_Class.html
Thanks for that Robert. BTW s/robuts/robust/.
Graham
···
On 07/05/2013 07:14, Robert Klemme wrote:
On Mon, May 6, 2013 at 7:22 PM, Ruby Mania <lists@ruby-forum.com > <mailto:lists@ruby-forum.com>> wrote:
Damm I forgot the simple concept of contract between eql and
hashcode
I blogged about this a long time ago - in case you need a page for
your bookmarks
http://blog.rubybestpractices.com/posts/rklemme/018-Complete_Class.html
7stud2
(7stud --)
8 May 2013 12:59
9
Robert Klemme wrote in post #1108013:
···
On Mon, May 6, 2013 at 7:22 PM, Ruby Mania <lists@ruby-forum.com> wrote:
Damm I forgot the simple concept of contract between eql and hashcode
I blogged about this a long time ago - in case you need a page for your
bookmarks
http://blog.rubybestpractices.com/posts/rklemme/018-Complete_Class.html
Excellent this one is.
--
Posted via http://www.ruby-forum.com/\ .