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

发布于 2024-12-11 04:49:42 字数 901 浏览 0 评论 0原文

有时,当 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无需解释 2024-12-18 04:49:42
  1. 请注意,您无法在 Ruby 中重新绑定 self,因此不会发生这种情况。相反,Ruby 中的某些点 self 会发生变化,最好 仔细阅读

  2. 在 Sinatra 示例中,很明显您不能这样做,因为 some_method 是一个类方法,并且它们需要一个显式接收器。尝试类似 self.class.some_method 的方法,它应该可以工作。

  3. 您的“hack”并不罕见,您经常会看到 klass 作为变量名称,而不是 me

看看你的代码,我想知道你的问题是否在于尝试从其他语言移植模式而不知道如何在 Ruby 中进行操作。也许有了更多的背景,我们就能更好地提供帮助。

  1. Please note that you can't rebind self in Ruby, so that's not what happening. Instead the there are certain points in Ruby where self changes, it's a good idea to read up on that.

  2. 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 like self.class.some_method and it should work.

  3. Your "hack" isn't so uncommon, you'll often see klass as the variable name instead of me.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文