2017-08-02 9 views
3

私はRubyの/ elsif/elseについて読んでいましたが、制御式がどのように動作するかを記述するときには、用語のいくつかの違いに遭遇しました。Rubyでは、if/elsif/else文の従属ブロックは、パラメータとして渡される 'ブロック'と同じですか?

Ruby Programming Wikibooks(強調追加)において:

条件分岐は、テスト式の結果を受け取り、テスト式が真であるか偽であるかによってコードのブロックを実行します。

アン発現場合、例えば、コードの下位ブロックを実行するか否かを判断するだけでなく、値そのものになります。

Ruby-doc.orgが、しかし、定義でのすべてのブロックを言及していない:

最も単純な式は二つの部分、「テスト」という表現と「その後」表現を持っている場合。 "test"式がtrueと評価された場合、 "then"式が評価されます。

通常、私がRubyで 'ブロック'について読んだ場合、ほとんどの場合、procsとlambdasのコンテキスト内にあります。例えば、rubylearning.comブロック定義:

Aルビーブロックの文をグループ化する方法であって、メソッド呼び出しに隣接するソースにのみ表示されてもよいです。 ブロックは、メソッド呼び出しの最後のパラメータ(またはパラメータリストの閉じ括弧)と同じ行から書き込まれます。

質問:

  • Rubyでコードのブロックについて話すとき、私たちはメソッドに渡されるコードのグループ について話しているか、我々は単に のグループについて話しています一般的なコードですか?
  • 2つの間を簡単に区別する方法はありますか(そしてそこには の技術的な違いがありますか)。これらの質問のための

コンテキスト:彼らは後に、ブロック、procsの、そしてラムダに導入されたときに、新しいRubyのプログラマーへの混乱を招くことになるブロックとして条件文の内のコードを参照する場合、私は疑問に思って。

答えて

1

TL; DR if...endは、ブロック

発現ないRubyで用語blockの適切な使用は、do...endまたは中括弧{...}間でメソッドに渡されたコードです。ブロックは、メソッド署名内で&block構文を使用することによって、メソッド内でProcに暗黙的に変換できます。この新しいProcProcが暗黙的に作成されている、上記のコードで

def block_to_proc(&block) 
    prc = block 
    puts prc 
    prc.class 
end 

block_to_proc { 'inside the block' } 
# "#<Proc:[email protected](irb):21>" 
# => Proc 

...繰り返し呼び出さ変数やデータ構造に格納されている他の方法、などに渡すことができ、独自のメソッドを持つオブジェクトでありますそのブロックを本体として変数blockに割り当てます。同様に、Proc(またはlambda、タイプはProc)をブロックに「展開」して、引数リストの末尾に&blockの構文を使用することで、ブロックを予想しているメソッドに渡すことができます。

def proc_to_block 
    result = yield # only the return value of the block can be saved, not the block itself 
    puts result 
    result.class 
end 

block = Proc.new { 'inside the Proc' } 

proc_to_block(&block) 
# "inside the Proc" 
# => String 

ややblock秒とProc sの双方向のストリートのがありますが、それらは同じではありませんね。 Procを定義するには、blockProc.newに渡す必要があります。厳密に言えば、blockは、明示的に呼び出されるまで実行が延期されるメソッドに渡される単なるコードです。 Procblockで定義され、呼び出されるまでその実行も延期されますが、それは他のオブジェクトとまったく同じです。 blockはそれ自体では生き残ることができません。Procができます。 if...else...endbegin...rescue...enddef...endclass...endmodule...enduntil...end:一方、block又はblock of code時々何気なくルビーで囲まれたコードのいずれか控えめチャンクを指すために使用される

endで終わるキーワード。しかし、これらは本質的にブロックではなく、実際にはそれらを表面上に似ています。彼らはしばしば、何らかの条件が満たされるまで実行を延期します。しかし、彼らは完全に独立して立つことができ、いつも戻り値を持っています。 Ruby-doc.orgの「表現」の使用はより正確です。プログラミング言語の表現は、プログラミング言語解釈する一つまたは 以上の明示的な値、定数、変数、演算子、および関数 の組み合わせであるwikipedia

から

(その特定 規則に従って優先度と関連性)を計算し、別の値を生成するように計算します(ステートフルな環境では " に戻ります")。

あなたはこの

return_value = if 'expression' 
    true 
end 

return_value # => true 

のようなものがブロック

return_value = do 
    true 
end 

# SyntaxError: (irb):24: syntax error, unexpected keyword_do_block 
# return_value = do 
#    ^

でブロックが独自に表現ではないことをやってみ行うことができます理由です。生き残るためには、yieldまたはProcへの変換が必要です。ブロックを必要としないメソッドにブロックを渡すとどうなりますか?

ブロックは完全に失われています。戻り値がなく、実行されず、まったく存在しないかのようにブロックが消えます。式を完成させて戻り値を生成するには、yieldが必要です。

class Object 
    def puts(*args) 
    super 
    yield if block_given? 
    end 
end 

puts("mindful") { "of blocks" } 
# "mindful" 
# => "of blocks" 
関連する問題