Perl Advent Calendar 2010-12-14

Class::XSAccessor

by Fayland Lam

创建所谓的 accessor 应该是件很普遍的事情,对于对象来说,大部分的属性都是 accessor. 因为这个功能的普遍性,CPAN 上大概有超过 20 个模块可以完成这个任务。其中最有名的应该是 Moose, Mouse 或者是 mst 刚开发的更轻量级的 Moo. 或许大家用过的有 Class::Accessor, Class::Accessor::Fast 或者 Class::MethodMaker. 今天要推荐的是目前来说最快速的 Class::XSAccessor.

Class::XSAccessor 最初是为了加速和简化 Padre 的代码而开发,用法与其他的 accessor 模块大同小异。

package MyClass;

use Class::XSAccessor
    replace     => 1,   # Replace existing methods (if any)
    constructor => 'new',
    getters     => {
      get_foo => 'foo', # 'foo' is the hash key to access
      get_bar => 'bar',
    },
    setters => {
      set_foo => 'foo',
      set_bar => 'bar',
    },
    accessors => [ 'foo', 'bar' ],
    predicates => {
      has_foo => 'foo',
      has_bar => 'bar',
    },
    lvalue_accessors => { zip_code => 'zip' };
    true  => [ 'is_token', 'is_whitespace' ],
    false => [ 'significant' ];

几个简单的解释是,

* constructor => 'new' 意味着你不用写无聊的 new 了。

* accessors => [] 是最常用的,因为大部分情况下 getter 和 setter 的名字会是一样的。

* lvalue 是个比较 fun 的功能。比如上面的设置可以有如下的测试代码

  my $address = MyClass->new(zip => 2);
  print $address->zip_code, "\n"; # prints 2
  $address->zip_code = 76135; # <--- This is it!
  print $address->zip_code, "\n"; # prints 76135

某些极端要求速度的人,会认为 bless 一个 hashref 给 class 是件很浪费的事情,他们说应该 bless 一个 arrayref 给 class 才是正确的。这种情况下,我们可以使用 Class::XSAccessor::Array, 它更给力。

当然,如果你需要说服你的上级或者你自己,你需要一个对大部分流行的 accessor 模块的 benchmark,我们也有这样的东西。简单的安装 App::Benchmark::Accessors, 你就能得到你所需要的结果。

类似的结果可以参考 http://www.cpantesters.org/distro/A/App-Benchmark-Accessors.html 里的 test reporters,我就不重复 copy 我自己的结果了。

Enjoy!

View Source (POD)