在Ruby中,有没有一种方法可以在任意对象上执行块,这样我们就可以拥有作用域变量



以以下示例为例:

greeting = "world hello".split.reverse.join(" ")
greeting << ", here me shouting!!"
greeting.upcase!
p greeting # "HALLO WORLD, HERE ME SHOUTING!!"

这使用局部变量greeting来存储字符串。现在,如果我们已经在代码的早期使用了这个变量,那么它的原始值现在就会丢失。

greeting = "Hi World."
...
greeting = "world hello".split.reverse.join(" ")
greeting << ", here me shouting!!"
greeting.upcase!
p greeting # "HALLO WORLD, HERE ME SHOUTING!!" ... original "Hi World." is gone.

所以我在想,是否有一种方法可以通过使用块来为这样的小片段创建一个范围。变量greeting将进入块中,并且只覆盖外部变量,而不覆盖它:

greeting = "Hi World."
"world hello".scope do |greeting|
  greeting.split.reverse.join(" ")
  greeting << ", here me shouting!!"
  greeting.upcase!
  p greeting # "HALLO WORLD, HERE ME SHOUTING!!"
end
p greeting # "Hi World."

注意我在这里使用的方法scope。我把这个方法猴痘接种到Object中。scope获取块,并用self:的局部变量生成块

class Object
  def scope
    yield self
  end
end

依赖monkey修补Object类,尤其是使用一个名为scope的方法,我感到很不舒服,它似乎可能会被其他类覆盖,这些类的实例不能再像这样确定范围了。

那么,Ruby中有没有内置的方法可以做到这一点

此外,如果我必须继续使用monkey补丁,我认为self可能是比scope更好的方法名称。即使也是关键字,也可以将其定义为方法名称;self似乎不太可能被其他类覆盖。它也很适合其他最常用的"块方法"each:的风格

collection.each do

"在每个元素上执行以下块。"

object.self do

"在(您的)自己上执行以下块"。

使用self作为方法名称有什么缺点吗?(感谢其他命名建议)

这个问题已经被反复问过了。一种方法是:

"world hello".instance_eval do
  ...
end

但是这是重的并且不是优选的。建议的更好的方法是:

"world hello".tap do |s|
  ...
  break s
end

但在您的特定情况下,方法链是最简单的:

"world hello"
.split
.reverse
.join(" ")
.concat(", here me shouting!!")
.upcase
.tap{|s| p s}

相关内容

最新更新