Meise2000: Variable im Packagenamen?!

Hallo Leute,

ich möchte eine Subroutine (z.B. "evaluate($p1,$p2,$p3)") aufrufen, die in einem anderen Package (z.B. "myPackage1") liegt. Normalerweise mache ich das so:

my $result = myPackage1::evaluate($p1, $p2, $p3);

Jetzt habe ich mehrere Packages ("myPackage1", "myPackage2", "myPackage3"...) und alle haben eine Subroutine "evaluate($p1,$p2,$p3)". Die Entscheidung, welches Package ich verwende, hängt von einer Variablen (z.B. $package) ab. Wie bekomme ich  denn nun den Aufruf hin?! Die Variante

my $result = eval("$package::evaluate($p1,$p2,$p3)");

klappt leider nicht. Gibt es überhaupt eine Lösung für mein Problem?

Gruss,
Meise.

PS:
Mir ist schon klar, dass ich das ganze auf über ein if-elsif-elsif...else hinbekomme, aber das ist ungünstigt, da $package aus der Konfiguration heraus belegt werden soll - und ich möchte nicht immer den Quellcode erweitern, wenn ich ein neues Module (myPackageN) erstellt...

  1. Hallo,

    my $result = eval("$package::evaluate($p1,$p2,$p3)");

    Versuchs mal mit

      
    my $result = eval("${package}::evaluate($p1,$p2,$p3)");  
    
    

    Grund:
    Beim auswerten des Strings "$package::evaluate" versucht Perl den Inhalt der Variablen 'evaluate' des Packages $package zu ermitteln, der aber zwangsläufig undef ist, also wird nur mehr "($p1,$p2,$p3)" evaluiert, was an sich ja auch ein gültiger Ausdruck ist, also keinen Fehler verursacht. Durch die Angabe von "${package}" wird nur die Variable $package verwendet, und der Rest ("::evaluate") als reiner Text verwendet.

    Hier mein kleines Testbeispiel:

      
    #!/usr/bin/perl  
      
    use strict;  
      
    my $PackageName = "myPackage1";  
      
    eval ("${PackageName}::test();");  
      
    package myPackage1;  
    sub test  
    {  
     print "das ist package 1\n";  
    }  
      
    package myPackage2;  
      
    sub test  
    {  
     print "das ist package 2\n";  
    }  
      
    
    

    Grüße
      Klaus

    1. Hallo Klaus,

      danke für den Hinweis, allerdings klappt das leider nicht, wenn ich die Subroutine test() mit Parametern aufrufen möchte. Es klappt solange die Parameter einzelne Skalare sind. Wenn sie aber Objekte sind, geht es wieder nicht :-(

      Gruss,
      Meise.

      1. Hallo,

        danke für den Hinweis, allerdings klappt das leider nicht, wenn ich die Subroutine test() mit Parametern aufrufen möchte. Es klappt solange die Parameter einzelne Skalare sind. Wenn sie aber Objekte sind, geht es wieder nicht :-(

        Du musst natürlich die Sonderzeichen, die durch double-quotes ausgewertet werden, dort ausmaskieren, wo sie erhalten bleiben sollen.
        Also z.B:
        eval ("${package}::evaluate($p1,@p2,%p3)");

        Grüße
          Klaus

  2. Jetzt habe ich mehrere Packages ("myPackage1", "myPackage2", "myPackage3"...) und alle haben eine Subroutine "evaluate($p1,$p2,$p3)". Die Entscheidung, welches Package ich verwende, hängt von einer Variablen (z.B. $package) ab. Wie bekomme ich  denn nun den Aufruf hin?! Die Variante

    my $result = eval("$package::evaluate($p1,$p2,$p3)");

    klappt leider nicht. Gibt es überhaupt eine Lösung für mein Problem?

    Das ginge auch ohne eval:

    #!/usr/bin/perl -w  
      
    package A;  
    sub a  
    {  
    print "A::a()\n";  
    }  
    package B;  
    sub a  
    {  
    print "b::a()\n";  
    }  
    use strict;  
    my $var;  
      
    $var = 'A';  
    &{$var.'::a'}();  
      
    $var = 'B';  
    &{$var.'::a'}();
    

    Struppi.

    1. Also außer dass das in meiner Perl-Version (5.6) nur funktioniert, wenn ich "use strict" auskommentiere (sonst: Can't use string ("A::a") as a subroutine ref while "strict refs" in use at...) klappt das in der Tat, danke!

      Meise.

      PS: Wenn du noch weißt, wie man den "Schönheitsfehler" noch weg bekommt, wäre ich dir sehr dankbar :-)

      1. Also außer dass das in meiner Perl-Version (5.6) nur funktioniert, wenn ich "use strict" auskommentiere (sonst: Can't use string ("A::a") as a subroutine ref while "strict refs" in use at...) klappt das in der Tat, danke!

        stimmt, ich hab hier noch:

        no strict 'refs';
        $var = 'A';
        &{$var.'::a'}();

        $var = 'B';
        &{$var.'::a'}();

        Struppi.