Overview
通常、メソッドの引き数は呼び出す側が指定するか、メソッドシグネチャーでデフォルト値を指定します。どちらの指定も無いときは通常エラーになりますが、このような場合に引き数を用意するる機構が"Signal Parameter"です。
Normally, an argument is provided by caller or method signature's default value. None of argument provided cause 'Warning: Missing argument' error. "Signal Parameter" function provides argument in this case.
引き数の用意の責任を、メソッド自身、メソッドの利用者から分離してボイラプレートコードの削減やテスタビリティの向上に役立てます。
We expected to reduce boiler plate code and increase testability by removing the responsibility for argument provide from the caller or the method itself.
Example
例)$now引き数を必要とするページリソース
class Param extends Page
{
public function onGet($now)
{
$this->body['now'] = $now;
return $this;
}
}
引き数を用意するパラメータープロバイダーを定義します。
Parameter Provider
現在時刻を用意するパラメータープロバイダー
namespace Sandbox\Params;
use BEAR\Resource\ParamProviderInterface;
use BEAR\Resource\Param;
class CurrentTime implements ParamProviderInterface
{
public function __invoke(Param $param)
{
$time = date("Y-m-d H:i:s", time());
return $param->inject($time);
}
}
ParamProviderInterfaceを実装したメソッドでは引き数に様々なアクセスができるParam型変数を受け取ります。プロバイダーからはメソッドや対象オブジェクトにアクセスできるので、他の引き数やメソッドにつけられたアノテーションによって引き数の準備を変える事ができます。ex) $endOfDayは他の引き数$monthを見て28/30/31を選択して注入
$args = $param->getArg(); // メソッドの引き数を全てを取得します
$paramReflection = $param->getParameter(); // パラメーターのリフレクションを取得します
$param->getMethodInvocation()->getMethod() // メソッドのリフレクションを取得します
$param->getMethodInvocation()->getThis(); // メソッドのオブジェクトを取得します。
引き数が 用意できるとき は$param->inject()
で注入します。出来ない時はそのままreturnします。
Binding
引き数名と引き数プロバイダーを登録することで利用可能になります。1つの変数に対して登録が複数できます。引き数プロバイダーは変数が用意されるまで順番にコールされます。
We need to bind 'variable name' and 'variable provider' to use this 'Signal Parameter' functionality. Parameter provider will be called till argument is provided.
$signalParam->attachParamProvider('now', new CurrentTime);
Idea
Pull Architecture
For example, "Calendar" helper in view template needs $year and $month to render calendar. 'Signal Parameter' enables every controller does no need to assign $year and $month in every controller which has calendar view.
loginId
Login ID is provider by "SessionLoginIdProvider" or "CookieIdProvider", but "TestLoginIdProvider" will provide in "test" mode. Caller and method changed nothing.
Overide
(not implemented yet) Regardless how do you call, Specified arguments by name or caller are overridden. Main use is for the test.
Actual code
$this->install(new SignalParamModule($this, $this->params));
in https://github.com/koriym/BEAR.Package/blob/e08cf8ebf39f539b605daab03315d4222f57b810/apps/Sandbox/Module/App/AppModule.php
RFC