• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] perl:Variabeln an ein Modul von einem Script aus ..

Hi zusammen!

Kann man einem Modul Parameter übergeben die man in einem Script definiert was auf das Modul angewiesen ist?

Code:
#!/usr/bin/perl -w

use standard;

$|=1;

standard->header("der string sollte an das modul übergeben werden und an STDOUT gesendet werden");

Das Modul
Code:
# standard.pm
package standard;

use warnings;
use strict;

sub header {
my ($VARIABLE) = @_;
print "$VARIABLE";
}
1;

Wie kann ich das was ich oben versucht habe umzusetzten in ein PERL konformes Script schreiben?

Danke für eure Hilfe!
 

abgdf

Guru
Probier's mal so:
Code:
# standard.pm
package standard;

use warnings;
use strict;

sub header {
    print $_[1];
}

1;
:wink:

Gruß
 

abgdf

Guru
Doch: Gerade nochmal getestet. Geht.

Übergib doch erstmal innerhalb eines Skripts eine Variable an eine Funktion (sub) (wieder mit "$_[0]" usw.).
Wenn das geht, setz das in einem zweiten Schritt in einem Modul um.
Du mußt die Probleme in kleinere Schritte zerteilen und langsam eins nach dem anderen angehen.
Dein
Code:
my ($VARIABLE) = @_;
war wohl nicht so gut: Die Klammern sind überflüssig, $VARIABLE ist eine Skalarvariable, @_ eine Liste. So kann das nichts werden.

Gruß
 
OP
xeroxed_yeti

xeroxed_yeti

Member
hey danke für deine mühe!

ich habe mir nun eine andere lösung ausgedacht.

aber kurz zu deiner lösung, der ansatz geht ohne probleme wenn du eine subroutine in dem script aufrufst.

Code:
subroutine($übergabe)

....

sub subroutine {
     my ($in) = @_;
}

dann habe ich die variable $übergabe an die subroutine in die variable $in übergeben.

auf diese weise habe ich es aber nicht geschaft eine variable an ein modul zu übergeben welches ausserhalb des scriptes liegt und nur in der USE - deklaration aufgerufen wird.

USE strict;
USE MODULE

ich habe nun eine bessere lösung gefunden:

Code:
#!/usr/bin/perl -w

use standard;

$|=1;

standard_print1;
standard->header;

standard_print2;
standard->header2;
das modul habe ich erweitert
Code:
#standard.pm
package standard;

use warnings;
use strict;

my $print = 'undef';
sub header_print1 {
     $print = "hallo du wicht!\n";
}

sub header_print2 {
    $print = "mach's gut du nase :) !\n";
}


sub header {
     print "$print";
}
1;

aber danke für deine bemühungen!!!!
 
newbie_needs_help schrieb:
Hi zusammen!
Kann man einem Modul Parameter übergeben
Code:
use standard qw(parameter);
...

package standard;
sub import (@)
{
        my $pkg = shift @_;
        # nun ist @_ = qw(parameter);
}
Ne genauere Erklärung zu sub import findet sich in den Perl-Manpages leider nicht, obwohl die sonst immer sehr gut sind.
 
OP
xeroxed_yeti

xeroxed_yeti

Member
Hi jengelh,

danke für deine Antwort.

Die Übergabe funktioniert ....nur leider nicht mit dem Parameter, den ich gerne übergeben würde :~)

mein perl script, std.pl

Code:
#!/usr/bin/perl -w

use warnings;
use strict;
use standard qw(ensembl0507);

$|=1;
standard->db_connection_5433;


mein modul

Code:
# standard.pm
package standard;

sub db_connection_5433  {
#PostgreSQL database connection

    use DBI;

    my $db = shift @_;
    print "\n\n$db\n\n";
}
1;

der Aufruf perl std.pl in der shell liefert mir "standard" für $db zurück.
 

ginka

Member
Probiers doch mal so:

Modul standard.pm:
Code:
# standard.pm
package standard;

use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(db_connection_5433);


sub db_connection_5433  {
#PostgreSQL database connection

    use DBI;

    my $db = shift @_;
    print "\n\n$db\n\n";
}
1;

Das Skript:
Code:
#!/usr/bin/perl -w

use warnings;
use strict;
use standard;

$|=1;
db_connection_5433("Hallo Welt!");


Noch was:

abgdf schrieb:
Dein
Code:
my ($VARIABLE) = @_;
war wohl nicht so gut: Die Klammern sind überflüssig, $VARIABLE ist eine Skalarvariable, @_ eine Liste. So kann das nichts werden.

Das stimmt übrigens nicht. Die Klammern indizieren einen Array-Kontext. So wie das hier definiert ist, wird das erste Element von @_ an $VARIABLE übergeben. Lässt man die Klammern weg, steht $VARIABLE in einem skalaren Kontext und wird mit der Anzahl der Elemente in @_ gefüllt.

Viele Grüße
ginka
 
OP
xeroxed_yeti

xeroxed_yeti

Member
wenn ich dein Script 1zu1 übernehme bekomme ich die Fehlernachricht:

