Rubyのパラメータと引数の対応付けを理解する(前編)

こんにちは、hachi8833です。今回は英文技術ブログ記事「Ruby Methods, Procs and Blocks」を参考に、Rubyのパラメータと引数についてまとめました。 分量が元記事よりもかなり増えたので、パラメータの話を前編、引数の話を後編として分割いたします。 Rubyのパラメータと引数の対応付けを理解する(後編) 元記事について 原著者の許諾を得て追記・再構成のうえ公開いたします。 元記事: Ruby Methods, Procs and Blocks norswapブログのRuby’s Dark Cornersシリーズより 著者: Nicolas Laurent 元記事のコメントや訂正文もチェックしました。 Rubyのパラメータと引数の対応付けを理解する(前編) 本記事では以下のトピックについて扱います。 前編 メソッド定義のパラメータの解説と、パラメータの正しい順序 後編 メソッドが呼び出されたときに引数がパラメータにどのように代入されるか procとブロックの関連 lambdaとprocの違い 2種類のブロック{ … }とdo … end?の違い 用語「パラメータ」「引数」について 本記事では混乱を避けるため、元記事に基いてパラメータと引数という用語を以下のように使い分けます。 パラメータ(parameter) メソッド定義側で書くものを指す(厳密には「メソッドパラメータ」なのでブロック内のパラメータは含めない) 引数(argument) メソッド呼び出し側で渡すものを指す 各パラメータの種類 元記事では、Rubyのメソッド定義で使えるパラメータを以下の8つに分類しています。 種別 例 必須 a オプション b = 2 配列分解 (c, *d) splat *args post-required f キーワード g:, h: 7 ダブルsplat **kwargs ブロック &blk 配列分解(array decomposition)とpost-requiredは、元記事著者独自の呼び方のようです。 上のパラメータをすべて使った例は以下のようになります。 def foo a, b = 2, *c, d, e:, f: 7, **g, &blk; end パラメータの説明 注意: 元記事で使われているパラメータの種類は、パラメータを修飾する記号の書式だけでは決まりません。元記事におけるパラメータの種類は、「パラメータを修飾する記号」、「パラメータが置かれる位置(順序)」、「パラメータにどんな引数が渡されるか」を総合したものです。 たとえば「記号が何もついていないから必須パラメータ」とは限らず、パラメータの配置に応じてpost-requiredパラメータと呼んでいます。 3.の配列分解はパラメータの書式ではなくパラメータの動作と理解するのがよいでしょう。 1. 必須 必須パラメータは、呼び出し側で引数を与えないとエラーになるパラメータです。つまりこの「必須」は「呼び出し側で引数を省略できない」という意味になります。もっとも普通のパラメータと言ってよいでしょう。 以下は、必須パラメータに引数を渡さなかった場合のエラー表示です。 def foo(a) # aが必須パラメータ(普通のパラメータ) puts “a: #{a}” end foo #=> エラー 2. オプション パラメータにデフォルト値を与えたものはオプションのパラメータになります。オプションなので、引数を渡さない場合はデフォルト値が使われ、エラーになりません。 以下は、オプションパラメータに引数を渡さなかった場合の結果です。 def foo(a = 1) # a = 1がオプションパラメータ(デフォルト値を持つ) puts “a: #{a}” end foo #=> a: 1 特に、opts = {}のような形式のオプションパラメータにすると、key-valueペアをいくつでもまとめて受けることができます。key-valueペアがひとつもない場合でもエラーになりません。 def foo(a, b, opts = {}) # opt = {}でkey-valueペアを受けられる puts “a: #{a}” puts “b: #{b}” puts “opts: #{opts}” end foo(“bar”, “baz”, { hoge: 1, huga: 2, hoga: 3 }) #=> a: bar #=> b: baz #=> opts: {:hoge=>1, :huga=>2, :hoga=>3} opts = {}形式のオプションパラメータの注意点については以下もご覧ください。 参考: Railsフレームワークで多用される「options = {} 」引数は軽々しく真似しない方がいいという話 3. 配列分解 配列分解は、入れ子になった配列をリテラルで(=変数に入れずに)渡された場合に配列を部分に切り分けて受け取る、特殊な動作です。 分解のパターンは、パラメータ側のsplat(後述)の配置や丸かっこ( )によって複雑に変化します。引数に[1, … Continue reading Rubyのパラメータと引数の対応付けを理解する(前編)