Perl:如何模拟Ruby的“包含/扩展”机制?

时间:2012-04-08 06:47:28

标签: ruby perl include extend emulation

我如何在我的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中存在一些组织它的好方法?

3 个答案:

答案 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上的MooseMooseX命名空间充满了免费(或实验性)包,以增加对更多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添加角色。