次の例を見てください。
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
Object特に というメソッドを使用して、クラスにモンキー パッチを適用することに頼るのは、まったく快適ではありscopeません。このメソッドは、他のクラスによってオーバーライドされる可能性が高く、そのインスタンスをこのようにスコープすることはできなくなります。
では、Ruby にこれを行う組み込みの方法はありますか?
また、モンキーパッチにとどまらなければならない場合はself、 よりも良いメソッド名かもしれないと考えていましたscope。キーワードでもありますが、メソッド名として定義できます。それは動作します、私はそれをテストしました。self他のクラスによってオーバーライドされる可能性はほとんどないようです。また、他の最も一般的に使用される「ブロックメソッド」のスタイルにもうまく適合しますeach。
collection.each do
「各要素で次のブロックを実行します。」
object.self do
「 (あなたの)自分で次のブロックを実行します」。
selfメソッド名として使用することの欠点はありますか? (他の命名の提案は大歓迎です)。