在评估 Class.new 中的块时保持对隐式接收器“self”的访问?
有时,当 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”是 Sinatra:
class App < Sinatra::Base
def self.some_method
end
get "/" do
yadda_yadda(some_method) # <-- can't do this!
end
end
也许我没有抓住要点?
Sometimes when APIs call for the use of blocks, I find it frustrating when I realise they are rebinding self
, therefore taking me out of the current implicit receiver context. Usually I just do something like assign a local variable me = self
before the block, then invoke methods on that. It feels like a hack. Is there a "correct" way to do this? Sort of like implicitly inserting the current self
into the inheritance hierarchy of the new class?
class ClassMaker
def do_something_complex
end
def make_a_class
me = self
Class.new do
me.do_something_complex # <-- This
end
end
end
When the blocks are repeated across a series of methods in the same class, you have to copy self
repeatedly, which seems messy and like there's probably a better way? This doesn't only apply to Class.new
, but to anything that changes the implicit receiver.
UPDATE: This is interesting, though it doesn't solve the problem unless you can rewrite the API you're forced to work with: http://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation (note that the "API" I'm currently working with is Sinatra:
class App < Sinatra::Base
def self.some_method
end
get "/" do
yadda_yadda(some_method) # <-- can't do this!
end
end
Maybe I'm missing the point?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请注意,您无法在 Ruby 中重新绑定
self
,因此不会发生这种情况。相反,Ruby 中的某些点self
会发生变化,最好 仔细阅读。在 Sinatra 示例中,很明显您不能这样做,因为
some_method
是一个类方法,并且它们需要一个显式接收器。尝试类似self.class.some_method
的方法,它应该可以工作。您的“hack”并不罕见,您经常会看到
klass
作为变量名称,而不是me
。看看你的代码,我想知道你的问题是否在于尝试从其他语言移植模式而不知道如何在 Ruby 中进行操作。也许有了更多的背景,我们就能更好地提供帮助。
Please note that you can't rebind
self
in Ruby, so that's not what happening. Instead the there are certain points in Ruby whereself
changes, it's a good idea to read up on that.In the Sinatra example it's kinda obvious that you can't do this, since
some_method
is a class method and they need an explicit receiver. Try something likeself.class.some_method
and it should work.Your "hack" isn't so uncommon, you'll often see
klass
as the variable name instead ofme
.Looking at your code I wonder if your problem lies in trying to port over a pattern from some other language and not knowing how to go about it in Ruby. Maybe with more context we'd be able to better help.