[Dresden-pm] Problem mit Moduleinbindung

A. Pagaltzis pagaltzis at gmx.de
Do Aug 16 04:42:58 PDT 2007


* Thomas Rittsche <thomas.rittsche at gmail.com> [2007-08-15 10:35]:
> Wir habens jetzt über die "Winklersche" Methode gelöst:
> 
> use Carp qw(croak);
> 
> eval "require $productCalculate";
> 
> croak $@ if $@;
> 
> if(my $coderef = UNIVERSAL::can($productCalculate, $sub)){
>  ($value{'netto'}, $value{'mwstprice'}, $value{'brutto'}) = 
>  $coderef->(\%val);
> }

Igitt. `UNIVERSAL::can` ist eine Methode; vergess bitte sofort
wieder, dass man das, weil Perl keinen wirklichen Unterschied
zwischen Methoden und Prozeduren kennt, auch als Prozedur
aufrufen kann. Das hebelt nur völlig grundlos Vererbung und
sonstige Polymorphie aus.

In deinem Fall ist das zwar wahrscheinlich kein Problem, aber du
brauchst `UNIVERSAL::can` auch garnicht. Genauso sieht es sonst
aus; da es keinen einzigen Fall gibt, in dem man darauf
angewiesen wäre, `UNIVERSAL::can` als Prozedur aufzurufen, sollte
man sich das garnicht angewöhnen.

Der ordentliche Ansatz lautet in deinem Fall folgendermassen:

    my $calc = eval qq{
        require $productCalculate;
        \\&${productCalculate}::calculate;
    };

    croak $@ if $@;

    if( $calc ) {
        @value{ qw( netto mwstprice brutto ) } = $calc->( \%val );
    }

Man beachte die Doppelung des Backslashs im Eval-String. Ich will
an der Stelle eine Referenz zur Funktion nehmen; da ich den Code
in einem ein String mit doppelten Anführungszeichen stehen habe,
muss der dafür verwendete Backslash entwertet werden.

Ich weiss übrigens nicht, warum das `if` an der Stelle eigentlich
nötig ist. Nach deiner ursprünglichen Beschreibung zu urteilen
sollte jedes der in Frage kommende Module eine `calculate`-
Funktion enthalten. Das bedeutet, dass das `if` allein dem Zweck
dient, ein fatales Problem in stillschweigendes Fehlverhalten zu
konvertieren. Entweder sollte das `if` durch einen `else`-Zweig
ergänzt werden, der laut schreit, oder einfach komplett wegfallen
(dann übernimmt Perl das laut schreien automatisch).

Gruss,
-- 
Aristoteles Pagaltzis // <http://plasmasturm.org/>