Wie kann Perls Druck standardmäßig eine neue Zeile hinzufügen?

95

In Perl haben die meisten meiner printAussagen die Form

print "hello." . "\n";

Gibt es eine gute Möglichkeit, um zu vermeiden, dass all die nervigen "\ n" herumliegen?

Ich weiß, dass ich eine neue Funktion wie myprintdiese erstellen könnte, die automatisch angehängt wird \ n, aber es wäre schön, wenn ich die vorhandene überschreiben könnte print.

Mike
quelle
10
Wenn Ihre Antwort $ \ enthält, stellen Sie bitte sicher, dass sie eine Liste mit Einschränkungen zum Festlegen globaler Variablen mit unsichtbarer Wirkung enthält. Während es sehr klug und technisch die Frage beantwortet, ist es auch sehr gefährlich, einem Neuling unqualifiziert zu übergeben.
Schwern
1
perldoc perlvarbeschreibt die meisten Vorbehalte, warum sie hier näher erläutern?
David M
5
@ David, weil ein zufälliger Hacker die Antworten hier anstelle von Perldoc googelt, mit ihnen zufrieden ist und nicht einmal über die Vorbehalte Bescheid weiß!
P Shved
2
Das ist genau die Art bizarrer Argumentation, die dazu geführt hat, dass mein Bügeleisen ein Warnschild hat, dass ich keine Kleidung bügeln sollte, während ich sie trage.
David M
8
Werkzeuge aus dem wirklichen Leben haben physische Einschränkungen, die von Menschen, die ihr Leben in der physischen Welt gelebt haben, einigermaßen gut verstanden werden. Software-Tools unterliegen keinen solchen Einschränkungen, und es gibt keine Regeln. Sie können alles und verhalten sich häufig außerhalb der Erwartungen, insbesondere für Anfänger, die die Grenzen vernünftiger Erwartungen noch nicht kennen.
Ether

Antworten:

98

Perl 6 hat die sayFunktion, die automatisch angehängt wird \n.

Sie können auch sayPerl 5.10 oder 5.12 verwenden, wenn Sie hinzufügen

use feature qw(say);

zum Anfang Ihres Programms. Oder Sie können Modern :: Perl verwenden , um diese und andere Funktionen zu erhalten.

Weitere Informationen finden Sie unter Perldoc-Funktion .

Josh Kelley
quelle
7
In der Tat ist alles, was Sie tun müssen, use 5.012;oder es use 5.010;zu bekommen, wenn Sie diese neueren perls ausführen .
Robert P
Ist es nicht sicher anzunehmen, dass sich die Frage auf Perl 5 bezieht, wenn Perl 6 nicht ausdrücklich erwähnt wird?
Wobbily_col
35

Sie können die -lOption in der She-Bang-Kopfzeile verwenden:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Ausgabe:

hello
hello
jaypal singh
quelle
3
Sehr schön. Weitere perlInformationen zu Optionen, einschließlich der aktuellen -lAktivitäten, finden Sie hier .
Ruffin
1
Da es sich um ein globales System handelt, ist dies eine schlechte Praxis für alles andere als Einzeiler und das kleinste Skript.
Schwern
24

Wenn Perl 5.10+ keine Option ist, finden Sie hier eine schnelle und schmutzige Annäherung. Es ist nicht genau das gleiche, da say etwas Magie hat, wenn sein erstes Argument ein Handle ist, aber zum Drucken an STDOUT:

sub say {print @_, "\n"}

say 'hello';
Eric Strom
quelle
20

Die Art und Weise, wie Sie Ihre Druckanweisung schreiben, ist unnötig ausführlich. Es ist nicht erforderlich, die Newline in eine eigene Zeichenfolge zu unterteilen. Das ist ausreichend.

print "hello.\n";

Diese Erkenntnis wird wahrscheinlich Ihre Codierung im Allgemeinen erleichtern.

Zusätzlich zur Verwendung use feature "say"oder use 5.10.0oder use Modern::Perlzum Erhalt der integrierten sayFunktion werde ich perl5i pimpen, wodurch standardmäßig viele sinnvolle fehlende Perl 5-Funktionen aktiviert werden.

Schwern
quelle
9

Vielleicht möchten Sie Ihr Trennzeichen für Ausgabedatensätze in Zeilenvorschub ändern mit:

local $\ = "\n";

