忍者ブログ

ぢみへんプログラミング日誌

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Rubyにおける多重代入について

Rubyの多重代入とは基本的にこういうものを指す。

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

COMMENT

NAME
TITLE
MAIL (非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS (コメント編集に必須です)
SECRET
管理人のみ閲覧できます
 
  

カレンダー

05 2020/06 07
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

フリーエリア

最新CM

バーコード

ブログ内検索

Copyright ©  -- ぢみへんプログラミング日誌 --  All Rights Reserved

Design by CriCri / Material by petit sozai emi / powered by NINJA TOOLS / 忍者ブログ / [PR]