是否可以在运行时替换Moose对象的方法?通过查看Class::MOP::Method(Moose::Meta::Method继承自)的源代码,我得出结论
$method->{body} = sub{ my stuff }
Run Code Online (Sandbox Code Playgroud)
我可以在运行时替换对象的方法.我可以使用该方法
$object->meta->find_method_by_name(<method_name>);
Run Code Online (Sandbox Code Playgroud)
但是,这并没有完全奏效.
是否可以在运行时修改方法?而且,与Moose一起做的方法是什么?
如何在初始化后定义Moose对象子程序?
我正在使用Moose编写一个对象模块,我计划序列化(nstore)创建的对象.
检查以下(简化!)示例:
package MyObj 0.001;
use Moose;
use namespace::autoclean;
has 'size' => (
is => 'ro',
isa => 'Int',
required => 1,
);
sub some_sub {
my ($self, @more) = @_;
if ($self->size() < 100) # do something;
elsif (($self->size() < 500)) # do something else;
elsif (($self->size() < 7500)) # do something else;
# ...
}
1;
Run Code Online (Sandbox Code Playgroud)
some_sub行为不同取决于size.由于它size是只读的,因此在初始化对象后它保持不变.
所以,假设我打了some_sub几十万次,很遗憾我if每次都必须经历所有的事情.
在对象初始化之后我最好这样做一次,然后设置some_sub为更简单的函数,根本没有ifs.
但是......我怎么能这样做?
UPDATE
也许我应该添加一个 …
我注意到一些Perl模块使用基于类的结构,但不管理任何数据.该类仅用于访问其中的方法,仅此而已.
请考虑以下示例:
Class.pm
package Class;
use Moose;
sub do_something {
print "Hi!\n";
}
1;
Run Code Online (Sandbox Code Playgroud)
test.pl
use Class;
# Instantiate an object from the class
my $obj = Class->new();
$obj->do_something();
Run Code Online (Sandbox Code Playgroud)
在此示例中,您可以看到首先实例化该类的实例,然后从创建的对象中调用该方法.
可以像这样实现相同的最终结果:
Module.pm
package Module;
use strict;
use warnings;
sub do_something {
print "Hi!\n";
}
1;
Run Code Online (Sandbox Code Playgroud)
test.pl
use Module;
Module::do_something();
Run Code Online (Sandbox Code Playgroud)
我想知道为什么人们使用第一种方法编写模块,并且如果它提供了一些好处.对我来说,似乎它增加了一个额外的步骤,因为为了使用这些方法,首先需要实例化该类的对象.
我不明白为什么人们会像这样编程,除非它有一些我没有看到的好处.
按照phaylon的回答"如何灵活地向Moose对象添加数据?" ,假设我有以下Moose属性:
has custom_fields => (
traits => [qw( Hash )],
isa => 'HashRef',
builder => '_build_custom_fields',
handles => {
custom_field => 'accessor',
has_custom_field => 'exists',
custom_fields => 'keys',
has_custom_fields => 'count',
delete_custom_field => 'delete',
},
);
sub _build_custom_fields { {} }
Run Code Online (Sandbox Code Playgroud)
现在,假设我想尝试读取(但不是写入)不存在的自定义字段时会呱呱叫.我被phaylon建议custom_field用一个环绕修饰语包裹.我已经around按照Moose文档中的各种示例尝试了修饰符,但无法确定如何修改句柄(而不仅仅是对象方法).
或者,是否有另一种方法来实现这个croak-if-try-to-read-unfxisting-key?