【问题标题】:How to check some value on every call to object's methods?如何在每次调用对象方法时检查一些值?
【发布时间】:2012-08-10 14:21:45
【问题描述】:

我想检查对我的对象方法的每次调用一些值(在这种情况下:令牌的年龄)。是否可以一次将其设置为所有方法?就像在构造函数中一样?我有这么简单的构造函数:

sub new {
    my $class = shift;
    my %args = @_;
    my $self  = {};

    $self->{key} = $args{key};
    bless($self, $class);

    ($self->{token}, $self->{token_start}) = $self->_get_authorized_token(); 
    return $self;
}

还有一堆方法,取决于代币的年龄,像这样:

sub add_item {
    my $self = shift;
    my %args = @_;
    ...
}

我想避免在每种方法中都包含年龄检查,所以我寻找更通用的方法来实现它。有吗?

【问题讨论】:

    标签: perl oop methods


    【解决方案1】:

    我能想到的就是隐藏你所有的“真实”方法——或者以带有前下划线的经典方式,或者在子例程的散列中——并使用AUTOLOAD正确地引导调用。

    下面的例子说明了这个想法

    模块 MyClass.pm

    package MyClass;
    
    use strict;
    use warnings;
    
    sub new {
      bless {}, __PACKAGE__;
    }
    
    sub _method1 {
      print "In method1\n";
    }
    
    sub _method2 {
      print "In method2\n";
    }
    
    sub AUTOLOAD {
    
      our $AUTOLOAD;
    
      my ($class, $method) = $AUTOLOAD =~ /(.+)::(.+)/;
      return if $method eq 'DESTROY';
    
      my $newmethod = "${class}::_$method";
      unless (exists &$newmethod) {
        die qq(Can't locate object method "$method" via package "$class");
      }
    
      print "Preprocessing...\n";
      goto &$newmethod 
    }
    
    1;
    

    程序

    use strict;
    use warnings;
    
    use MyClass;
    
    my $thing = MyClass->new;
    
    $thing->method1;
    $thing->method2;
    $thing->method3;
    

    输出

    Preprocessing...
    In method1
    Preprocessing...
    In method2
    Can't locate object method "method3" via package "MyClass" at MyClass.pm line 23.
    

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 感谢您的正确路径 - 方法修饰符!我什至不知道要搜索什么。
      【解决方案3】:

      老实说,如果您在 Perl 中进行 OO,并且想要在没有样板的情况下处理属性、方法修饰符和延迟资源加载等问题,那么值得投资学习 Moose。举例来说,这是使用 Moose 编写所需内容的一种方式:

      use Moose;
      has key => (isa => 'Str', is => 'ro');
      has token => (isa => 'HashRef', is => 'ro', lazy_build => 1);
      
      before [qw(add_item method2 method3)] => sub {
          my $self = shift;
          if (do something with $self->token) {
               # return, die, etc.
          }
      };
      
      sub _build_token {
          my $self = shift;
          my $key = $self->key;
          return { token => 'foo', token_start => time };
      }
      

      这些可能会有所帮助:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-01
        • 1970-01-01
        相关资源
        最近更新 更多