こんにちは。
LocoPartnersでReluxのサーバーサイドを担当している山口です。
この記事は「Relux Advent Calendar 2018」10日目の記事です。
本日はphp rfcで議論中になっているものから、個人的に取り込まれると楽しそうだなと感じている Immutable classes and properties という提案について紹介を行っていきたいと思います。
紹介と言っても元ページの内容を書いてるだけですが、php rfc自体に今まで興味がなかった人が興味を示すキッカケとなってくれると幸いです。また、議論中のものなので 最終的にどういった形で取り込まれるのか や そもそも取り込まれるのか は誰にも解りません。
Immutable classes and properties
php自体にImmutableなClassとPropertyを設定可能な機能を導入してみませんかという提案です。現時点(2018/12/10)で提案されている例は下記になります。
Immutable Class
immutable class Email {
public $email;
public function __construct ($email) {
$this->email = $email;
}
}
$email = new Email("foo@php.net");
$email->email = "bar@php.net" // Call will result in Fatal Error
immutable class Foo{}
class Bar extends Foo{} // Will result in Fatal Error
Immutable Classを用いるとClassのPropertyはImmutableとして暗黙的に設定されます。これによりgetterなどで取得する必要のあるPropertyを安心して public
として ImmutableClass->attribute
などで値を取得することが出来そうですね。
もう、getEmail()
といったgetter用のfunctionを用意したりする手間や、どこかで値が変わることに心配する必要も無くなるのでしょうね、
また、継承を行う際は継承を行う子クラスもImmutable Classである必要があることや、参照を利用した値の変更も不可となっています。
Immutable Properties
class User {
private $id;
public immutable $email;
public function __construct ($id, $email) {
$this->id = $id;
$this->email = $email;
}
}
immutable class Email{}
class User {
public immutable $email;
public function __construct (Email $email) {
$this->email = $email;
}
}
Classの一部のPropertyにImmutable Propertyを用いることも可能です。
しかし、下記のように幾つかの制約があります。
- Immutable Propertyにオブジェクトが代入される場合、代入するObjectもImmutableである必要があること。
- Immutable PropertyにResource(ファイル等)であるものは割り当てることはできないこと。
- Immutable Propertyに配列は割り当てることができないこと。
- 子クラスで親クラスのImmutable Propertyをoverrideする場合は子クラスでもImmutable Propertyとして宣言する必要があること
比較
immutable class Email {
public $email;
public function __construct ($email) {
// validation
$this->email = $email;
}
}
$email1 = new Email("foo@php.net");
$email2 = new Email("foo@php.net");
var_dump($email1 === $email2); // bool(true)
ImmutableなObjectの場合には通常のObjectとは異なり、型とその中に設定されているプロパティの値が同じである場合は同一としてみなされます。
MoneyPatternの実装例
元ページには、この他にMoneyPatternと呼ばれるものを用いてのImmutable Classを用いた場合と用いない場合での具体例な実装例が記載されています。興味がある方はそちらも是非ご覧になってください。
さいごに
現時点でも、開発者側で独自に実装をすることでImmutableなClassやPropertyを実装することは可能ですが、統一された方法が言語として用意されimmutable
と付与されていればImmutableであることを保障してくれるのが嬉しいですね。
それでは、明日も引き続きRelux Advent Calendar 2018をお楽しみください。