2009-12-02 45 views
2

如果我有两个数组ab,包含的对象必须覆盖哪种方法,这样减法-才能正常工作?需要什么方法让“ - ”(减法)方法与Ruby数组一起工作?

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 

但是这是行不通的,因为ab被关押在数组中。我想知道我需要在我的课程中重写什么方法才能正常工作。

+0

你能定义“正常工作”吗?现在,从array1中减去array2,可以删除array2中存在的任何项目。我想这似乎是预期的效果。 – 2009-12-02 03:31:54

+0

@dcneiner:对于每一个对象? ...我正在定义...让我把这个问题 – OscarRyz 2009-12-02 03:34:39

回答

4

您需要重新定义#eql?hash方法。

你可以将其定义为:

def hash 
    id.hash + 32 * desc.hash 
end 

详情:

要看看什么东西被称为红宝石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 2009-12-02 03:42:55

+0

呃...... :)我认为这有点太先进了我只是还没有.....让我咀嚼它一段时间;) – OscarRyz 2009-12-02 04:06:54

+0

好的,我做了'def hash'并包括这个:'id.has + 32 * desc.hash',但它仍然不起作用。我错过了什么? – OscarRyz 2009-12-02 04:12:39