"Undefined subroutine &main::db_connection_5433 called at std.pl line 10."

also habe ich den aufruf in

Code:
#!/usr/bin/perl -w

use warnings;
use strict;
use standard;

$|=1;
standard->db_connection_5433("Hallo Welt!");

verändert.

Der output in der shell ist dann wieder "standard". Hehe ich dachte ich bin eine Perlfreak ... man lernt nieee aus. Momentan habe ich mich echt an dem Problem verbissen :)

wer weiß die lösung?
 

ginka

Member
newbie_needs_help schrieb:
wenn ich dein Script 1zu1 übernehme bekomme ich die Fehlernachricht:

"Undefined subroutine &main::db_connection_5433 called at std.pl line 10."

Hast du auch das Modul übernommen? Wenn du die dort definierte Subroutine korrekt exportierst, mit:
Code:
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(db_connection_5433);

... dann sollte es gehen. Tut es bei mir jedenfalls - der von mir gepostete Code (Skript UND Modul) funktioniert einwandfrei so wie er ist.

Ohne Export kannst du die Subroutine db_connection_5433 nicht so ohne weiteres ansprechen, da sie sich im Namensraum standard befindet (verursacht durch die Anweisung
Code:
package standard;
im Modul). Das Skript sucht aber im Namensraum main.

Theoretisch könntest du die Subroutine in deinem Modul aus dem Hauptprogramm heraus auch mit
Code:
standard::db_connection_5433();
aufrufen, damit gibst du dem Interpreter an, dass er im Namensraum "standard" suchen soll. Aber eigentlich ist das nicht im Sinne des Erfinders. Die Idee ist, dass man NICHT wissen muss, in welchem Namensraum sich eine in einem Modul definierte Funktion befindet. Daher die Sache mit dem Export.

Die Pfeil-Notation

Code:
standard->...

ist übrigens für objektorientierte Programmierung in Perl gedacht, nicht für Namensräume.

Viele Grüße
ginka
 
OP
xeroxed_yeti

xeroxed_yeti

Member
hey ginka,

ja danke jetzt geht es. ich habe oben ein wenig geflunkert, als ich gesagt habe, ich habe es 1zu1 übernommen. Das Problem: ich hatte noch immer "use warnings" und "use strict" aufgerufen ... strict hat wie schon so oft das Script beendet und mir eine Fehlermeldung ausgegeben mit standard->db_connection_5433 konnte ich das Problem umgehen aber kam nicht zum gewünschten Ergebnis. Nun rufe ich erst "use Exprorter" und die Zeilen mit @ISA und @EXPORT auf und dann kommt mein überlicher Unsinn :)

Danke für deine Hilfe!!
 

abgdf

Guru
Das stimmt übrigens nicht. Die Klammern indizieren einen Array-Kontext. So wie das hier definiert ist, wird das erste Element von @_ an $VARIABLE übergeben. Lässt man die Klammern weg, steht $VARIABLE in einem skalaren Kontext und wird mit der Anzahl der Elemente in @_ gefüllt.

:lol: Perl versteht eben alles.
Dafür ist nicht immer offensichtlich, wie es etwas versteht.
(Das ist einer der Gründe, warum ich Python bevorzuge. Dort ist übrigens auch das Einbinden von Modulen kinderleicht: So einfach und klar sähe das dort aus:
Code:
#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-

import standard

standard.header("der string sollte an das modul übergeben werden und an STDOUT gesendet werden")

Code:
#!/usr/bin/env python

# standard.py

def header(a):
    print a
).

Viele Grüße
 
newbie_needs_help schrieb:
Hi jengelh,
danke für deine Antwort.
Die Übergabe funktioniert ....nur leider nicht mit dem Parameter, den ich gerne übergeben würde :~)
Nein, die Parameter zum Modul sind nur in der import Funktion verfügbar... die musst du dann halt woanders hinkopieren wenn du die benötigst, a la:
Code:
package mypkg;
our $db_name;

sub import ($@)
{
    $db_name = $_[1];
    return;
}

sub new ($)
{
    return bless {};
}

sub connect ($)
{
    my $this = shift @_;
    $this->{connection} = mysql_connect("localhost", "username", "passwort", $db_name);
}
oder wie auch immer sql geht.
und mach dir keine Sorgen mit @ISA und @EXPORT... zumindest nicht jetzt.
Code:
use mypkg qw(ensembel);
$object = new mypkg();
$object->connect();
(Wo man dann aber ensembel besser als Argument zu new mypkg übergeben könnte.) Aber sollte ja auch eine Moduloption sein, und keine Instanzoption...
 

ginka

Member
abgdf schrieb:
:lol: Perl versteht eben alles.
Dafür ist nicht immer offensichtlich, wie es etwas versteht.

Das ist wohl wahr... :lol:

Frei nach dem Motto "Perl macht keine Fehler, Perl macht immer irgendwas". Oft nur nicht das, was man vielleicht erwartet hat.

Nicht umsonst steht Perl auch für "Pathologically Eclectic Rubbish Lister" :D

Viele Grüße
ginka
 
Oben