Was bedeutet diese Fehlermeldung ?
Poldi
- perl
0 Jens Müller
Im NMS formmail von sourceforge.net wollte ich einen Text variabel gestalten und habe daher in dem folgenden Codeteil die Zeile (#....) durch die darauf folgende ersetzt.
Ich erhalte dann die Fehlermeldung:
Global symbol "$tDanke" requires explicit package name at (eval 8) line
1342
Als Perl-Anfänger sagt mir die Meldung nichts. Könnt Ihr mir - ohne das gesamte Listing zu kennen, sagen, woran es liegen könnte ?
Hier der Code-Teil:
use vars qw(... $tDanke ....);
...
$tDanke = ".....";
sub success_page_html_preamble {
my ($self, $date) = @_;
# my $title = $self->escape_html( $self->{FormConfig}{'title'} || "Danke für die Nachricht");
my $title = $self->escape_html( $self->{FormConfig}{'title'} || "$tDanke");
my $torecipient = 'to ' . $self->escape_html($self->{FormConfig}{'recipient'});
$torecipient = '' if $self->{Hide_Recipient};
my $attr = $self->body_attributes;
.........
Hallo ,
Global symbol "$tDanke" requires explicit package name at
(eval 8) line 1342
Das strict Modul beschwert sich da drueber, dass die Variable
$tDanke nicht explizit deklariert wurde.
> use vars qw(... $tDanke ....);
> ...
> my $tDanke = ".....";
Such mal ein wenig in deiner Perl-Dokumentation nach der Seite
perldiag.html. Das ist eine Diagnose Datei, die dokumentiert was
und wo drueber sich der Perl-Parser beschwert.
gruesse aus'm ruhrpott
jens mueller
Hallo ,
Such mal ein wenig in deiner Perl-Dokumentation nach der Seite
perldiag.html.
Danke für den Hinweis
Das strict Modul beschwert sich da drueber, dass die Variable
$tDankenicht explizit deklariert wurde.
Mit der Angabe my $tDanke .... kommt die gleiche Meldung.
Gruß
Poldi
Das strict Modul beschwert sich da drueber, dass die Variable
$tDankenicht explizit deklariert wurde.Mit der Angabe my $tDanke .... kommt die gleiche Meldung.
Die Datei wo du das hingeschrieben hast, ist die Gleiche in der der Fehler auftritt?
Struppi.
Die Datei wo du das hingeschrieben hast, ist die Gleiche in der der Fehler auftritt?
Ja,
aber ich habe folgenden Kommentar im Script gefunden.
Heißt das vielleicht, das das Script wie mehrere Dateien zu betrachten ist ?
Es hat mehrere BEGIN-Blöcke !
Ja,
aber ich habe folgenden Kommentar im Script gefunden.The code below consists of module source inlined into this
script to make it a standalone CGI.
Was immer das bedeuten mag, ich versteh es nicht.
Heißt das vielleicht, das das Script wie mehrere Dateien zu betrachten ist ?
Es hat mehrere BEGIN-Blöcke !
Ein BEGIN Block wird vor dem Start des Skriptes ausgeführt (während der Übersetzung), es sollte schon klar sein, warum man das tut.
Struppi.
Ein BEGIN Block wird vor dem Start des Skriptes ausgeführt (während der Übersetzung), es sollte schon klar sein, warum man das tut.
Ich tue es ja nicht,
ich möchte es ja nur verstehen!
Ein BEGIN Block wird vor dem Start des Skriptes ausgeführt (während der Übersetzung), es sollte schon klar sein, warum man das tut.
Ich tue es ja nicht,
ich möchte es ja nur verstehen!
http://perldoc.perl.org/perlmod.html#BEGIN%2C-CHECK%2C-INIT-and-END-BEGIN-CHECK-INIT-END
Es sollte aber nichts mit deiner Fehlermeldung zu tun haben.
Struppi.
Hallo ,
Ein BEGIN Block wird vor dem Start des Skriptes ausgeführt
(während der Übersetzung), es sollte schon klar sein, warum
man das tut.
Ich tue es ja nicht,
ich möchte es ja nur verstehen!
Es ist a nicht Poldis Script, er moechte es ja nur bei sich einsetzen.
Es sollte aber nichts mit deiner Fehlermeldung zu tun haben.
Doch es sollte:
»A BEGIN code block is executed as soon as possible, that is, the
moment it is completely defined, even before the rest of the
containing file (or string) is parsed.«
Original Code:~~~perl
sub success_page_html_preamble {
my ($self, $date) = @_;
my $title = $self->escape_html( $self->{FormConfig}{'title'} || 'Thank You' );
my $torecipient = 'to ' . $self->escape_html($self->{FormConfig}{'recipient'});
$torecipient = '' if $self->{Hide_Recipient};
my $attr = $self->body_attributes;
Der Fehler des Scripts liegt da dran, das der Begin Block als eigene
Script Datei augefuehrt wird. [In dieser Existiert die Variable `$tDanke`{:.language-perl}
gar nicht.
Die Variable `$tDanke`{:.language-perl} muss noch einmal explizit mit `my`{:.language-perl} aufgerufen
werden
~~~perl
sub success_page_html_preamble {
my ($self, $date) = @_;
# Kleine Modifizierung: Wenn du noch andere Variablen in $tDanke
# aufrufst, dann muessn diese auch mit *my* gekenzeichnet werden
my $tDanke = ".....";
my $title = $self->escape_html( $self->{FormConfig}{'title'} || "$tDanke");
...
Die vorherige deklarierung, kann geloescht werden
use vars qw(... $tDanke ....);
...
# ... und wech damit: $tDanke = ".....";
gruesse aus'm ruhrpott
jens mueller
Es sollte aber nichts mit deiner Fehlermeldung zu tun haben.
Doch es sollte:
»A BEGIN code block is executed as soon as possible, that is, the
moment it is completely defined, even before the rest of the
containing file (or string) is parsed.«
Bis jetzt war noch nicht davon die Rede, dass der code im BEGIN Block steht und selbst wenn, dann definiert man die betreffende Variabel in diesem Block.
Original Code:~~~perl
Na, du weißt mehr als ich. Wobei aus dem Beispiel auch der Fehler nicht klar wird, weil hier nirgends ein BEGIN Block ist. Und wenn, wozu ist der gut?
Der Fehler des Scripts liegt da dran, das der Begin Block als eigene
Script Datei augefuehrt wird. [In dieser Existiert die Variable [code lang=perl]$tDanke
> gar nicht.
Ich kenn den Code ja nicht, aber der Fehler ist vermutlich eher die Existenz des BEGIN Blocks.
> Die Variable `$tDanke`{:.language-perl} muss noch einmal explizit mit `my`{:.language-perl} aufgerufen
> werden
Oder einfach den BEGIN block rausschmeissen.
Struppi.
--
[Javascript ist toll](http://javascript.jstruebig.de/) (Perl auch!)
Ist mein Beitrag untergegangen ?
Zu Jens:
# Kleine Modifizierung: Wenn du noch andere Variablen in $tDanke
# aufrufst, dann muessn diese auch mit *my* gekenzeichnet werden
my $tDanke = ".....";
my $title = $self->escape_html( $self->{FormConfig}{'title'} || "$tDanke");
Auf diese Art erhalte ich jetzt zwar keine Fehlermeldung mehr, aber ich weiß nicht, wie ich $tDanke einen dynamischen Wert zuweisen soll.
Ich erhalte vom rufenden Skript die Sprache (spr) übergeben.
Ich habe also in der Subroutine folgende Befehle eingefügt.
my $tsprache = param('spr');
my $tDanke;
if ($tsprache == "d")
{$tDanke = "Danke für die Nachricht"}
else
{$tDanke = "Merci pour votre message"};
Da bringt mir das System aber nur noch die nichtssagende Meldung
Application Error
An error has occurred in the program
See the web server's error log for details
Das Dumme ist nur, ich kann den Log (bei Netbeat) nicht anschauen.
Zu Jens und Struppi:
Ich sehe vollkommen ein, dass eine realistische Einschätzung der Fehlersituation ohne Vorlage des Script eigentlich nicht möglich ist.
Ich wollte allerdings der SELFHTML-Gemeinde nicht ein so langes Script zumuten (über 3500 Zeilen).
Falls sich doch jemand die Mühe machen wollte (mein Dank wird ihr/ihm gewiss sein), ich habe das Skript unter
beinahe<Minuszeichen>gratis<Punkt>de<Schrägstrich>feedback-test.txt
abgestellt (fragliche Stelle ab Zeile 3236).
Ist mein Beitrag untergegangen ?
nein, aber angesichts des Umfanges (des in meinem augen nicht schönen Skript) und meiner eingeschränkten Zeit, ist da keine Chance, dass ich mir das antue.
Meiner Meinung nach beruht dein Problem darin, dass dieses Skript überall diese BEGIN Blöcke verwendet, allerdings fehlt mir wie gesagt die Zeit das nachzuprüfen.
Auf diese Art erhalte ich jetzt zwar keine Fehlermeldung mehr, aber ich weiß nicht, wie ich $tDanke einen dynamischen Wert zuweisen soll.
Ich erhalte vom rufenden Skript die Sprache (spr) übergeben.
Ich habe also in der Subroutine folgende Befehle eingefügt.
my $tsprache = param('spr');
my $tDanke;
if ($tsprache == "d")
{$tDanke = "Danke für die Nachricht"}
else
{$tDanke = "Merci pour votre message"};
Hier fehlen die abschliessenden Semikolons (arghh, die heissen bestimmt anders, ich Legasteniker)
Falls sich doch jemand die Mühe machen wollte (mein Dank wird ihr/ihm gewiss sein), ich habe das Skript unter
beinahe<Minuszeichen>gratis<Punkt>de<Schrägstrich>feedback-test.txt
abgestellt (fragliche Stelle ab Zeile 3236).
ich hab's runtergeladen und angeschaut. Aber wie gesagt, es ist nicht mein Stil und daher hab ich auch wenig Lust gehabt das auszuprobieren.
Struppi.
Hallo Struppi,
ich hab's runtergeladen und angeschaut. Aber wie gesagt, es ist nicht mein Stil und daher hab ich auch wenig Lust gehabt das auszuprobieren.
Habe vollstes Verständnis bei der Länge des Skripts.
Danke Dir trotzdem, Du warst ja bisher sehr engagiert, und wie ich sehe auch in vielen anderen Beiträgen.
Ich hoffe ja immer noch, dass sich jemand meldet, der das Skript selbst verwendet und viel darin geändert hat (vielleicht sogar mehrsprachig erweitert hat) - und die Hoffnung stirbt zuletzt.
Ansonsten werde ich halt weiter herumstochern.
Gruß Poldi
Moin,
Hier fehlen die abschliessenden Semikolons (arghh, die heissen
bestimmt anders, ich Legasteniker)
Dem kann nachgeholfen werden:
»Semiko̱lon, das; -s, -s / Semikola lat. + griech. /Satzzeichen, das
keinen starken Einschnitt zwischen zwei selbständigen Sätzen
kennzeichnet: ;/ das S. trennt schärfer als das Komma, aber
weniger scharf als der Punkt«
gruesse aus'm ruhrpott
jens mueller
Hell-O!
my $tDanke = ".....";
my $title = $self->escape_html( $self->{FormConfig}{'title'} || "$tDanke");
Auf diese Art erhalte ich jetzt zwar keine Fehlermeldung mehr, aber ich weiß nicht, wie ich $tDanke einen dynamischen Wert zuweisen soll.
Innerhalb der entsprechenden Routine.
Ich erhalte vom rufenden Skript die Sprache (spr) übergeben.
Ich habe also in der Subroutine folgende Befehle eingefügt [...]
Und diese Subroutine steht vermutlich innerhalb des BEGIN-Blocks, weshalb die Variable nicht deklariert wurde und der entsprechende Fehler geworfen wird.
Falls sich doch jemand die Mühe machen wollte (mein Dank wird ihr/ihm gewiss sein), ich habe das Skript unter beinahe<Minuszeichen>gratis<Punkt>de<Schrägstrich>feedback-test.txt abgestellt (fragliche Stelle ab Zeile 3236).
Warum kein Link? Was helfen dürfte, ist ein no strict "vars" am Anfang des Scripts, was aber nicht Sinn und Zweck der Sache sein kann. Leider fällt die Dokumentation auf der Projektseite ziemlich dürftig aus und die Herren Experten scheinen keinen gesteigerten Wert darauf zu legen, dass jemand anderes ihr Script versteht.
Siechfred
Hallo Siechfred !
Und diese Subroutine steht vermutlich innerhalb des BEGIN-Blocks, weshalb die Variable nicht deklariert wurde und der entsprechende Fehler geworfen wird.
Ja, das ist wohl so. Wie ich erfahren habe, wird ein BEGIN-Block schon vor der Ausführung des Skripts, nämlich bei der Prüfung des Skripts ausgeführt.
Heißt dies, dass dann im BEGIN-Block noch gar keine Vaiablen des rufenden Skripts angesprochen werden können ?
Gruß
Poldi
Hell-O!
Heißt dies, dass dann im BEGIN-Block noch gar keine Vaiablen des rufenden Skripts angesprochen werden können ?
Ja, BEGIN-Blöcke werden *vor* der Kompilierung des verbleibenden Scripts ausgeführt, deshalb sind ihm von Haus aus keinerlei Variablen bekannt. Du musst halt zwischen Kompilierung und Ausführung des Scripts unterscheiden. BEGIN-Blöcke werden während der Kompilierung des Scripts ausgeführt und sind danach Geschichte. Daher kann man auch keine Variablen, die im BEGIN-Block deklariert wurden, unter dem strict-Pragma außerhalb dieses Blockes - also während des Ausführens des Scripts - aufrufen, ohne ihre Gültigkeit zur Laufzeit explizit festzulegen.
Mal ein paar Beispiele:
use strict;
use CGI qw/param/;
BEGIN {
$boo = param('foo');
}
print $boo;
Das wird nicht funktionieren. Zwar wird $boo innerhalb des BEGIN-Blocks deklariert, steht während der Ausführung aber nicht zur Verfügung.
use strict;
use CGI qw/param/;
BEGIN {
sub return_boo { my $boo = param('foo'); }
}
print return_boo();
Das funktioniert, da u.a. das Deklarieren von Subroutinen - ggf. aus anderen Packages - zu den Aufgaben eines BEGIN-Blocks gehört.
Und schließlich noch die letzte Variante:
use strict;
use CGI qw/param/;
my $boo;
BEGIN {
$boo = param('foo');
}
print $boo;
Diese Variante funktioniert auch und kommt dem Grundprinzip des von dir verwendeten Scripts m.E. am nächsten. Die Variable $boo wird zweimal deklariert, nämlich während des Kompilierens im BEGIN-Block (wichtig: Ohne my oder our) und während der Ausführung via my $boo;. Dadurch erhältst du zur Laufzeit Zugriff auf den Inhalt der Variablen, den sie während der Kompilierungsphase erhalten hat. Würdest du es so schreiben:
use strict;
use CGI qw/param/;
my $boo = "";
BEGIN {
$boo = param('foo');
}
print $boo;
weist du der Variablen einen Leerstring zu und überschreibst damit den Wert, den sie während der Kompilierungsphase im BEGIN-Block erhalten hat.
Ich hoffe, ein kleines bisschen Licht ins Dunkel gebracht zu haben :-)
Siechfred
Auch Hell-O!
Gut erklärt ! Werde versuchen, damit auch 'mein' Skript zu verstehen (für einen Rentner und Perl-Anfänger gar nicht so einfach). Ich gehe wohl erst ein paar Tage (Wochen) auf Tauchstation, bevor ich mich dann wieder mit einer Erfolgsmeldung (oder einer neuen Frage) melde !
Danke
Poldi
Hallo,
Ist mein Beitrag untergegangen ?
Nein, war nur anders beschaeftigt. Ausserdem, kostet es ein wenig
Zeit, so ein langes Script zu analysieren.
Zu Jens:
# Kleine Modifizierung: Wenn du noch andere Variablen in
$tDanke aufrufst, dann muessn diese auch mit *my*
gekennzeichnet werden my $tDanke = ".....";
Auf diese Art erhalte ich jetzt zwar keine Fehlermeldung mehr,
aber ich weiß nicht, wie ich $tDanke einen dynamischen Wert
zuweisen soll.
Weil du schon vorher, innerhalb deines Scripts mindestens einen
Fehler hast.
Gleich am Anfang steht:
#!shebang line -wT
-w warnings
-T Taint modus
Anstatt: $tempfaenger = param('empfaenger'); , muss es
dann heisen:
my $tempfaenger = ($self->cgi_object->param('empfaenger'));
Das Modul strict(); erfordert die my Variante.
Der Taint Modus, den anderen Code. Das gillt fuer alle deine
eingefuegten Variablen. (Zeilen zwischen: 107 und 115)
Versuche deine Variablen Deklarationen so frueh wie Moeglich zu machen, innerhalb des im Script vorgegebenen Blocks.
# USER CUSTOMISATION SECTION
# --------------------------
# Place any custom code here
Ich wollte allerdings der SELFHTML-Gemeinde nicht ein so langes
Script zumuten (über 3500 Zeilen).
Generell richtig. Aber hier steckt der Teufgel wohl im Detail.
gruesse aus'm ruhrpott
jens mueller
Hallo Jens,
Gleich am Anfang steht:
#!shebang line -wT
das -wT steht doch erst in der zweiten Zeile, in der ersten steht nur -w. Wird die zweite trotzdem interpretiert ?
my $tempfaenger = ($self->cgi_object->param('empfaenger'));
Das Skript läuft auch mit
$tempfaenger = param('empfaenger');
einwandfrei.
Das Problem erhalte ich erst, wenn ich diese beiden kleinen Texte variabel gestalten will.
Gruß Poldi
Howdy Poldi,
Gleich am Anfang steht:
#!shebang line -wT
das -wT steht doch erst in der zweiten Zeile, in der ersten
steht nur -w. Wird die zweite trotzdem interpretiert ?
Ja das wird es:
»The #! line is always examined for switches as the line is
being parsed.« Perlrun Manpage
Das Skript läuft auch mit
$tempfaenger = param('empfaenger');
einwandfrei.
Sollte nicht, da -T beim Start beachtet wird. Oder aber, das Script
selbst fuehrt schon das Parsing durch...
Ja tut es:
sub parse_config_form_input {
my ($self, $name) = @_;
my $val = $self->strip_nonprint($self->cgi_object->param($name));
if ($name =~ /return_link_url|redirect$/) {
$val = $self->validate_url($val);
}
$self->{FormConfig}{$name} = $val;
unless ($self->{CFG}{emulate_matts_code}) {
$self->{Form}{$name} = $val;
if ( $self->{CFG}{"include_config_$name"} ) {
push @{ $self->{Field_Order} }, $name;
}
}
}
Das Problem erhalte ich erst, wenn ich diese beiden kleinen
Texte variabel gestalten will.
Dann extrahiere mal die POD-Doku
aus dem Script selbst. Als Text in der Shell oder als HTML Seite.
gruesse aus'm ruhrpott
jens mueller
Zu Jens:
# Kleine Modifizierung: Wenn du noch andere Variablen in $tDanke
# aufrufst, dann muessn diese auch mit *my* gekenzeichnet werden
my $tDanke = ".....";
my $title = $self->escape_html( $self->{FormConfig}{'title'} || "$tDanke");
Auf diese Art erhalte ich jetzt zwar keine Fehlermeldung mehr, aber ich weiß nicht, wie ich $tDanke einen dynamischen Wert zuweisen soll.
Ich erhalte vom rufenden Skript die Sprache (spr) übergeben.
Ich habe also in der Subroutine folgende Befehle eingefügt.
my $tsprache = param('spr');
my $tDanke;
if ($tsprache == "d")
{$tDanke = "Danke für die Nachricht"}
else
{$tDanke = "Merci pour votre message"};
Da bringt mir das System aber nur noch die nichtssagende Meldung
Application Error
An error has occurred in the program
See the web server's error log for details
Das Dumme ist nur, ich kann den Log (bei Netbeat) nicht anschauen.
Zu Jens und Struppi:
Ich sehe vollkommen ein, dass eine realistische Einschätzung der Fehlersituation ohne Vorlage des Script eigentlich nicht möglich ist.
Ich wollte allerdings der SELFHTML-Gemeinde nicht ein so langes Script zumuten (über 3500 Zeilen).
Falls sich doch jemand die Mühe machen wollte (mein Dank wird ihr/ihm gewiss sein), ich habe das Skript unter
beinahe<Minuszeichen>gratis<Punkt>de<Schrägstrich>feedback-test.txt
abgestellt (fragliche Stelle ab Zeile 3236).