2009-12-02 4 views
2

Если у меня есть два массива a и b, какой метод должен содержать объект, который должен переопределить, поэтому метод вычитания - работает правильно?Какой метод необходим для использования метода «-» (вычитания) с массивами Ruby?

Достаточно с eql?

EDIT

я добавляю более подробно на мой вопрос.

Я этот класс определен:

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 

Ok?

Затем я заполнил свои два массива из разных частей, и я хочу получить разницу.

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 хранятся в массиве. Мне интересно, какой метод мне нужно переопределить в моем классе, чтобы он работал правильно.

+0

Можете ли вы определить, что «работает правильно»? Прямо сейчас, вычитая array2 из array1, удаляется любой элемент в массиве 1, который существует в array2. Думаю, похоже, что это желаемый эффект. –

+0

@ dcneiner: Для каждого объекта? ... Я определяю ... позвольте мне сказать это по вопросу – OscarRyz

ответ

4

Вам необходимо переопределить #eql? и метод hash.

Вы можете определить его как:

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] 
    => [] 

То же самое верно и в рубин 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] 
    => [] 
+0

mmhh давайте посмотрим ... ruby ​​-version: У меня есть 1.8.7 :( – OscarRyz

+0

uhh ... :) Я думаю, что это слишком продвинуто для я просто еще ... позволь мне немного пережевать его;) – OscarRyz

+0

Хорошо, я сделал 'def hash' и включил это:' id.has + 32 * desc.hash', и все же он не работает. Что мне не хватает? – OscarRyz

 Смежные вопросы

  • Нет связанных вопросов^_^