Rubyにおける多重代入について
- 2012/10/24 (Wed) |
- ruby |
- CM(0) |
- Edit |
- ▲Top
Rubyの多重代入とは基本的にこういうものを指す。
このように * という記号を付けることで、代入式の右辺の配列を分解して左辺に渡したり、右辺の任意数の要素を配列としてまとめて左辺に代入できる。(こういう働きをするときの * をsplat演算子とも呼ぶこともあるそうだが、実際には本物の演算子ではないと「プログラミングRuby」には書いてある。)この性質を生かして、メソッドの定義で可変引数を実現可能だ。
見ての通り、可変引数は配列として引数に渡される。
ところが話はここで終わらない。多重代入による可変引数を使うことには意外な(ある意味便利な)副作用があるからだ。以下は上記コードのfuncメソッドを引数なしで実行した例である。
なんと! 引数がないから例外発生かと思いきや、空の配列として引数を受け取っているではないか。ということは多重代入引数は同時に空配列のデフォルト引数でもあるわけだ。
多重代入に関する注意点がもう一つ。単なる代入式での多重代入とメソッドの引数で扱う多重代入では挙動が異なっていることに注意しなければならない。
メソッドの引数ではなく、左辺に * をつけての単なる多重代入の場合、右辺要素が1つしかないときは、左辺の変数に配列が代入されるのではなく、単に右辺のオブジェクトがそのまま代入される。
しかしメソッド引数としての多重代入の動作では、呼び出し側で用意した引数が1個のみだとしても、メソッド側では必ず配列として扱われる。
この挙動の違いが将来なくなるかどうかは分からないが、現状では注意するべきだろう。
a, b = *[1, 2] # a = 1, b = 2
*c = 1, 2, 3 # c = [1, 2, 3]
このように * という記号を付けることで、代入式の右辺の配列を分解して左辺に渡したり、右辺の任意数の要素を配列としてまとめて左辺に代入できる。(こういう働きをするときの * をsplat演算子とも呼ぶこともあるそうだが、実際には本物の演算子ではないと「プログラミングRuby」には書いてある。)この性質を生かして、メソッドの定義で可変引数を実現可能だ。
irb(main):001:0> def func( *s )
irb(main):002:1> s
irb(main):003:1> end
=> nil
irb(main):005:0> func(1,2,3)
=> [1, 2, 3]
見ての通り、可変引数は配列として引数に渡される。
ところが話はここで終わらない。多重代入による可変引数を使うことには意外な(ある意味便利な)副作用があるからだ。以下は上記コードのfuncメソッドを引数なしで実行した例である。
irb(main):004:0> func
=> []
なんと! 引数がないから例外発生かと思いきや、空の配列として引数を受け取っているではないか。ということは多重代入引数は同時に空配列のデフォルト引数でもあるわけだ。
多重代入に関する注意点がもう一つ。単なる代入式での多重代入とメソッドの引数で扱う多重代入では挙動が異なっていることに注意しなければならない。
メソッドの引数ではなく、左辺に * をつけての単なる多重代入の場合、右辺要素が1つしかないときは、左辺の変数に配列が代入されるのではなく、単に右辺のオブジェクトがそのまま代入される。
irb(main):021:0> *a = 1
=> 1
irb(main):022:0> *a = 1, 2
=> [1, 2]
しかしメソッド引数としての多重代入の動作では、呼び出し側で用意した引数が1個のみだとしても、メソッド側では必ず配列として扱われる。
irb(main):001:0> def func( *s )
irb(main):002:1> s
irb(main):003:1> end
=> nil
irb(main):023:0> func
=> []
irb(main):024:0> func 1
=> [1]
irb(main):025:0> func 1, 2
=> [1, 2]
この挙動の違いが将来なくなるかどうかは分からないが、現状では注意するべきだろう。
PR
カレンダー
フリーエリア
最新CM
最新記事
(06/05)
(06/04)
(06/04)
(11/18)
(11/18)
ブログ内検索
最古記事
(09/15)
(09/20)
(09/27)
(09/27)
(10/11)
COMMENT