在评估Class.new中的块时,保持对隐式接收器“self”的访问?

时间:2011-10-23 07:03:23

标签: ruby metaprogramming

有时当API要求使用块时,当我意识到它们正在重新绑定self时,我发现它令人沮丧,因此将我从当前的隐式接收器上下文中取出。通常我只是做一些事情,比如在块之前分配一个局部变量me = self,然后在那里调用方法。感觉就像一个黑客。有没有“正确”的方法来做到这一点?类似于将当前self隐式插入到新类的继承层次结构中?

class ClassMaker
  def do_something_complex
  end

  def make_a_class
    me = self
    Class.new do
      me.do_something_complex # <-- This
    end
  end
end

当在同一个类中的一系列方法中重复这些块时,你必须重复复制self,这看起来很混乱,并且可能有更好的方法吗?这不仅适用于Class.new,也适用于任何改变隐式接收器的内容。

更新:这很有意思,虽然它不能解决问题,除非您可以重写您被迫使用的API:http://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation(请注意,我目前正在使用的“API”是屈:

class App < Sinatra::Base
  def self.some_method
  end

  get "/" do
    yadda_yadda(some_method) # <-- can't do this!
  end
end

也许我错过了这一点?

1 个答案:

答案 0 :(得分:2)

  1. 请注意,您无法在Ruby中重新绑定self,因此不会发生这种情况。相反,在self更改的Ruby中存在某些点,read up on that是个好主意。

  2. 在Sinatra示例中,显然你不能这样做,因为some_method是一个类方法,他们需要一个明确的接收者。尝试类似self.class.some_method的内容,它应该有用。

  3. 您的“黑客”并不罕见,您经常会将klass视为变量名而不是me

  4. 查看您的代码我想知道您的问题是否在于尝试从其他语言移植模式而不知道如何在Ruby中使用它。也许有更多的背景,我们可以更好地帮助。