Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

Array dereferencing(配列のデリファレンス)がphp-trunkに来た

おお。。。


I was writing about new features in the upcoming PHP version (5.4, 6.0?) before. Today's topic reads like this in the NEWS file:

- Added array dereferencing support. (Felipe)

デリファレンスとは、参照の指す値を取り出すことで、Perlではお馴染みと思います。
たとえば、関数の戻り値が配列の場合に

<?php
// func()は配列を返す関数
$val = func()[2];

と書けるようになる、ということです。で、どうやらphp-trunkにcommitされた模様。
ということで、早速試してみました。

使用したPHP

201008030430付けのsnapshotです。

$ php -v
PHP 5.3.99-dev (cli) (built: Aug  3 2010 14:22:47)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2010 Zend Technologies
$ 

動作確認

動作確認に使用したコードは、Features in PHP trunk: Array dereferencing - Johannes Schlüterに掲載されているものです。

$ php -a
Interactive shell

php > function foo() {
php {     return array(1, 2, 3);
php { }
php > echo foo()[2]; // prints 3
3
php > exit
$

おお。。。ちょっと見慣れないので気持ち悪いですが、確かに意図した動作です。
で、もっと気持ち悪い例w

$ php -a
Interactive shell

php > $data = array('me', 'myself', 'you');
php > function &get_data() {
php {     return $GLOBALS['data'];
php { }
php > get_data()[2] = 'I'; // $data will now contain 'me', 'myself' and 'I'
php > // $dataの値を確認
php > var_dump($data);
array(3) {
  [0]=>
  string(2) "me"
  [1]=>
  string(6) "myself"
  [2]=>
  string(1) "I"
}
php >
php > exit
$

うわ。。。まあ、動作としては分からなくもないですが、これは書きたくない。。。
当然ですが、連想配列でも動作します。まあ、PHPなので、配列もハッシュも(ry

$ php -a
Interactive shell

php > function bar() {
php {     return array('a' => 1, 'b' => 2, 'c' => 3);
php { }
php > echo bar()['b'];
2
php >

存在しない要素を参照した場合

error_reportingはE_ALL|E_STRICTです。

$ php -a
Interactive shell

php > function foo() {
php {     return array(1, 2, 3);
php { }
php > echo foo()[100];
PHP Notice:  Undefined offset: 100 in php shell code on line 1

Notice: Undefined offset: 100 in php shell code on line 1
php >

まあ、そりゃそうだ。。。ちなみに、error_reportingが(E_ALL|E_STRICT)&~E_NOTICEとかだと、nullとして扱われます。これも通常の配列とかと同じですね。

まとめ

デリファレンスが使えると言っても、要素が存在しなければNoticeが発生します。なので、配列を返す関数側で要素が必ず存在することを保証しないと、面倒くさい事になりそうな感じもしなくもないです。