Цепочка функций с разными возвращаемыми значениями? - PullRequest
3 голосов
/ 28 марта 2012

Можно ли заставить метод возвращать разные значения в зависимости от контекста (как используется возвращаемое значение)?Например, может ли метод вернуть $this, когда он затем используется с оператором стрелки для вызова другого метода (т. Е. Вызовы метода цепочки), но вернуть скаляр, если возвращаемое значение не используется таким образом?Случай 1:

$result = $test->doSomething1(); // returns 4
// $result returns 4

Случай 2:

$result = $test->doSomething1()->doSomething2();
// doSomething1() returns $this
// doSomething2() returns 8

Есть ли способ выполнить такое поведение?

Ответы [ 3 ]

4 голосов
/ 28 марта 2012

Если я правильно понимаю вопрос, вы хотите, чтобы метод (doSomething1) возвращал значение, основываясь на том, как выглядит остальная часть цепочки вызовов. К сожалению, нет абсолютно никакого способа сделать это.

Общие парадигмы программирования, общие для "всех" языков (как методы, операторы и такие работают в контексте грамматики), требуют, чтобы результат выражения $this->doSomething1() был обработан до результата возможного вызова ->doSomething2() на это можно посчитать. Статически типизированные и динамически типизированные языки делают это по-разному, но общий фактор заключается в том, что выражение $this->doSomething1() должно рассматриваться независимо от того, что следует или не следует.

В двух словах: $this->doSomething1() должен возвращать определенный тип значения в обоих случаях. И в PHP нет способа иметь тип значения, который может вести себя как число в одном контексте и как объект с методами для вызова в другом.

3 голосов
/ 28 марта 2012

Нет, невозможно, чтобы функция возвращала разные значения в зависимости от того, вызывается ли другая функция для возвращаемого значения или нет. Вы можете эмулировать это с помощью toString () (где применимо преобразование в строку, или другой функцией, которую вы вызываете в конце каждой цепочки, чтобы получить значение вместо объекта:

$test = new foo();
echo $test->doSomething1(); // Outputs 1

$test = new foo();
echo $test->doSomething1()->doSomething2(); // Outputs 3

$test = new foo();
$result = $test->doSomething1()->done(); // $result === 1

$test = new foo();
$result = $test->doSomething1()->doSomething2()->done(); // $result === 3

class foo {

    private $val;

    function __construct($val = 0){
        $this->val = $val;
    }

    function doSomething1(){
        $this->val += 1;
        return $this;
    }

    function doSomething2(){
        $this->val += 2;
        return $this;
    }

    function done(){
        return $this->val;
    }

    function __toString(){
        return (string)$this->val;
    }

}

Пример кодовой панели

0 голосов
/ 28 марта 2012

В этом ответе предлагается создать внутренний стек вызовов для класса, чтобы вы могли отслеживать, где находитесь в цепочке методов.Это может быть использовано для возврата $this или чего-то еще, в зависимости от контекста.

...