以以下示例为例:
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}