Comment l'impression de Perl peut-elle ajouter une nouvelle ligne par défaut?

95

En Perl, la plupart de mes printdéclarations prennent la forme

print "hello." . "\n";

Existe-t-il un moyen efficace d'éviter de laisser traîner tous les "\ n" embêtants?

Je sais que je pourrais créer une nouvelle fonction telle que myprintcelle-ci ajoute automatiquement \ n, mais ce serait bien si je pouvais remplacer l'existant print.

Mike
la source
10
Si votre réponse inclut $ \, assurez-vous qu'elle est accompagnée d'une liste de mises en garde concernant la définition de variables globales avec effet invisible. Bien qu'il soit très intelligent et répond techniquement à la question, il est également très dangereux de le remettre sans réserve à un débutant.
Schwern
1
perldoc perlvardécrit la plupart des mises en garde, pourquoi les insister ici?
David M
5
@David, parce qu'un pirate informatique aléatoire va chercher les réponses ici au lieu de perldoc, s'en satisfait et ne saura même pas les mises en garde!
P Shved
2
C'est exactement le genre de raisonnement bizarre qui a fait que mon fer porte une étiquette d'avertissement indiquant que je ne devrais pas repasser les vêtements pendant que je les porte.
David M
8
Les outils de la vie réelle ont des limitations physiques qui sont raisonnablement bien comprises par les personnes qui ont vécu leur vie dans le monde physique. Les outils logiciels ne sont liés par aucune limitation de ce type et il n'y a pas de règles. Ils peuvent tout faire et se comportent souvent en dehors des attentes, en particulier pour les débutants qui n'ont pas encore appris les limites des attentes raisonnables.
Ether

Réponses:

99

Perl 6 a la sayfonction qui ajoute automatiquement \n.

Vous pouvez également utiliser sayen Perl 5.10 ou 5.12 si vous ajoutez

use feature qw(say);

au début de votre programme. Ou vous pouvez utiliser Modern :: Perl pour obtenir ceci et d'autres fonctionnalités.

Voir la fonctionnalité perldoc pour plus de détails.

Josh Kelley
la source
7
En fait, tout ce que vous avez à faire est use 5.012;ou use 5.010;pour l' obtenir si vous utilisez ces nouvelles perls.
Robert P
N'est-il pas sûr de supposer qu'à moins que Perl 6 ne soit spécifiquement mentionné, la question se réfère à Perl 5?
wobbily_col
35

Vous pouvez utiliser l' -loption dans l'en-tête she-bang:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Production:

hello
hello
jaypal singh
la source
3
Très agréable. Plus d'informations sur les perloptions, y compris ce qui -lest en cours, ici .
ruffin le
1
Parce que c'est un global, c'est une mauvaise pratique dans tout sauf les one-liners et le plus petit des scripts.
Schwern
24

Si Perl 5.10+ n'est pas une option, voici une approximation rapide et sale. Ce n'est pas exactement la même chose, puisque say a un peu de magie quand son premier argument est un handle, mais pour imprimer vers STDOUT:

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

say 'hello';
Eric Strom
la source
20

La façon dont vous rédigez votre déclaration d'impression est inutilement verbeuse. Il n'est pas nécessaire de séparer la nouvelle ligne dans sa propre chaîne. Cela suffit.

print "hello.\n";

Cette réalisation facilitera probablement votre codage en général.

En plus d'utiliser use feature "say"ou use 5.10.0ou use Modern::Perlpour obtenir la sayfonctionnalité intégrée, je vais pimp perl5i qui active par défaut de nombreuses fonctionnalités sensibles de Perl 5.

Schwern
la source
9

Peut-être voulez-vous changer votre séparateur d'enregistrement de sortie en saut de ligne avec:

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

Mise à jour: ma réponse parle de capacité plutôt que d'opportunité. Je ne considère pas l'ajout de "\ n" à la fin des lignes comme une corvée "embêtante", mais si quelqu'un veut vraiment les éviter, c'est une solution. Si je devais maintenir un peu de code qui utilise cette technique, je le refactoriserais probablement pronto.

David M
la source
6
Non, ne faites pas ça. Bien que techniquement une réponse correcte, l'utilisation d'une variable spéciale pour quelque chose d'aussi trivial que cela représente un fardeau de maintenance sur la route.
tsee
1
@tsee je suis entièrement d'accord, en fait. Comme j'ai modifié ma réponse pour l'indiquer, ma réponse décrit la capacité, même si l'on ne la recommanderait pas comme pratique générale.
David M
Le vrai danger vient du fait que tout le code ajoutera désormais des nouvelles lignes, même du code dans les modules d'autres personnes qui ne s'y attendaient pas. Imaginez un code de réseau qui aurait envoyé le message "helo\r\n"qui envoie maintenant "helo\r\n\n".
Chas. Owens
Bien sûr, vous pouvez toujours le rendre local pour éviter d'affecter d'autres codes, mais vous voulez tout de même rendre votre sous-programme un peu plus propre:local $\ = "\n";
redbmk
L'utilisation de l'indicateur de commande -lest idéale pour les one-liners de ligne de commande (voir perldoc.perl.org/perlrun.html#Command-Switches ). Je ne le recommanderais pas dans un programme plus vaste.
djd
4

Voici ce que j'ai trouvé sur https://perldoc.perl.org/perlvar.html :

$ \ Le séparateur d'enregistrement de sortie pour l'opérateur d'impression. Si elle est définie, cette valeur est imprimée après le dernier des arguments d'impression. La valeur par défaut est undef.

Vous ne pouvez pas appeler output_record_separator () sur un handle, uniquement en tant que méthode statique. Voir IO :: Handle.

Mnémonique: vous définissez $ \ au lieu d'ajouter "\ n" à la fin de l'impression. De plus, c'est comme $ /, mais c'est ce que vous récupérez de Perl.

exemple:

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

En Perl 6, il y a, la sayfonction

Michael Mrozek
la source
16
C'est aussi en
5.010
1

Si vous êtes bloqué avec la version antérieure à 5.10, les solutions fournies ci-dessus ne répliqueront pas complètement la sayfonction. Par exemple

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

Ne fonctionnera pas avec des invocations telles que

say for @arr;

ou

for (@arr) {
    say;
}

... parce que la fonction ci-dessus n'agit pas sur le $_like global implicite printet la sayfonction réelle .

Pour répliquer plus fidèlement le perl 5.10+, sayvous voulez cette fonction

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

Qui agit maintenant comme ça

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

L' sayintégré dans perl6 se comporte un peu différemment. L'appeler avec say @arrou @arr.sayne concaténera pas simplement les éléments du tableau, mais les affichera à la place séparés par le séparateur de liste. Pour répliquer cela dans perl5, vous feriez

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

$"est la variable de séparation de liste globale, ou si vous utilisez, English.pmalors est est$LIST_SEPARATOR

Il agira maintenant plus comme perl6, comme ça

say @arr;
# OUTPUT
# alpha beta gamma
#
Joshua
la source