'."\n");?> フレームワーク (8) - サブクラスでのメソッドのオーバーライドを禁止する - 勤務先と無関係なことを書く日記

Home > C::M::App > | Perl > フレームワーク (8) - サブクラスでのメソッドのオーバーライドを禁止する

フレームワーク (8) - サブクラスでのメソッドのオーバーライドを禁止する

C::M::App は、CGI::Application と同様、自分のクラスから継承されることを想定している

package MyClass;
use basee 'CGI::Minimal::App';

1;

んだが、一部メソッドは子クラスでのオーバーライド前提だし、一部メソッドはオーバーライドされたくないし、ということで、思案。他の言語みたいに attribute :final とか用意されてると

sub cannot_override :final {
}

とかするだけだし、そういうことを行うモジュール Attribute::Final もあるんだが、外部モジュール使うほどでもないし、attribute で実装しなくてもよかろう

# 子クラスの時だけ実行
unless ( ref $self eq __PACKAGE__ ) {
  for my $method (@all_methods) {
    next if .... ; # 親クラスのメソッドだったら何もしない

    die 'You can NOT OVERRIDE method'
      if ( grep {$_ eq $method} @not_override_methods );
  }
}

まずは基本ということで、Class::Inspector 使ってみる

# Check methods that cannot override in Sub-Class
unless ( ref $self eq __PACKAGE__ ) {
  my @not_override_methods = qw(
                                new run
                                _tt_obj _setup_http_headers _lvalue_method
                               );
  for my $method ( @{Class::Inspector->methods(ref $self, 'expanded') || [[]]} ) {
    next if $method->[1] eq __PACKAGE__;
    die 'You can NOT OVERRIDE method ',__PACKAGE__,'::',$method->[2],' in ',$method->[1]
      if ( grep {$_ eq $method->[2]} @not_override_methods );
  }
}

続いて、Class::Inspector はコアモジュールではないので、使わない版

# Check methods that cannot override in Sub-Class
unless ( ref $self eq __PACKAGE__ ) {
  my @not_override_methods = qw(
                                new run
                                _tt_obj _setup_http_headers _lvalue_method
                               );
  {
     no strict 'refs';
     for my $method ( keys %{ref($self).'::'} ) {
       next unless defined &{ref($self).'::'.$method};
       die 'You can NOT OVERRIDE method ',__PACKAGE__,'::',$method,' in ',ref($self)
         if ( grep {$_ eq $method} @not_override_methods );
     }
  }
}

タイムリーなことに、「どう書く?org」で「メソッド名一覧の表示」がお題になっているので、良さげな回答がでてきたらマネさせてもらおう

で、この実装だとコンストラクタ生成後にチェックするので、use した時点でチェクする方法考えた方がいいのかなぁ、とちょっと思った。new のしょっぱなにやっとけば同じかな

Home > C::M::App > | Perl > フレームワーク (8) - サブクラスでのメソッドのオーバーライドを禁止する

Feeds

Return to page top