関数の定義
関数はdef...end
で定義する。その関数が呼び出されるより前に定義されていなければならない。
1 2 3 4 5 6 7 |
def f(str) puts str end f("test") # test |
関数の戻り値
return
文で関数の戻り値を指定できる。
1 2 3 4 5 6 7 |
def g(n) return n * 2 end puts g(3) # 6 |
再帰呼び出し
再帰呼び出しにも対応。
1 2 3 4 5 6 7 8 |
def frac(n) return 1 if n == 0 n * frac(n - 1) end puts frac(5) # 120 |
デフォルト引数
あまりよくない方法
引数のデフォルト値をPythonと同じように指定できる。
1 2 3 4 5 6 7 8 9 10 11 |
def func_default_arg(x=1, y=2) p x + y end func_default_arg() func_default_arg(10) func_default_arg(10, 20) # 3 # 12 # 30 |
実行時に指定した引数は、デフォルト引数があっても引数の順に入れ替えられる。以下の例の8行目で2つの仮引数に対して1つの実引数を与えているが、その値は1つ目の引数に使われている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def func_default_arg(x=1, y="score") print y, "+", x, "\n" end func_default_arg() func_default_arg(10) func_default_arg(10, "point") func_default_arg("point") # score+1 # score+10 # point+10 # score+point # -> 指定した引数は一つ目のパラメーターに与えられる |
以下の6行目で仮引数名y
とz
を指定して実引数を渡しているが、それらの値はx
とy
に与えられてしまう。これは以下の流れによるものと考えられる。
- 実行時に与えた引数は、デフォルト引数の有無にかかわらず先頭から順番に与えられる
- 実行時に指定した引数
'y=7'
、'z=8'
はそれぞれ式として評価され、その値が7、8となる - この2つの値が仮引数の先頭から与えられ
x=7
とy=8
となり、z
はデフォルト値の3が使われる
1 2 3 4 5 6 7 8 9 |
def default_arg(x=1, y=2, z=3) print x, y, z, "\n" end default_arg() default_arg(y=7, z=8) # 123 # 783 |
妥当な方法~キーワード引数
仮引数名を指定して実引数を渡す場合は、以下のようにキーワード引数を使うとよい。ただしキーワード引数で仮引数を指定した場合、実行時には指定を省略してデフォルト値を使うか、仮引数を明示して引数を与える必要がある。
1 2 3 4 5 6 7 8 9 10 11 |
def default_arg(x: 1, y: 2, z: 3) print x, y, z, "\n" end default_arg() default_arg(y: 7, z: 8) # default_arg(6, 7, 8) # -> wrong number of arguments (given 3, expected 0) (ArgumentError) # 123 # 178 |
デフォルト値を指定しない仮引数と、デフォルト値を指定したキーワード引数は混在して利用可能。
1 2 3 4 5 6 7 8 9 |
def root(x, n: 2) return x**(1.0/n) end puts root(2) puts root(2, n: 3) # 1.4142135623730951 # 1.2599210498948732 |
可変長引数
引数の頭に'*'
をつけると配列とみなされ、複数の引数を渡せる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ef func_var(*args) p args end func_var() func_var(1) func_var(1, 2) func_var(1, 2, 3) # [] # [1] # [1, 2] # [1, 2, 3] |
配列の要素を使った処理の例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def sum(*nums) result = 0 for n in nums do result += n end p result end sum() sum(1) sum(1, 2) sum(1, 2, 3) # 0 # 1 # 3 # 6 |
通常の引数と可変長の引数が混在する場合、少なくとも通常の引数に対応する引数を渡す必要がある。
可変長引数の内容は空でもよく、まず通常の引数が埋められた後、その数を超える引数が可変長引数となる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def func_var2(x, y, *args, z) p x p y p args p z end # func_var2() -> error # func_var2(1) -> error # func_var2(1, 2) -> error func_var2(1, 2, 3) func_var2(1, 2, 3, 4) func_var2(1, 2, 3, 4, 5) # 1 2 [] 3 # 1 2 [3] 4 # 1 2 [3, 4] 5 |