取势 明道 优术

作者为 扶 凯 发表

 


NAME

Moose::Manual::MOP – The Moose (and Class::MOP) meta API

 


VERSION

version 2.0401

 


INTRODUCTION

Moose提供了一个强大的自省api=> Class::MOP."MOP"是Meta-Object Protocol的简写,MOP是moose内部自省的class,可以 查看属性,方法等等.

事实上,Class::MOP的很多特性都是通过MOP实现的,包括属性,before/after/around方法修饰,以及immutability.在大多数情况下,Moose内置的Class::MOP并且通过子类添加特性.Moose还添加了一些roles,augment modifiers,以及type.

其实Class::MOP就像我们经常查阅的perldoc,如果你想随时随地的了解Moose或者拿起来就查阅的doc,那么你一定要了解一下Class::MOP.

MOP提供的自省api都是只读模式的。同样,你也可以根据自己的需要添加你自己的属性和方法.事实上,所有Moose的语法糖都是建立在MOP这一层面上的.

如果你想写Moose的扩展,你需要更透彻的了解MOP API.这些自信方法都是你要在你的moose extension里面提供和继承的.

这篇文章可能不能百分之百覆盖meta API所有的内容,我们只是带你浏览一遍MOP一些比较有特色的内容,就像小骆驼那本书一样,对MOP从头到尾让你浏览一遍,了解它工作的原理,如果你想更深的了解,你可能需要阅读一些更为深入的文档.

 


GETTING STARTED

最常用的使用meta API就是通过一个metaclass对象=> the Moose::Meta::Class manpage。你可以通过调用meta方法来得到这个meta对象 。

  package User;
  use Moose;
  my $meta = __PACKAGE__->meta;

当你声明了 use moose,meta方法就已经被导入到这个class里面了.

另外,你害可以通过<Class::MOP::Class-initialize($name>>获取一个metaclass 对象,这比之前的方法 更为安全,当你不确定你所在的类是否有这个meta的方法.

Class::MOP::Class->initialize将会返回一个Class::MOP::Class的对象,当然这只能在你的class是moose的class的前提下,如果你是普通的perl5的类,这完全是没有效果的.

 


USING THE METACLASS OBJECT

metaclass对象可以告诉你有关一个类的属性,方法,role,父类甚至更多.例如,查看一下moose的所有属性.

  for my $attr ( $meta->get_all_attributes ) {
      print $attr->name, "\n";
  }

get_all_attributes方法是Class::MOP::Class提供的,凡是使用的moose的class,它都会返回一个the Moose::Meta::Attribute manpage的列表,包括父类的属性.

你也可以得到所有的方法对象列表

  for my $method ( $meta->get_all_methods ) {
      print $method->fully_qualified_name, "\n";
  }

这些method对象还可以是委托方法的对象,或者是new方方法的对象.

我们还可以查看一下当前类的父类和子类.

  for my $class ( $meta->linearized_isa ) {
      print "$class\n";
  }

  for my $subclass ( $meta->subclasses ) {
      print "$subclass\n";
  }

值得注意的是,这里返回的不是对象了,而是直接返回class的names.

 


ALTERING CLASSES WITH THE MOP

通过metaclass对象还可以直接更改class,通过添加属性,方法等等方式.

例如,我们给一个类添加一个方法.

  $meta->add_method( 'say' => sub { print @_, "\n" } );

或者添加一个属性.

  $meta->add_attribute( 'size' => ( is => 'rw', isa  => 'Int' ) );

某种程度上,这比使用perl的语法糖来添加方法更加直观,而且这个API提供了非常强大的扩展.

你可能还记得我们之前提供的immutable方法,一旦你在class里面声明了这个class immutable,所以想要更新这个class的方法的操作都会抛出一个异常.

现在假设我们调用了$meta->make_mutable.一旦你做完了你要的改变,你可以通过$meta->make_immutable来恢复immutable。

其实meta APi最常用的是用来写Moose的扩展,假设这些扩展在你声明immutable的之前已经开始run了.

 


GOING FURTHER

如果你有兴趣来扩展Moose,我们推荐你阅读在the Moose::Cookbook manpage里面所有有关"Meta"和"Extending"的原则。这些原则展示了各种各样的通过MOP来扩展的应用.

如果你想写你自己的扩展,最好的方法就是看看其他人已经贡献的扩展,看看他们是如何实现的.同样你还需要阅读各种各样的API文档.包括Moose::Meta::*系列以及Class::MOP::*系列文档.

最后,如果你在这方面有什么问题,可以在我们的邮件列表和IRC畅所欲言,我们会尽可能的帮助你解决问题.IRC的地址和maillist的地址你可以在Moose.pm docs里面找到.好了,完了.

AUTHOR

译者:斯文牛氓

 


NOTE

本文由个人根据 cpan 翻译,可能由于水平有限,译文质量望读者见谅,不屑一顾者请绕道远行,英文好的请直接看原著(最好也帮助翻译). — PerlChina 重建计划作品

来了就留个评论吧! 没有评论