我如何在我的Perl代码中模拟Ruby的“包含”/“扩展”机制?
让我们以Ruby中的以下代码为例:
module ActiveRecord
class Base
class << self
#...
end
#...
end
Base.class_eval do
include ActiveRecord::Persistence
extend ActiveModel::Naming
extend QueryCache::ClassMethods
extend ActiveSupport::Benchmarkable
extend ActiveSupport::DescendantsTracker
include ActiveModel::Conversion
include Validations
extend CounterCache
include Locking::Optimistic, Locking::Pessimistic
include AttributeMethods
...
end
end
这引出我提出这个问题,因为在研究的几天内我找不到任何明确的想法。那么,也许在Perl中存在一些组织它的好方法?
答案 0 :(得分:7)
看起来像 traits / mixins vs 继承,两者都是在运行时完成的。
traits / mixins部分由称为角色的Perl6概念所涵盖。
如何在Perl 5中实现?请看Moose(另请参阅perldoc for Moose)
我认为它最初是作为Perl 6的OO /元语言支持功能的试验场,但是在Perl 5中。现在它已经拥有了自己的生命,并且许多CPAN包依赖于Moose。
Moose实现了各种面向对象的语言结构(来自几个不同的OO范例)并且非常易于扩展。
可以在Concepts section of the Moose manual
中找到对Moose概念的解释以及它们如何映射到其他语言的构造。此外,CPAN上的Moose
和MooseX
命名空间充满了免费(或实验性)包,以增加对更多OO结构的支持。
答案 1 :(得分:3)
这是一个小例子:
#!/usr/bin/env perl
use 5.014;
package My::Quoted {
use Role::Tiny;
sub quoted_name {
my $self = shift;
return sprintf q{"%s"}, $self->name;
}
}
package My::One {
use Moo;
has name => (is => 'ro');
sub greet {
my $self = shift;
return sprintf 'Hello %s', $self->name;
}
}
package My::Two {
use Moo;
extends 'My::One';
with 'My::Quoted';
sub greet {
my $self = shift;
return sprintf 'Merhaba %s', $self->quoted_name;
}
}
package main {
run('Perl');
sub run {
my $name = shift;
my $x = My::Two->new({name => $name});
my $y = My::One->new({name => $name});
say $_->greet for $x, $y;
}
}
输出:
Merhaba "Perl" Hello Perl
答案 2 :(得分:1)
将此代码转换为Perl / Moose的 literal 将(有点)看起来像这样:
package ActiveRecord::Base;
use Moose;
use namespace::autoclean;
with qw(
ActiveRecord::Persistence
ActiveModel::Naming
QueryCache::ClassMethods
ActiveSupport::Benchmarkable
ActiveSupport::DescendantsTracker
ActiveModel::Conversion
Validations
CounterCache
Locking::Optimistic
Locking::Pessimistic
AttributeMethods
);
__PACKAGE__->meta->make_immutable;
1;
上面使用的Moose Roles相当于Ruby的mixins。
在Ruby中include
用于混合实例方法,而extend
用于类混合。在Perl中,所有方法都可以由类或实例调用,因此使用with
添加角色。