0

我想覆盖发送对象,就像这样

class Object
    @@object_send = self.instance_method( :send )

    def send *args
        @@object_send.bind( self ).call *args
    end
end

或者

class Object
    def send *args
        __send__ *args
    end
end

或者

class Object
    alias_method :old_send, :send

    def send *args
        old_send *args
    end
end

但是所有这些选项都会导致出现此错误

/opt/local/lib/ruby1.9/gems/1.9.1/gems/minitest-2.8.1/lib/minitest/unit.rb:871:in `block in process_args': unsupported argument type: Integer (ArgumentError)
    from /opt/local/lib/ruby1.9/gems/1.9.1/gems/minitest-2.8.1/lib/minitest/unit.rb:862:in `new'
    from /opt/local/lib/ruby1.9/gems/1.9.1/gems/minitest-2.8.1/lib/minitest/unit.rb:862:in `process_args'
    from /opt/local/lib/ruby1.9/gems/1.9.1/gems/minitest-2.8.1/lib/minitest/unit.rb:912:in `_run'
    from /opt/local/lib/ruby1.9/gems/1.9.1/gems/minitest-2.8.1/lib/minitest/unit.rb:905:in `run'
    from /opt/local/lib/ruby1.9/gems/1.9.1/gems/minitest-2.8.1/lib/minitest/unit.rb:685:in `block in autorun'

有什么我可以做的吗?

更新:尝试更新到 2.9.1 但这并没有解决问题

4

1 回答 1

1

没有 MWE,我很难分析您的问题。也许我找到了解决您问题的第一个提示。

我试图重建错误,但没有成功:

class Object
    alias_method :old_send, :send

    def send *args
        old_send *args
    end
end
n = 5
puts n.send(:*, 2)

我明白了10

但是对于块我遇到了一个问题:

puts n.send(:times){ |i| p i } #-> #<Enumerator:0xb778a8>

稍作修改,您就可以看到发生了什么:

class Object
    alias_method :old_send, :send

    def send *args
        puts "send called with #{args}"  #--> [:times]
        old_send *args
    end
end

n = 5
n.send(:times){ |i| p i }

你得到

send called with [:times]

该块丢失。您必须将 proc 参数添加到重新定义中:

class Object
    alias_method :old_send, :send

    def send *args, &proc
        old_send *args, &proc
    end
end

n = 5
n.send(:times){ |i| p i } #-> 1 2 3 4 5
于 2011-12-19T23:07:52.480 回答