ruby - 在不更改其上下文的情况下使方法在 block 中可用?

标签 ruby

我想创建一个执行以下操作的类:

  • 它的实例接受一个 block 。
  • 在实例初始化期间,它执行某些操作,然后调用 block ,然后执行更多操作。
  • 在 block 内,该类的另一个方法应该可用。

这是我希望它的工作方式:

Foo.new do
  puts "Hell, I can get you a toe by 3 o'clock this afternoon..."
  bar
  puts "...with nail polish."
end

我已经通过以下类(class)成功实现了它:

class Foo

  def initialize(&block)

    puts "This represents a beginning action"

    instance_eval &block

    puts "This symbolizes an ending action"

  end

  def bar
    puts "I should be available within the block."
  end

end

如您所见,我使用了 instance_eval 技巧。它允许在 block 内使用 bar

它工作正常,但这里的问题是 instance_eval 使当前本地上下文不可用。如果我在另一个类中使用它,我将无法访问该类的方法。例如:

class Baz
  def initialize
    Foo.new do
      bar  # -> Works
      quux # -> Fails with "no such method"
    end
  end

  def quux
    puts "Quux"
  end
end

问题是:我如何允许在 block 内执行 bar 而不会失去对 quux 的访问权限?

我新手想到的唯一方法是将 bar 作为参数传递到 block 中。但这需要更多的输入,所以我想尽可能避免这种情况。

最佳答案

instance_eval 不考虑调用 block 的范围,因此每个方法调用仅与 Foo 中定义的内容相关。

所以你有两个选择。要么

def initialize
  baz = self
  Foo.new do
    bar  # -> Works
    baz.quux # -> Works
  end
end

def initialize
  puts "This represents a beginning action"
  yield self
  puts "This symbolizes an ending action"
end

....

def initialize
  Foo.new do |b|
    b.bar  # -> Works too
    quux # -> Works too
  end
end

我不确定哪一个在性能方面会更好,但您选择的选项取决于您自己的偏好。

关于ruby - 在不更改其上下文的情况下使方法在 block 中可用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25106615/

相关文章:

ruby-on-rails - 设计路由错误 : No route matches [GET] "/users/sign_out"

ruby - 在 Ruby 中,group_by 我知道每组只有 1 个元素

ruby-on-rails - 根据不确定的哈希长度生成行号

ruby - 当无法重新保存文档时,如何克服 "Ole::Storage::FormatError: OLE2 signature is invalid"错误?

ruby-on-rails - 评估数组是否有 ruby​​ 中的任何项目

ruby - 如何将字符串列表转换为 ruby​​ 中的一个字符串?

ruby - 访问类主体中的方法

ruby-on-rails - rspec assert_equal 没有方法错误

ruby - 在 ruby​​ 中创建大文件 xml

ruby - 工厂女孩的奇怪问题