Techioz Blog

開始/終了ブロックから早めに抜け出す

概要

結果が割り当てられる変数を割り当てながら、begin/end ブロックを終了する方法が必要です。

def foo
  @foo ||= begin
    puts "running"

    return "leaving early" if true # would be some sort of calculation

    # Other calculations
  end
end

私が願っていること

> foo
running
=> leaving early
> foo
=> leaving early

実際に何が起こるか

> foo
running
=> leaving early
> foo
running
=> leaving early

@foo を設定せずに return がメソッド全体を終了するため、コードは機能しません。 Break または Next の使用はループ内でのみ機能します。 begin ブロック内で私の思考を妨げるものはありますか?

現在はそれを行うことができますが、回避したいと考えていた方法は次のとおりです。

ブロックの解除については関連する質問がたくさんあるようですが、この特定のバージョンに回答するものが見つかりませんでした (おそらく不可能なため)。

解決策

これらすべてのロジックを独自のメソッドに組み込むだけで、多くの争いを避けられると思います。

def foo
  @foo ||= compute_foo
end

def compute_foo
  puts "running"

  return "leaving early" if true # would be some sort of calculation

  # Other calculations
end

これにより、計算がメモ化から切り離され、テストと推論が容易になります。これは、Ruby やその他の言語ではかなり一般的な設計パターンです。

もちろん、あなたが求めていることを実行する方法はあります。最も明白な解決策は、すぐに呼び出される匿名プロシージャです。

def foo
  @foo ||= (proc do
    puts "running"

    next "leaving early" if true # would be some sort of calculation

    # Other calculations
  end)[] # or .call or .()
end

しかし、あなた自身やこのコードの将来のメンテナに有利になることは決してないでしょう。