Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Perlにおけるクラスの実装パターン.pdf

Avatar for ybrliiu ybrliiu
November 22, 2018

 Perlにおけるクラスの実装パターン.pdf

Avatar for ybrliiu

ybrliiu

November 22, 2018
Tweet

More Decks by ybrliiu

Other Decks in Technology

Transcript

  1. デメリット 比較的メモリ使用量が多い カプセル化が不十分 メソッドを介さずとも容易にインスタンスの状態を変更 することができる 自由に値を追加 / 削除 / 変更できる構造体をプログラ

    ムの中で引きづり回せると考えると、厳しい物がある my $point = Point->new(-3, 5); $point->{x} = 100; # accessorを介さなくてもインスタンス変数を操作できてしまう say $point->x; # -> 100 $point->{name} = 'Anonymous'; # こんなこともできてしまうわけです 7 / 23
  2. サブルーチンベースのクラス サブルーチンリファレンスにパッケージ名を紐付かせる サブルーチンリファレンスを実行することでインスタンス変数 を取得する 昔のjsにもこういうのがありましたね package Point; sub new {

    my ($class, $x, $y) = @_; my $fields = +{ X => $x, Y => $y }; bless sub { $fields->{shift(@_)} }, $class; } sub x { my $self = shift; $self->('X'); # サブルーチンリファレンスを実行してインスタンス変数として扱えるものを取り出 } 12 / 23
  3. スカラベースのクラス スカラリファレンスにパッケージ名を紐付かせる インスタンス変数は紐付けたスカラリファレンスの実体のみ スカラ値をラップするだけのようなモジュールや、XSモジュー ルなどで使われていたりする boolean, Furl, URI etc... package

    PositiveInt; sub new { my ($class, $num) = @_; die 'PositiveInt must be larger than 0.' if $num < 0; bless \$num, $class; } sub num { my $self = shift; $$self; # デリファレンスすることでインスタンス変数として使える } 15 / 23
  4. 実装 package Point; my (%x_fields, %y_fields); sub new { my

    ($class, $x, $y) = @_; my $ref = \(my $anon) + 0; $x_fields{$ref} = $x; $y_fields{$ref} = $y; bless $ref, $class; } sub x { my $self = shift; $x_fields{$$self + 0}; # インスタンス変数 } sub DESTROY { my $self = shift; my $ref = $$self + 0; delete $x_fields{$ref}; delete $y_fields{$ref}; } 19 / 23