そこにあるRubyの本はこれを詳細に説明しています。しかし、それがなくても、その論理に慣れます。まともなコーダーは、次のように、強制的な順序付きパラメーターが最初になるように関数を定義します。
def foo( a, b, c=0, d=0 )
# ...
end
簡単に言えば、最初の 2 つの引数はa
, に移動し、b
最大 2 つのオプションの引数c
は ,d
にこの順序で移動します。しかし、あなたには常識を超えた自由が与えられています。
def foo( a=0, b )
# ...
end
引数を 1 つ指定すると、 に移動しb
ます。引数を 2 つ指定すると、 、 、 の順に割り当てられa
ますb
。これは、ユーザーからより多くのことを学ぶ必要があるため、まともではありません。あなた自身がユーザーなら、あなたは自分自身に卑猥ですが、それでも構文上のあいまいさはまったくありません。これを見てください:
def foo( a=0, b, c=0 )
# ...
end
に電話した場合、、、、または、、というfoo( 1, 2 )
意味でしたか? おそらく最初の可能性が高いですが、コーディングのルールは、ユーザーの意図を推測しないことです。そのため、Ruby チームはこの構文を甘やかさないことに決めたのでしょう。以下を定義することで、それを実現できます。a = 1
b = 2
c = 0
a = 0
b = 1
c = 2
def foo( *args )
a, b, c = case args.size
when 1 then [0, args[0], 0]
when 2 then [*args, 0]
when 3 then args
else fail ArgumentError; "#{args.size} arguments for 1..3!" end
# ...
end
これにより、実際には完全な自由が与えられますが、Ruby は優れた実践へと導きます。つまり、良いコードを悪いコードよりも見栄えよくすることです。*splat で引数を収集する場合も同様です。まともなケースは明白です:
def foo( a, b=0, *c )
# ...
end
ただし、次の場合:
def foo( a=0, b, *c )
# ...
end
を呼び出したとき、、、および、または、、およびのfoo( 1, 2, 3 )
ことでしたか? したがって、この 2 番目のケースも推奨されませんが、実現可能です。a = 1
b = 2
c = [3]
a = 0
b = 1
c = [2, 3]
def foo( *c )
a, b = case c.size
when 0 then fail ArgumentError, "Too few arguments!"
when 1 then [0, c.shift]
else [c.shift, c.shift] end
# ...
end
多くの引数、特に多くの順序付けされた引数を持つ関数を書くことは、悪い習慣です。バイナリ メソッドは 3 項よりも優れており、単項はバイナリよりも優れており、最後に、ヌルは単項よりも優れているという古いことわざがあります。メソッドに多くの引数が必要な場合は、 object に置き換えてリファクタリングする必要があります。これはあなたの質問に答えていますか?