Come può la stampa di Perl aggiungere una nuova riga di default?


95

In Perl la maggior parte delle mie printaffermazioni assume la forma

print "hello." . "\n";

C'è un modo carino per evitare di tenere in giro tutte le "\ n" fastidiose "\ n"?

So che potrei creare una nuova funzione come quella myprintche aggiunge automaticamente \ n, ma sarebbe carino se potessi sovrascrivere quella esistente print.


10
Se la tua risposta include $ \ assicurati che venga fornito con un elenco di avvertenze sull'impostazione di variabili globali con effetto invisibile. Sebbene sia molto intelligente e tecnicamente risponde alla domanda, è anche molto pericoloso da mano non qualificato a un principiante.
Schwern

1
perldoc perlvardescrive la maggior parte degli avvertimenti, perché dilungarli qui?
David M

5
@David, perché qualche hacker casuale cercherà qui le risposte su Google invece di perldoc, si accontenterà e non saprà nemmeno degli avvertimenti!
P Shved

2
Questo è esattamente il tipo di ragionamento bizzarro che ha portato il mio ferro ad avere un'etichetta di avvertimento che non dovrei stirare i vestiti mentre li indosso.
David M

8
Gli strumenti della vita reale hanno limitazioni fisiche che sono ragionevolmente ben comprese dalle persone che hanno vissuto la loro vita nel mondo fisico. Gli strumenti software non sono vincolati da tali limitazioni e non ci sono regole. Possono fare qualsiasi cosa e spesso si comportano al di fuori delle aspettative, specialmente per i principianti che non hanno ancora imparato i confini delle aspettative ragionevoli.
Ether

Risposte:


99

Perl 6 ha la sayfunzione che aggiunge automaticamente \n.

Puoi anche usare sayin Perl 5.10 o 5.12 se aggiungi

use feature qw(say);

all'inizio del tuo programma. Oppure puoi usare Modern :: Perl per ottenere questa e altre funzionalità.

Vedi funzionalità perldoc per maggiori dettagli.


7
In effetti, tutto ciò che devi fare è use 5.012;o use 5.010;ottenerlo se stai eseguendo quelle più recenti perl.
Robert P

Non è lecito ritenere che, a meno che Perl 6 non sia specificamente menzionato, la domanda si riferisce a Perl 5?
wobbily_col

35

Puoi utilizzare l' -lopzione nell'intestazione She-Bang:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Produzione:

hello
hello

3
Molto bella. Maggiori informazioni sulle perlopzioni, incluso ciò che -lsta facendo, qui .
ruffin

1
Poiché è globale, questa è una cattiva pratica in tutto tranne che nelle battute e nel più piccolo degli script.
Schwern

24

Se Perl 5.10+ non è un'opzione, ecco una rapida e sporca approssimazione. Non è esattamente la stessa cosa, dal momento che say ha un po 'di magia quando il suo primo arg è un handle, ma per la stampa su STDOUT:

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

say 'hello';

20

Il modo in cui scrivi la tua dichiarazione di stampa è inutilmente prolisso. Non è necessario separare la nuova riga nella propria stringa. Questo è sufficiente.

print "hello.\n";

Questa consapevolezza probabilmente renderà la tua codifica più semplice in generale.

Oltre a usare use feature "say"o use 5.10.0o use Modern::Perlper ottenere la funzionalità incorporata say, ho intenzione di pimp perl5i che attiva molte funzionalità Perl 5 mancanti per impostazione predefinita.


9

Forse vuoi cambiare il separatore del record di output in avanzamento riga con:

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

Aggiornamento: la mia risposta parla di capacità piuttosto che di opportunità. Non considero l'aggiunta di "\ n" alla fine delle righe un compito "fastidioso", ma se qualcuno vuole davvero evitarli, questo è un modo. Se dovessi mantenere un po 'di codice che utilizza questa tecnica, probabilmente lo rifatterò subito.


6
No, per favore non farlo. Sebbene tecnicamente sia una risposta corretta, usare una variabile speciale per qualcosa di così banale come questo è un onere di manutenzione lungo la strada.
vedi

1
@tsee Sono completamente d'accordo, in realtà. Mentre ho modificato la mia risposta per indicare, la mia risposta descrive la capacità, anche se non la consiglierei come pratica generale.
David M

Il vero pericolo deriva dal fatto che tutto il codice ora aggiungerà nuove righe, anche il codice nei moduli di altre persone che non se lo aspettavano. Immagina il codice di rete che avrebbe inviato il messaggio "helo\r\n"che ora invia "helo\r\n\n".
Chas. Owens

Ovviamente potresti sempre renderlo locale per evitare di influenzare altro codice, ma vuoi comunque rendere la tua subroutine un po 'più pulita:local $\ = "\n";
redbmk

L'uso del flag di comando -lè ottimo per i one-liner della riga di comando (vedere perldoc.perl.org/perlrun.html#Command-Switches ). Non lo consiglierei in nessun programma più grande.
djd

4

Ecco cosa ho trovato su https://perldoc.perl.org/perlvar.html :

$ \ Il separatore del record di output per l'operatore di stampa. Se definito, questo valore viene stampato dopo l'ultimo degli argomenti di print. L'impostazione predefinita è undef.

Non è possibile chiamare output_record_separator () su un handle, solo come metodo statico. Vedere IO :: Handle.

Mnemonico: imposti $ \ invece di aggiungere "\ n" alla fine della stampa. Inoltre, è proprio come $ /, ma è quello che ottieni "indietro" da Perl.

esempio:

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


1

Se sei bloccato con la versione precedente alla 5.10, le soluzioni fornite sopra non replicheranno completamente la sayfunzione. Per esempio

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

Non funzionerà con invocazioni come

say for @arr;

o

for (@arr) {
    say;
}

... perché la funzione di cui sopra non agisce sul $_like globale implicito printe sulla sayfunzione reale .

Per replicare più fedelmente il perl 5.10+ saysi desidera questa funzione

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

Che ora si comporta in questo modo

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

Il saybuiltin in perl6 si comporta in modo leggermente diverso. Invocarlo con say @arro @arr.saynon si limiterà a concatenare gli elementi dell'array, ma li stampa invece separati dal separatore di elenco. Per replicare questo in perl5 dovresti farlo

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

$"è la variabile separatore di elenco globale o, se stai usando, English.pmè$LIST_SEPARATOR

Ora si comporterà più come perl6, in questo modo

say @arr;
# OUTPUT
# alpha beta gamma
#
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.