1

次の例を見てください。

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に注意してください。このメソッドを にモンキーパッチしましたObjectscopeブロックを取得し、次のローカル変数で生成しますself:

class Object
  def scope
    yield self
  end
end

Object特に というメソッドを使用して、クラスにモンキー パッチを適用することに頼るのは、まったく快適ではありscopeません。このメソッドは、他のクラスによってオーバーライドされる可能性が高く、そのインスタンスをこのようにスコープすることはできなくなります。

では、Ruby にこれを行う組み込みの方法はありますか?

また、モンキーパッチにとどまらなければならない場合はself、 よりも良いメソッド名かもしれないと考えていましたscope。キーワードでもありますが、メソッド名として定義できます。それは動作します、私はそれをテストしました。self他のクラスによってオーバーライドされる可能性はほとんどないようです。また、他の最も一般的に使用される「ブロックメソッド」のスタイルにもうまく適合しますeach

collection.each do

「各要素で次のブロックを実行します。」

object.self do

「 (あなたの)自分で次のブロックを実行します」。

selfメソッド名として使用することの欠点はありますか? (他の命名の提案は大歓迎です)。

4

1 に答える 1

1

この質問は繰り返し聞かれました。1 つの方法は次のとおりです。

"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}
于 2013-02-22T12:24:37.453 に答える