如何在Ruby中检索调用者上下文对象?

时间:2010-04-10 18:35:57

标签: ruby metaprogramming

此后是我要简化的代码片段,以避免在每次调用时传递额外的参数。实际上,我的用例是M是一个用户库,没有在每个方法上定义context参数。 check是一种未由用户定义的方法。

# User code
module M
  def do_something(context)
    puts "Called from #{context}"
    context.check
  end
  module_function :do_something
end

# Application code
class Bar
  def check
    puts "Checking from #{self}..."
  end
end

class Foo < Bar
  def do_stuff(scope, method)
    scope.send method, self
  end
end

# Executed by user
Foo.new.do_stuff M, :do_something

为了检索self方法,有没有办法在不将do_something作为check方法的输入参数传递的情况下进行同样的思考?

# User code
module M
  def do_something
    called_from_object = ???
    puts "Called from #{called_from_object}"
    called_from_object.check
  end
  module_function :do_something
end

# Application code
class Bar
  def check
    puts "Checking from #{self}..."
  end
end

class Foo < Bar
  def do_stuff(scope, method)
    scope.send methood
  end
end

# Executed by user
Foo.new.do_stuff M, :do_something

感谢您的支持!

2 个答案:

答案 0 :(得分:5)

在为自己的目的寻找答案时遇到过这篇文章。

没有找到合适的,所以我挖掘了Ruby源并组合了一个扩展。我把它捆绑成一个gem-应该安装没有任何问题,只要你使用Ruby 1.9.1:

  

sudo gem install sender

这个对于Ruby 1.8不起作用,因为1.8有一个不同的跟踪帧模型。

http://rubygems.org/gems/sender

答案 1 :(得分:1)

不是您要求的,但如果Foo包括M,那么您是否可以实现您所追求的目标? e.g。

module M
  def do_something
    puts "I am going to use the test method from the including class"
    test
  end
end

class Foo
  include M
  def test
    puts "In Foo's test method"
  end

  def do_stuff
    do_something
  end
end

然后你可以这样做:

irb(main):019:0> Foo.new.do_stuff
I am going to use the test method from the including class
In Foo's test method

如果想要让模块提供一些通用功能并在类中具有细节,那么这是ruby中相当常见的模式,例如: Comparable模块要求包含类实现<=>