Какой метод необходим, чтобы метод «-» (вычитание) работал с массивами Ruby?

StackOverflow https://stackoverflow.com/questions/1830470

  •  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]
    => []
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top