【问题标题】:What method is needed to have the "-" ( subtract ) method working with Ruby arrays?使用 Ruby 数组的“-”(减法)方法需要什么方法?
【发布时间】:2009-12-02 03:22:07
【问题描述】:

如果我有两个数组ab,那么包含的对象应该重写什么方法,这样减法- 才能正常工作?

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 被保存在数组中。我想知道我需要在我的类中重写什么方法才能使其正常工作。

【问题讨论】:

  • 你能定义“正常工作”吗?现在,从array1 中减去array2 将删除array1 中存在于array2 中的任何项目。我想这似乎是想要的效果。
  • @dcneiner:每个对象? ...我正在定义...让我把它放在问题上

标签: ruby arrays subtraction


【解决方案1】:

您需要重新定义#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]
    => []

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

【讨论】:

  • mmhh 让我们看看... ruby​​ -version : 我有 1.8.7 :(
  • uhh... :) 我认为这对我来说有点太高级了.....让我咀嚼一会儿;)
  • 好的,我做了def hash 并包括这个:id.has + 32 * desc.hash,但它仍然无法正常工作。我错过了什么?
  • 好吧,至少我可以看到它正在被调用。我要覆盖 eql 吗?还有吗?
  • 不错的一个!所以实际上你应该为对象定义一个好的散列函数,然后是 eql?函数确实很简单(比较哈希)。
猜你喜欢
  • 2020-05-18
  • 1970-01-01
  • 2020-09-02
  • 2014-10-07
  • 2010-11-02
  • 2015-02-07
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多