Scribble at 2022-05-20 17:58:41 Last modified: 2022-05-21 12:48:48

プログラミングでは、よく関数や演算の「副作用」という言い方を使う。これは、或る関数や無名関数(クロージャ)や演算を加えることによって、元の変数や入力値がもっていた値とか値の配列が変わってしまうことを指している。一例として、PHP の shuffle() 関数を取り上げよう。これは、入力された配列の要素がもともと持っていたインデックスを消去して、新しくメルセンヌ・ツイスター乱数で振りなおしたランダムな順番でインデックスを割り当てなおす。よって、はじめに $ar = array( 3, 2, 5 ) があったら、各要素には $ar[0] = 3, $ar[1] = 2, $ar[2] = 5 というインデックスが割り当てられているけれど、shuffle( $ar ) によって、その結果を print_r() で出力すると、$ar[0] = 5, $ar[1] = 2, $ar[2] = 3 となったり、$ar[0] = 2, $ar[1] = 5, $ar[2] = 3 となったりする。そして、元の $ar で各要素がどの順番に並んでいたのかは保存されない。このような効果を「副作用」と呼んでいる。

元の値や値の配列という特性を、shuffle() のような処理をした後でも維持できるように保存したければ、副作用をもつ関数や演算を加える前に、オリジナルの配列や変数を暫定的に作成した別の配列や変数に退避させておくことがある。$tmp = $ar のようにしておき、shuffle( $ar ) で $ar の要素の並びが変わってしまった後でも $tmp でオリジナルの並びを扱える。関数によっては、副作用がなくて元の配列に何も変更を加えないものもあるが、その場合は加えた変更を反映させる新しい配列を作って格納してやらなければ意味がない。よって、副作用のある shuffle() については、

shuffle( $ar );

だけで $ar に対して有効だが、たとえば副作用のない array_flip() については、

$ar2 = array_flip( $ar );

のように処理の戻り値を受ける別の配列を用意しないといけないわけである。

そして、副作用のある関数を使うときに注意したいのは、副作用がある関数を、そういう新しく作った配列に格納するという操作は意図しない結果を招くということだ。もし shuffle() を実行して要素の順番が変わった新しい配列を単に使いたいなら、副作用によってオリジナルの配列が〈新しくそうなっている〉のだから、単に $ar を使えばいいだけなのだ。それを、

$ar3 = shuffle( $ar );

などとやって $ar3 に shuffle() で順番が変わった配列を取り込めると勘違いしてしまうことは避けなくてはいけない(shuffle() の戻り値は、要素の順番が変わっている新しい配列〈ではなくて〉、その処理が成功したかどうかのブール値であるから、$ar3 の値は TRUE である)。

  1. もっと新しいノート <<
  2. >> もっと古いノート

冒頭に戻る


※ 以下の SNS 共有ボタンは JavaScript を使っておらず、ボタンを押すまでは SNS サイトと全く通信しません。

Twitter Facebook