4

我的职能是:

def hello(str)
  puts "hello #{str}"
end

def hello_scope(scope, &block)
  # ???
end

我想在我的方法块中临时增加一个函数。

hello_scope中,我只是想在将scope字符串str传递给原始hello方法之前将其添加到之前。这是一个例子:

hello 'world'               #=> hello world

hello_scope "welcome!" do
  hello 'bob'               #=> welcome!hello bob
  hello 'alice'             #=> welcome!hello alice
end

当谈到 Ruby 中的这种事情时,我是个菜鸟。有人可以帮助我以优雅的方式解决这个问题吗?


编辑:

如果它使事情变得更容易,我们可以将方法作为参数传递给块,例如:

hello_scope "welcome!" do |h|
  h "bob"                     #=> welcome!hello bob
  h "alice"                   #=> welcome!hello alice
end
4

2 回答 2

4

一种方法是创建一个“评估上下文对象”,块将在该对象上进行实例评估。该对象必须提供特定于块的所有方法。在下面的示例中,我没有使用相同的名称,因为我不记得如何显式引用全局方法“hello”(以避免无限递归)。在适当的库中,“hello”将在某处定义为类方法,因此这不是问题。

例如

def hello(str)
  puts "hello #{str}"
end
class HelloScope
  def h(str)
    print scope
    hello(str)
  end
end
def hello_scope(scope, &block)
  HelloScope.new(scope).instance_eval(&block)
end
于 2013-03-22T07:25:10.157 回答
0

只需修改您的“hello”方法以考虑当前范围:

class Greeter
  def initialize
    @scope = nil
  end

  def hello(str)
    puts "#{@scope}hello #{str}"
  end

  def with_scope(scope)
    @scope = scope
    yield
    @scope = nil
  end
end

Greeter.new.instance_eval do
  hello 'world'               #=> hello world

  with_scope "welcome!" do
    hello 'bob'               #=> welcome!hello bob
    hello 'alice'             #=> welcome!hello alice
  end
end
于 2013-03-22T08:14:02.077 回答