メソッド引数¶
これは、メソッドパラメータと呼び出し引数の正式な仕様です。
メソッド定義の構成要素¶
メソッド定義は以下で構成されます。
- 必須およびオプションの位置パラメータ
- 名前が空でもよいオプションのスプラットパラメータ
- 必須およびオプションの名前付きパラメータ
- オプションのダブルスプラットパラメータ
例:
def foo(
# These are positional parameters:
x, y, z = 1,
# This is the splat parameter:
*args,
# These are the named parameters:
a, b, c = 2,
# This is the double splat parameter:
**options
)
end
これらのそれぞれはオプションであるため、メソッドはダブルスプラット、スプラット、名前付きパラメータ、位置パラメータなしで実行できます。
メソッド呼び出しの構成要素¶
メソッド呼び出しにもいくつかの部分があります。
foo(
# These are positional arguments
1, 2,
# These are named arguments
a: 1, b: 2
)
さらに、呼び出し引数には、スプラット(*
)またはダブルスプラット(**
)を含めることができます。スプラットはタプルを位置引数に展開し、ダブルスプラットはNamedTupleを名前付き引数に展開します。複数の引数スプラットとダブルスプラットが許可されています。
呼び出し引数がメソッドパラメータにどのように対応付けられるか¶
メソッドを呼び出す場合、呼び出し引数をメソッドパラメータに一致させるアルゴリズムは次のとおりです。
- まず、位置呼び出し引数は位置メソッドパラメータと一致させます。これらの数は、デフォルト値を持たない位置パラメータの数以上である必要があります。名前付きのスプラットパラメータがある場合(名前のない場合は以下で説明します)、より多くの位置引数が許可され、それらはタプルとして取得されます。位置引数は、スプラットパラメータを超えて一致することはありません。
- 次に、名前付き引数は、名前で、メソッド内の任意のパラメータと一致させます(スプラットパラメータの前後どちらでもかまいません)。パラメータが位置引数によって既に満たされている場合はエラーです。
- 余分な名前付き引数は、存在する場合はNamedTupleとしてダブルスプラットメソッドパラメータに配置され、そうでない場合はエラーになります。
スプラットパラメータに名前がない場合、それ以上位置引数を渡すことができず、後続のパラメータは名前付き引数として渡す必要があります。例:
# Only one positional argument allowed, y must be passed as a named argument
def foo(x, *, y)
end
foo 1 # Error, missing argument: y
foo 1, 2 # Error: wrong number of arguments (given 2, expected 1)
foo 1, y: 10 # OK
しかし、スプラットパラメータに名前が付いている場合でも、それに続くパラメータは名前付き引数として渡す必要があります。
# One or more positional argument allowed, y must be passed as a named argument
def foo(x, *args, y)
end
foo 1 # Error, missing argument: y
foo 1, 2 # Error: missing argument; y
foo 1, 2, 3 # Error: missing argument: y
foo 1, y: 10 # OK
foo 1, 2, 3, y: 4 # OK
メソッドに名前付き引数のみを受け取らせる(そしてそれらをリストする)ことも可能です(星を先頭に配置します)。
# A method with two required named parameters: x and y
def foo(*, x, y)
end
foo # Error: missing arguments: x, y
foo x: 1 # Error: missing argument: y
foo x: 1, y: 2 # OK
星印の後にあるパラメータにもデフォルト値を設定できます。つまり、名前付き引数として渡す必要がありますが、必須ではありません(つまり、オプションの名前付きパラメータです)。
# x is a required named parameter, y is an optional named parameter
def foo(*, x, y = 2)
end
foo # Error: missing argument: x
foo x: 1 # OK, y is 2
foo x: 1, y: 3 # OK, y is 3
スプラットパラメータの後にある(デフォルト値のない)パラメータは名前で渡す必要があるため、必要な名前付きパラメータが異なる2つのメソッドはオーバーロードされます。
def foo(*, x)
puts "Passed with x: #{x}"
end
def foo(*, y)
puts "Passed with y: #{y}"
end
foo x: 1 # => Passed with x: 1
foo y: 2 # => Passed with y: 2
位置パラメータは常に名前で一致させることができます。
def foo(x, *, y)
end
foo 1, y: 2 # OK
foo y: 2, x: 3 # OK
外部名¶
メソッドパラメータには外部名を指定できます。外部名は、引数を名前付き引数として渡す際に使用される名前であり、内部名は、メソッド定義内でパラメータを参照するために使用される名前です。
def foo(external_name internal_name)
# here we use internal_name
end
foo external_name: 1
これは2つのユースケースをカバーしています。
最初のユースケースは、キーワードを名前付きパラメータとして使用することです。
def plan(begin begin_time, end end_time)
puts "Planning between #{begin_time} and #{end_time}"
end
plan begin: Time.local, end: 2.days.from_now
2番目のユースケースは、メソッド本体内でメソッドパラメータの可読性を高めることです。
def increment(value, by)
# OK, but reads odd
value + by
end
def increment(value, by amount)
# Better
value + amount
end