【问题标题】:finding instance in method_missing在 method_missing 中查找实例
【发布时间】:2013-01-17 15:01:33
【问题描述】:

我有一种情况,我想打电话

foo.bar.baz arg1,arg2...argn

有时 baz 不会被定义,我将使用 method_missing 但是从从“bar”返回的对象上的 method_missing 中,我希望能够到达“foo”。那就是我想获得 foo 所指对象的引用

我可以假设的一个解决方案是是否有可能获取调用上下文/父上下文的绑定对象。即从method_missing内部获取绑定对象,因为它在调用foo.bar

所以我的问题是,在 method_missing 中是否有任何方法可以让我回溯(在本例中为 foo)?如果我必须对调用进行检测,只要它在解释时完成,并且不使用 #extend 或其他会严重破坏缓存/影响性能的东西。

【问题讨论】:

  • 请对不清楚的地方发表评论(这可能是not a real question)我有一个非常明确的目标,所以如果目标不明确,一些不清楚的地方会很好:)
  • I'd like to be able to get to 'foo'不清楚。你想要 foo 返回的方法或对象的名称吗?从您对sawa的评论来看,它将是 foo 的接收者???
  • 您掌握了foobar 方法还是缺少这些方法?在sawa 的解决方案中,您可以访问自己,即原始接收者。
  • @BernardK 我想获取对象 foo 所指/返回(不是对象 foo 的一部分) foo 是一个表达式。可以是成员、方法或任何其他表达式。酒吧我可以完全访问
  • 还是不清楚。如果 foo 是一个表达式,它返回一个值。您将bar 发送到该值,因此bar 中的self 指的是foo 的结果。如果bar返回的值是self,baz可以访问foo的结果。我错过了什么吗?

标签: ruby metaprogramming


【解决方案1】:
def method_missing *_; self end

【讨论】:

  • 在给定的示例中,它将返回 bar 所指的内容,但我需要 foo 所指的内容
【解决方案2】:
class MyFooClass
    attr_reader :value

    def initialize(value)
        @value = value
    end

        # In order to say foo.bar, the class of foo must define bar.
    def bar
        puts "bar sent to #{self}"
            # return a class where method_missing is defined,
            # and pass it a reference to foo
        MyBarClass.new(self)
    end
end # MyFooClass

class MyBarClass
    def initialize(foo)
        @foo = foo
    end

    def method_missing(name, *args, &block)
        puts "missing #{name} in #{self.class}"
        self.class.class_eval %Q{
            puts "about to define #{name}"
            def #{name}(*args)
                puts "in #{name} on self=#{self} with args=#{args}"
                puts "foo is #{@foo} and it's value is <#{@foo.value}>"
            end
        }
        puts "after define, execute #{name}"
        self.send(name, *args)
    end
end # MyBarClass

foo = MyFooClass.new('value of foo') # result of an expression
foo.bar.baz 'arg1' # define baz for future reference and execute it
print 'MyBarClass.instance_methods : '; p MyBarClass.instance_methods(false)

执行:

$ ruby -w t.rb
bar sent to #<MyFooClass:0x10195c750>
missing baz in MyBarClass
about to define baz
after define, execute baz
in baz on self=#<MyBarClass:0x10195c6b0> with args=arg1
foo is #<MyFooClass:0x10195c750> and it's value is <value of foo>
MyBarClass.instance_methods : ["baz", "method_missing"]

【讨论】:

  • 感谢您的尝试,但不幸的是它不能解决我的问题。我无法更改“MyBarClass”,需要将消息/方法调用重定向到“foo”
猜你喜欢
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2013-08-02
相关资源
最近更新 更多