Help us understand the problem. What is going on with this article?

Immutable classes and propertiesについて

More than 1 year has passed since last update.

こんにちは。

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をお楽しみください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした