2012-04-08 1 views
2

Rubyの「インクルード」/「拡張」メカニズムのようなPerlコードをどのようにエミュレートできますか?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で整理する良い方法がいくつか存在するでしょうか? 継承、実行時に行われ、両方の対特性/ミックスインのように見えます

答えて

7

traits/mixinsの部分は、役割と呼ばれるPerl6の概念でカバーされています。

Perl 5での実装方法は?私はそれがPerl 6のために向かったOO /メタ言語サポート機能の試験場として開始信じる

(もperldoc for Mooseを参照してください)Mooseよりもう探す必要はありませんが、Perlの5に今ではの生活に撮影していて自分自身とたくさんのCPANパッケージはMooseに依存しています。

Mooseは、さまざまなオブジェクト指向言語構造(いくつかの異なるOOパラダイムから)を実装しており、非常に拡張性があります。

ムースにおける概念の説明とそれらがどのように他の言語の構文にマッピングまた、CPANにMooseMooseX名前空間は、無料(または実験)がぎっしり詰まっているConcepts section of the Moose manual

で見つけることができますパッケージへより多くのオブジェクト指向(OO)構造をサポートします。ここで

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
1

のPerl /ムースに、このコードのリテラル翻訳が(ちょっと)のようになります。

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のミックスインと同等です。

ルビーincludeではインスタンスメソッドで混合するのに対し、extendはクラスミックスインで使用します。 Perlでは、すべてのメソッドをクラスまたはインスタンスで呼び出すことができるため、ロールはwithを使用して追加されます。

関連する問題