Array#uniq - Comparison doesn't use 'eql?' and 'hash'

I am confused about “Array#uniq”. In
http://groups.google.com/group/comp.lang.ruby/msg/e57b80fbcd61aaab it is
described, that one has to redefine “eql?” and “hash”, if one needs an
own
“Array#uniq” interpretation.

I made tests with the result, that neither “eql?” nor “hash” is called.
What
went wrong here?

code >>>>>

class String
alias :org_hash :hash
alias :org_eql? :eql?
def hash
puts ‘String#hash called’
self.org_hash
end
def eql?(other)
puts ‘String#eql? called’
self.org_eql?(other)
end
end

puts ‘Start of test’
a = [‘a’, ‘b’, ‘a’, ‘c’, ‘b’]
b = a.uniq
p b
puts ‘End of test’

Output >>>>>

Start of test
[“a”, “b”, “c”]
End of test

EoE >>>>>

Wolfgang Nádasi-Donner

Wolfgang Nádasi-Donner:

I am confused about “Array#uniq”.

Although you already have the answer on dclr, for this list’s archives:
Strings are handled in a special way, as shown here:

definitions = lambda do

alias :org_equal_op :==
def ==(other)
puts ‘== called’
org_equal_op(other)
end

alias :org_hash :hash
def hash
puts ‘hash called’
org_hash
end

alias :org_eql? :eql?
def eql?(other)
puts ‘eql? called’
org_eql?(other)
end

alias :org_equal? :equal?
def equal?(other)
puts ‘equal? called’
org_equal?(other)
end

end

String.module_eval &definitions
Regexp.module_eval &definitions

puts ‘Regexp:’
p [ /a/, /b/, /a/, /c/, /b/ ].uniq
puts ‘String:’
p %w(a b a c b).uniq

puts “\nRegards, Kalman”

END

Output:

Regexp:
hash called
hash called
hash called
eql? called
hash called
hash called
eql? called
hash called
hash called
hash called
hash called
hash called
[/a/, /b/, /c/]
String:
[“a”, “b”, “c”]

Regards, Kalman

Kalman N. schrieb:

Although you already have the answer on dclr, for this list’s archives:
Strings are handled in a special way, as shown here:…

Then another question came up.

There is one good reason to use class “String” in ad-hoc-tools, instead
of a new
class, that uses class “String”: The constants.

If I write write

a = “this is a string”

an object of class “String” will be created. If I have my wrapper class
“MyString” which uses class “String”, I must use some construct like

a = MyString.new(“this is my string”)

Is there some possibility to shorten this?

Wolfgang Nádasi-Donner

A lot of often used add-on classes use the class method [], for example
Set:
Set[4, 3] == Set.new(4,3)

Also, you could do
[4, 3].to_set

Dan