Ruby/Rubyの基礎知識

ブロックとイテレータ、および手続きオブジェクトProcとlambdaについて(3ページ目)

Rubyの特徴的な文法であるブロックとイテレータについて解説を行います。標準イテレータのほか、自分でブロック付きメソッドを定義する方法、そして最後にブロックを手続きオブジェクトとして扱うProcとlambdaについて解説します。

橋本 拓也

執筆者:橋本 拓也

Rubyガイド

lambda

Kernel.#lambdaもProcクラスのインスタンスを生成するメソッドです(lambdaはラムダと読みます)。生成されるオブジェクトはProcクラスのインスタンスですが、Procで作られたのかlambdaで作られたのかを区別するためにProc#lambda?というメソッドが用意されています。

Ruby 1.9からは"lambda"の代わりに -> という書き方(アロー記法)も使えるようになりました。アロー記法の場合は引数が -> {|x| ... } ではなく -> (x) { ... } となることに注意してください。

Procとlambdaの違い

Procとlambdaにはいくつかの違いがあり、おおまかに言うとlambdaの生成する手続きオブジェクトの方が、Procの生成する手続きオブジェクトに比べてメソッドに近い挙動をします。

  1. 引数の数に厳密なのがlambda、寛容なのがProc
  2. returnで自分自身から出るのがlambda、自分自身より上のメソッドをreturnするのがProc

lambdaの場合は引数の数(arity)が異なるとエラーになりますが、Procは足りない分をnilで埋め、余分な引数を捨てたうえで実行しています。

次にreturnの挙動です。

lambda内でreturnすると単にlambdaから出るだけで処理は続いており、Proc内でreturnしたときはwrap_proc自体からもreturnされそこで処理が終わっていることがわかります。

クロージャ

最後にRubyから少し視野を広げて、計算機科学一般における「クロージャ」という概念でRubyのブロック、Proc、lambdaを眺めてみることにします。

クロージャ(closure) とは定義時のスコープにおける環境を保持し、その環境内でコードを実行することが出来るものです。なおここで言う「環境」とは「変数と変数の指すオブジェクトの集合」を指します。

Rubyにおいてクロージャと呼ぶことが出来るものは以下の3つです。

  • ブロック
  • Proc
  • lambda

次のコード片は、ブロック、Proc、lambdaそれぞれの定義時に存在するローカル変数 「x」 をスコープの内側から参照する単純な例です。

※メソッドは定義時の環境を参照できないためクロージャには含まれません。

以上

以上、Rubyを特徴付ける「ブロック」周辺について解説を行いました。

今回に限らず、本連載ではなるべく正確な情報を掲載するよう心掛けています。記事内容に誤りを発見された場合は著者に連絡頂くか、 allabout/021_block.md at master ? memerelics/allabout からプルリクエストを送って頂ければ反映いたします。

【編集部おすすめの購入サイト】
楽天市場で Ruby 関連の書籍を見るAmazon で Ruby 関連の書籍を見る
  • 前のページへ
  • 1
  • 2
  • 3
※記事内容は執筆時点のものです。最新の内容をご確認ください。
※OSやアプリ、ソフトのバージョンによっては画面表示、操作方法が異なる可能性があります。

あわせて読みたい

あなたにオススメ

    表示について

    カテゴリー一覧

    All Aboutサービス・メディア

    All About公式SNS
    日々の生活や仕事を楽しむための情報を毎日お届けします。
    公式SNS一覧
    © All About, Inc. All rights reserved. 掲載の記事・写真・イラストなど、すべてのコンテンツの無断複写・転載・公衆送信等を禁じます