PHP
JavaScript

PHPでも過激な短絡評価がしたい!

More than 1 year has passed since last update.

絶対どこかにあるだろうけど言語化の不自由と情報の海に埋もれてうまく検索できないシリーズ

結果的にボツだこれ。

要件

jsなど幾つかの言語で可能な、論理和の返り値が最後の評価値になるやつがしたい。
単純に短絡評価で伝わるか。

短絡評価 - Wikipedia

('' || 'test') // 'test'
('test' || '') // 'test'
(false || '') // ''

変数が1かギリギリ2個だけなら三項演算子でなんとかできるけれど…っと。

選択的代入とも言うらしい?

コード

<?php

function js_sce($callback = null, ...$args) {
    if(!is_callable($callback)) {
        $callback = function ($arg) {
            return !!$arg; // $arg == true
        };
    }

    foreach ($args as $arg) {
        if($callback($arg)) {
            return $arg;
        }
    }
    // ここ例外かreturn false null 悩むけどjsが最後の値なので。
    return array_pop($args);
}

var_dump(js_sce(null, 'test', 'example', 'year!')); // string(4) "test"
var_dump(js_sce(null, '','test', 'example', 'year!')); // string(4) "test"
var_dump(js_sce(null, null, 'example', 'year!')); // string(7) "example"
var_dump(js_sce(function($arg) {
    return $arg === 'year!';
}, null, 'example', 'year!')); // string(5) "year!"
var_dump(js_sce(null, null, '', false)); // bool(false)
var_dump(js_sce()); // NULL

(これarray_filterからのarray_shiftでほぼ似そう?)

できれば

function js_sce( ...$args, $callback = null)

がいいけれど、可変長引数なら無理だよね。(Fatal error: Only the last parameter can be variadic)
呼び出す側が...使えばいいのかな?

By the way

個人的なJavaScriptによる短絡評価の最頻パターンは以下だと思います。

hoge.huga = hoge.huga || 'huni'

JSONで受け取ったデータの処理などに使う。

次点でES2015未満の関数のデフォルト引数か、複雑なデフォルト値の設定か。

とかく、hogeがちゃんとオブジェクトならhugaは未定義でも構わない。(左辺の評価時にエラーにならない)

が、PHPでは存在しないプロパティを読むと、Noticeエラーになる。

<?php

error_reporting(-1);

$a = new Stdclass();

echo $a->tes; // Notice: Undefined property: stdClass::$tes 

仮に||の短絡評価時はセーフになったとしても、関数の引数になればもうそこでNGだろう。
だから、完成度が高い模倣ではないし、おもったより使えない気がする。

過去に何度か作ろうとして毎度ここで諦めてたような記憶もかすかにある。

参考