Какой метод необходим, чтобы метод «-» (вычитание) работал с массивами Ruby?
-
11-09-2019 - |
Вопрос
Если у меня есть два массива a
и b
, какой метод должен переопределить содержащийся объект, чтобы метод вычитания -
работает нормально?
Достаточно ли с eql?
РЕДАКТИРОВАТЬ
Я добавляю больше деталей к своему вопросу.
У меня определен этот класс:
class Instance
attr_reader :id, :desc
def initialize( id , desc )
@id = id.strip
@desc = desc.strip
end
def sameId?( other )
@id == other.id
end
def eql?( other )
sameId?( other ) and @desc == other.desc
end
def to_s()
"#{id}:#{desc}"
end
end
Хорошо?
Затем я заполнил два своих массива из разных частей и хочу получить разницу.
a = Instance.new("1","asdasdad")
b = Instance.new("1","a")
c = Instance.new("1","a")
p a.eql?(b) #false
p b.eql?(c) #true
x = [a,b]
y = [c]
z = x - y # should leave a because b and c "represent" the same object
Но это не работает, потому что a
и b
хранятся в массиве.Мне интересно, какой метод мне нужно переопределить в моем классе, чтобы это работало правильно.
Решение
Вам нужно переопределить #eql?
и хэш метод.
Вы можете определить это как:
def hash
id.hash + 32 * desc.hash
end
Подробности:
Чтобы увидеть, что вызывается в Ruby 1.9:
% irb
>> class Logger < BasicObject
>> def initialize(delegate)
>> @delegate = delegate
>> end
>> def method_missing(m,*args,&blk)
>> ::STDOUT.puts [m,args,blk].inspect
>> @delegate.send(m,*args,&blk)
>> end
>> end
=> nil
>> object = Logger.new(Object.new)
[:inspect, [], nil]
=> #<Object:0x000001009a02f0>
>> [object] - [0]
[:hash, [], nil]
[:inspect, [], nil]
=> [#<Object:0x000001009a02f0>]
>> zero = Logger.new(0)
[:inspect, [], nil]
=> 0
>> [zero] - [0]
[:hash, [], nil]
[:eql?, [0], nil]
=> []
То же самое верно и в Ruby 1.8.7.
% irb18
>> class Logger < Object
>> instance_methods.each { |m| undef_method m }
>> def initialize(delegate)
>> @delegate = delegate
>> end
>> def method_missing(m,*args,&blk)
>> ::STDOUT.puts [m,args,blk].inspect
>> @delegate.send(m,*args,&blk)
>> end
>> end
(irb):2: warning: undefining `__send__' may cause serious problem
(irb):2: warning: undefining `__id__' may cause serious problem
=> nil
>> object = Logger.new(Object.new)
[:inspect, [], nil]
=> #<Object:0x100329690>
>> [object] - [0]
[:hash, [], nil]
[:inspect, [], nil]
=> [#<Object:0x100329690>]
>> zero = Logger.new(0)
[:inspect, [], nil]
=> 0
>> [zero] - [0]
[:hash, [], nil]
[:eql?, [0], nil]
=> []
Не связан с StackOverflow