$ perl -e 'print q{hello};print q{goodbye}' | od -c
0000000    h   e   l   l   o   g   o   o   d   b   y   e                
0000014
$ perl -e '$\ = qq{\n}; print q{hello};print q{goodbye}' | od -c
0000000    h   e   l   l   o  \n   g   o   o   d   b   y   e  \n        
0000016

Update: Meine Antwort spricht eher für Fähigkeiten als für Ratsamkeit. Ich halte das Hinzufügen von "\ n" am Ende von Zeilen nicht für eine "lästige" Aufgabe, aber wenn jemand sie wirklich vermeiden möchte, ist dies eine Möglichkeit. Wenn ich ein bisschen Code pflegen müsste, der diese Technik verwendet, würde ich ihn wahrscheinlich sofort umgestalten.

David M.
quelle
6
Nein, bitte tu das nicht. Obwohl technisch eine korrekte Antwort ist, ist die Verwendung einer speziellen Variablen für etwas so Triviales wie dieses eine Wartungslast in der Zukunft.
Siehe
1
@tsee Ich stimme eigentlich völlig zu. Während ich meine Antwort bearbeitete, um anzuzeigen, beschreibt meine Antwort die Fähigkeit, auch wenn man sie nicht als allgemeine Praxis empfehlen würde.
David M
Die wirkliche Gefahr besteht in der Tatsache, dass der gesamte Code jetzt Zeilenumbrüche hinzufügt, sogar Code in den Modulen anderer Personen, die dies nicht erwartet haben. Stellen Sie sich vor Netzwerk - Code, der die Nachricht gesendet hätte , "helo\r\n"die jetzt sendet "helo\r\n\n".
Chas. Owens
Natürlich können Sie es immer lokal machen, um die Beeinflussung anderer Codes zu vermeiden, möchten aber dennoch, dass Ihre Unterroutine ein wenig sauberer local $\ = "\n";
aussieht
Die Verwendung des Befehlsflags -leignet sich hervorragend für Befehlszeilen-Einzeiler (siehe perldoc.perl.org/perlrun.html#Command-Switches ). Ich würde es in keinem größeren Programm empfehlen.
DJD
4

Folgendes habe ich unter https://perldoc.perl.org/perlvar.html gefunden :

$ \ Das Trennzeichen für den Ausgabedatensatz für den Druckoperator. Wenn definiert, wird dieser Wert nach dem letzten Argument des Drucks gedruckt. Standard ist undef.

Sie können output_record_separator () für ein Handle nur als statische Methode aufrufen. Siehe IO :: Handle.

Mnemonik: Sie setzen $ \, anstatt am Ende des Drucks "\ n" hinzuzufügen. Es ist auch wie $ /, aber es ist das, was Sie von Perl "zurück" bekommen.

Beispiel:

$\ = "\n";
print "a newline will be appended to the end of this line automatically";
Hofergabriel
quelle
3

In Perl 6 gibt es die sayFunktion

Michael Mrozek
quelle
16
Es ist auch in 5.010 :-)
nc3b
1

Wenn Sie mit Pre-5.10 nicht weiterkommen, wird die sayFunktion durch die oben angegebenen Lösungen nicht vollständig repliziert . Beispielsweise

sub say { print @_, "\n"; }

Funktioniert nicht mit Aufrufen wie

say for @arr;

oder

for (@arr) {
    say;
}

... weil die obige Funktion nicht auf das implizite globale $_Like printund die reale sayFunktion einwirkt.

Um das Perl 5.10+ genauer zu replizieren, möchten saySie diese Funktion

sub say {
    if (@_) { print @_, "\n"; }
    else { print $_, "\n"; }
}

Was jetzt so wirkt

my @arr = qw( alpha beta gamma );
say @arr;
# OUTPUT
# alphabetagamma
#
say for @arr;
# OUTPUT
# alpha
# beta
# gamma
#

Das sayeingebaute perl6 verhält sich etwas anders. Wenn Sie es mit say @arroder @arr.sayohne Verkettung der Array-Elemente aufrufen, werden sie stattdessen getrennt mit dem Listentrennzeichen gedruckt. Um dies in perl5 zu replizieren, würden Sie dies tun

sub say {
    if (@_) { print join($", @_) . "\n"; }
    else { print $_ . "\n"; }
}

$"ist die globale Listentrennvariable, oder wenn Sie verwenden, English.pmist es$LIST_SEPARATOR

Es wird sich jetzt eher wie perl6 verhalten

say @arr;
# OUTPUT
# alpha beta gamma
#
Joshua
quelle