Seltsames Verhalten von '' unter mod_perl
Frage
Ich habe Folgendes in einem Skript, das unter mod_perl ausgeführt wird
Logger::log("\$1 = '$1'");
Logger::log("\$ 1 = '$1'");
Logger::log("\\$1 = '$1'");
Dies gibt Folgendes in meine Protokolldatei aus:
logger: = ''
logger: $ 1 = ''
logger: \ = ''
$ 1 ist als null bekannt. Ist dies ein Fehler in mod_perl2 oder fehlt mir etwas anderes?
Lösung
Hast du versucht:
Logger::log(q!$1 = '! . $1 . q!'!);
Oder um Warnungen zu vermeiden:
Logger::log(q!$1 = '! . ( defined $1 ? $1 : '' ) . q!'!);
Die Idee hier ist, dass Q! ...! Interpoliert seinen Inhalt nicht, so dass Sie sicher wissen, dass der erste Teil der Zeichenfolge $ 1 = "ist. Wenn er noch nicht in der Ausgabe erscheint, wissen Sie, dass Logger :: Log () oder etwas, das es ruft, seine Argumente interpoliert , was wahrscheinlich nicht passieren sollte.
Oh, und wenn Sie ein moderneres Perl verwenden, kann das zweite Beispiel stattdessen ($ 1 // '') verwenden.
Andere Tipps
Wenn Sie sich Sorgen machen, Nulls zu fangen und versehentlich zu drucken, gibt es einen schnellen und einfachen Weg, so dass fast jeder Ihnen empfehlen wird: Fügen Sie Folgendes zu Ihrem Programm hinzu:
use strict;
use warnings;
Insbesondere das Problem scheint seltsam; Wenn ich es tue
my $foo = 'zip';
$foo =~ /(bal)/;
print "\$1: '$1'";
Ich bekomme
$1: ''
(und mit strikter und Warnungen den zusätzlichen Fehler
Use of uninitialized value in concatenation (.) or string at - line 5.
Natürlich können Sie verhindern, dass 1 US -Dollar jemals null ist, wenn Sie Ihren Regex testen:
if ($foo =~ /(pattern)/) {
# $1 is guaranteed to be ok here, if it matched
}
Also ja, es könnte sein, dass Ihr Logger 1 $ 1 als etwas anderes interpretiert. Versuchen Sie zwei weitere hinzuzufügen \\
; eine, um den $ zu entkommen, und eine andere, um einem zusätzlichen Backslash zu entkommen. So würde es so aussehen
print "\\\$1: '$1'";