¿Cómo puede la impresión de Perl agregar una nueva línea por defecto?

95

En Perl, la mayoría de mis printdeclaraciones toman la forma

print "hello." . "\n";

¿Existe una buena manera de evitar tener todos los molestos "\ n" por ahí?

Sé que podría crear una nueva función como la myprintque agrega automáticamente \ n, pero sería bueno si pudiera anular la existente print.

Miguel
fuente
10
Si su respuesta incluye $ \, asegúrese de que incluya una lista de advertencias sobre la configuración de variables globales con efecto invisible. Si bien es muy inteligente y técnicamente responde a la pregunta, también es muy peligroso entregarlo sin calificación a un novato.
Schwern
1
perldoc perlvardescribe la mayoría de las advertencias, ¿por qué insistir en ellas aquí?
David M
5
@David, porque algún hacker aleatorio buscará en Google las respuestas aquí en lugar de perldoc, quedará satisfecho con ellas y ni siquiera sabrá acerca de las advertencias.
P Shved
2
Ese es exactamente el tipo de razonamiento extraño que ha resultado en que mi plancha tenga una etiqueta de advertencia de que no debo planchar la ropa mientras la estoy usando.
David M
8
Las herramientas de la vida real tienen limitaciones físicas que las personas que han vivido sus vidas en el mundo físico las entienden razonablemente bien. Las herramientas de software no están sujetas a tales limitaciones y no existen reglas. Pueden hacer cualquier cosa y, con frecuencia, se comportan fuera de las expectativas, especialmente para los principiantes que aún no han aprendido los límites de las expectativas razonables.
Ether

Respuestas:

99

Perl 6 tiene la sayfunción que se agrega automáticamente \n.

También puede usar sayen Perl 5.10 o 5.12 si agrega

use feature qw(say);

al comienzo de su programa. O puede usar Modern :: Perl para obtener esta y otras características.

Consulte la función de perldoc para obtener más detalles.

Josh Kelley
fuente
7
De hecho, todo lo que tiene que hacer es use 5.012;o use 5.010;conseguirlo si se está ejecutando esos nuevos perls.
Robert P
¿No es seguro asumir que, a menos que se mencione específicamente Perl 6, la pregunta se refiere a Perl 5?
wobbily_col
35

Puede usar la -lopción en el encabezado she-bang:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Salida:

hello
hello
Jaypal Singh
fuente
3
Muy agradable. Más sobre perlopciones, incluido lo que -lestá haciendo, aquí .
Ruffin
1
Debido a que es global, esta es una mala práctica en cualquier cosa menos en frases sencillas y en los guiones más pequeños.
Schwern
24

Si Perl 5.10+ no es una opción, aquí hay una aproximación rápida y sucia. No es exactamente lo mismo, ya que say tiene algo de magia cuando su primer argumento es un identificador, pero para imprimir en STDOUT:

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

say 'hello';
Eric Strom
fuente
20

La forma en que está escribiendo su declaración impresa es innecesariamente detallada. No es necesario separar la nueva línea en su propia cadena. Esto es suficiente.

print "hello.\n";

Esta realización probablemente facilitará la codificación en general.

Además de usar use feature "say"o use 5.10.0o use Modern::Perlpara obtener la sayfunción incorporada, voy a utilizar perl5i, que activa muchas funciones sensibles de Perl 5 que faltan por defecto.

Schwern
fuente
9

Tal vez desee cambiar su separador de registros de salida para avanzar de línea 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

Actualización: mi respuesta habla de capacidad más que de conveniencia. No considero que agregar "\ n" al final de las líneas sea una tarea "molesta", pero si alguien realmente quiere evitarlos, esta es una forma. Si tuviera que mantener un poco de código que usa esta técnica, probablemente lo refactorizaría pronto.

David M
fuente
6
No, por favor no hagas eso. Si bien técnicamente es una respuesta correcta, usar una variable especial para algo tan trivial como esto es una carga de mantenimiento en el futuro.
Ver
1
@tsee estoy completamente de acuerdo, en realidad. Como edité mi respuesta para indicar, mi respuesta describe la capacidad, incluso si uno no la recomendaría como práctica general.
David M
El peligro real proviene del hecho de que todo el código ahora agregará nuevas líneas, incluso el código en los módulos de otras personas que no lo esperaban. Imagínese el código de red que habría enviado el mensaje "helo\r\n"que ahora envía "helo\r\n\n".
Chas. Owens
Por supuesto, siempre puede hacerlo local para evitar afectar a otro código, pero aún así desea que su subrutina se vea un poco más limpia:local $\ = "\n";
redbmk
El uso de la bandera de comando -les excelente para las líneas de comandos de una sola línea (consulte perldoc.perl.org/perlrun.html#Command-Switches ). No lo recomendaría en ningún programa más grande.
djd
4

Esto es lo que encontré en https://perldoc.perl.org/perlvar.html :

$ \ El separador de registros de salida para el operador de impresión. Si se define, este valor se imprime después del último de los argumentos de print. El valor predeterminado es indefinido.

No puede llamar a output_record_separator () en un identificador, solo como un método estático. Consulte IO :: Handle.

Mnemotécnico: establece $ \ en lugar de agregar "\ n" al final de la impresión. Además, es como $ /, pero es lo que "recuperas" de Perl.

ejemplo:

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

En Perl 6 existe, la sayfunción

Michael Mrozek
fuente
16
También está en 5.010 :-)
nc3b
1

Si está atascado con la versión anterior a 5.10, las soluciones proporcionadas anteriormente no replicarán completamente la sayfunción. Por ejemplo

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

No funcionará con invocaciones como

say for @arr;

o

for (@arr) {
    say;
}

... porque la función anterior no actúa sobre el me $_gusta global implícito printy la sayfunción real .

Para replicar más de cerca el perl 5.10+ say, desea esta función

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

Que ahora actúa así

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

La función sayincorporada en perl6 se comporta un poco diferente. Invocándolo consay @arr o @arr.sayno solo concatenará los elementos de la matriz, sino que los imprimirá separados con el separador de lista. Para replicar esto en perl5 deberías hacer esto

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

$"es la variable de separador de lista global, o si está usando English.pmentonces es es$LIST_SEPARATOR

Ahora actuará más como perl6, así

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