2009-02-27 5 views
0

Ich möchte eine Funktion exportieren, die vom Namen der Klasse abhängt, in die exportiert wird. Ich dachte, dass es mit Sub::Exporter einfach sein sollte, aber leider wird der Schlüssel into nicht an Generatoren übergeben. Ich habe mit diesem hässlichen Beispielcode am Ende:Wie kann ich einfach eine Perl-Funktion abhängig vom Namen der importierenden Klasse generieren?

use strict; 
use warnings; 

package MyLog; 

use Log::Log4perl qw(:easy get_logger); 

use Sub::Exporter -setup => { 
    exports => [ 
     log  => \&gen_log, 
     audit_log => \&gen_log, 
    ], 
    groups  => [ default => [qw(log audit_log)] ], 
    collectors => ['category'], 
    installer => \&installer, # tunnel `into` value into generators 
}; 

if (not Log::Log4perl->initialized()) { 

    #easy init if not initialised 
    Log::Log4perl->easy_init($ERROR); 
} 

sub gen_log { 
    my ($class, $name, $arg, $global) = @_; 

    my $category = $arg->{category}; 
    $category = $global->{category}{$name} unless defined $category; 

    return sub { # return generator 
     my $into = shift; # class name passed by `installer` 

    $category = $name eq 'audit_log' ? "audit_log.$into" : $into 
     if !defined $category; # set default category 

     # lazy logger 
     my $logger; 
     return sub { 
      $logger or $logger = get_logger($category); 
     }; 
    }; 
} 

sub installer { 
    my ($args, $todo) = @_; 

    # each even value is still generator thus generate final function 
    my $i; 
    1 & $i++ and $_ = $_->($args->{into}) for @$todo; 

    Sub::Exporter::default_installer(@_); 
} 

1; 

Gibt es eine bessere Art und Weise, wie es all diese reichen Sub::Exporter Fähigkeiten ohne Opfer zu tun?

Zum Beispiel würde Ich mag einen von denen verwenden:

use MyLog category => { log => 'foo', audit_log => 'bar' }; 

use MyLog -default => { -prefix => 'my_' }; 

use MyLog 
    audit_log => { -as => 'audit' }, 
    log  => { -as => 'my_log', category => 'my.log' }; 

bearbeiten: hinzugefügt Sub::Exporter Fähigkeiten Anforderung in Frage zu stellen.

Edit2: Weitere Verwendungsbeispiele hinzugefügt.

Antwort

2

Sie sind nicht klar, wie Sie den Namen ermitteln möchten. Wenn ich dich richtig verstehe, macht das, was du willst.

+0

Ihr Code tun, was ich will, aber ohne all diese reichen Sub :: Exporter Fähigkeiten z. B. MyLog category => {log => 'foo', audit_log => 'bar'}; oder benutze MyLog -default => {- prefix => 'my_'}; oder benutze MyLog audit_log => {- as => 'audit'}, log => {- als => 'mein_log', kategorie => 'mein.log'}; usw. –

+0

Wenn du das wolltest, hättest du es in deiner Frage sagen können, anstatt mich jetzt zu wählen. –

+0

Sorry, ich habe es jetzt zur Frage hinzugefügt. –

Verwandte Themen