Les traits cachés de Perl?

quelles sont les caractéristiques du langage Perl vraiment utiles mais ésotériques que vous avez pu utiliser pour faire un travail utile?

lignes directrices:

  • Essayer de limiter les réponses à la Perl de base et de ne pas CPAN
  • Veuillez donner un exemple et une courte description

les traits cachés également trouvés dans les traits cachés d'autres langues:

(tous de réponse de Corion )

  • C
    • Duff "Dispositif de 1519170920"
    • portabilité et Standardness
  • C#
    • guillemets pour listes et chaînes délimitées par des espaces
    • Aliasable espaces de noms
  • Java
    • Initaliseurs Statiques
  • JavaScript
    • les fonctions sont des citoyens de première classe
    • Bloc de portée et à la fermeture de l'1519170920"
    • l'Appel de méthodes accesseurs et indirectement par l'intermédiaire d'une variable
  • Ruby
    • Définir les méthodes à l'aide de code
  • PHP
      "1519160920 de l'omniprésence de la documentation en ligne
    • méthodes Magiques
    • références symboliques
  • Python
    • changement de valeur d'une ligne
    • capacité de remplacer même les fonctions de base avec votre propre fonctionnalité

Autres Fonctions Cachées:

"1519110920 les Opérateurs":

citant des constructions:

syntaxe et noms:

des Modules, des Pragmas, et les options de ligne de commande:

"1519110920 des Variables":

boucles et régulation de débit:

expressions régulières:

autres caractéristiques:

d'Autres astuces, et des méta-réponses:


Voir Aussi:

143
demandé sur Adam Bellaire 2008-10-02 15:49:22
la source

30 ответов

l'opérateur flip-flop est utile pour sauter la première itération en boucle à travers les enregistrements (habituellement des lignes) retournés par une poignée de fichier, sans utiliser de variable flag:

while(<$fh>)
{
  next if 1..1; # skip first record
  ...
}

Exécuter perldoc perlop et la recherche pour "flip-flop" pour plus d'informations et d'exemples.

54
répondu John Siracusa 2008-10-02 16:41:44
la source

il y a de nombreuses caractéristiques non évidentes dans Perl.

Par exemple, saviez-vous qu'il peut y avoir un espace après un signe?

 $ perl -wle 'my $x = 3; print $ x'
 3

ou que vous pouvez donner des noms subs numériques si vous utilisez des références symboliques?

$ perl -lwe '*4 = sub { print "yes" }; 4->()' 
yes

il y a aussi le quasi opérateur "bool", qui renvoie 1 pour les expressions vraies et la chaîne vide pour false:

$ perl -wle 'print !!4'
1
$ perl -wle 'print !!"0 but true"'
1
$ perl -wle 'print !!0'
(empty line)

autre chose intéressante: avec use overload vous pouvez surcharger la chaîne de lettres et les nombres (et les faire BigInts par exemple).

beaucoup de ces choses sont en fait documentées quelque part, ou découlent logiquement des caractéristiques documentées, mais néanmoins certaines ne sont pas très bien connues.

mise à Jour : un Autre joli. Au-dessous des constructions de citation q{...} ont été mentionnés, mais saviez-vous que vous pouvez utiliser des lettres comme délimiteurs?

$ perl -Mstrict  -wle 'print q bJet another perl hacker.b'
Jet another perl hacker.

de même, vous pouvez écrire des expressions régulières:

m xabcx
# same as m/abc/
47
répondu moritz 2009-08-24 01:39:45
la source

Ajouter le support pour les fichiers compressés via magie ARGV :

s{ 
    ^            # make sure to get whole filename
    ( 
      [^'] +     # at least one non-quote
      \.         # extension dot
      (?:        # now either suffix
          gz
        | Z 
       )
    )
    \z           # through the end
}{gzcat '' |}xs for @ARGV;

(devis d'environ $_ nécessaires pour traiter les noms de fichiers avec des métacharactères shell)

maintenant la fonctionnalité <> va décompresser tous les fichiers @ARGV qui se terminent par".gz" ou ".Z":

while (<>) {
    print;
}
46
répondu timkay 2010-10-31 01:34:06
la source

une de mes caractéristiques préférées de Perl est d'utiliser l'opérateur booléen || pour sélectionner entre un ensemble de choix.

 $x = $a || $b;

 # $x = $a, if $a is true.
 # $x = $b, otherwise

cela signifie qu'on peut écrire:

 $x = $a || $b || $c || 0;

pour prendre la première vraie valeur de $a , $b , et $c , ou une valeur par défaut de 0 autrement.

dans Perl 5.10, Il ya aussi l'opérateur // , qui renvoie le côté gauche si elle est défini, et le côté droit autrement. La commande suivante sélectionne la première valeur définie de $a , $b , $c , ou 0 autrement:

$x = $a // $b // $c // 0;

ceux-ci peuvent également être utilisés avec leurs formes courtes mains, qui sont très utiles pour fournir par défaut:

$x ||= 0;   # If $x was false, it now has a value of 0.

$x //= 0;   # If $x was undefined, it now has a value of zero.

Cheerio,

Paul

40
répondu pjf 2010-11-11 18:09:37
la source

les opérateurs ++ et unary - ne travaillent pas seulement sur les nombres, mais aussi sur les chaînes.

my $_ = "a"
print -$_

imprime -un

print ++$_

imprime b

$_ = 'z'
print ++$_

imprime aa

39
répondu Leon Timmermans 2008-10-02 16:26:31
la source

comme Perl a presque toutes les parties "ésotériques" des autres listes, je vais vous dire la seule chose que Perl ne peut pas:

la seule chose que Perl ne peut pas faire est d'avoir des URLs arbitraires dans votre code, parce que l'opérateur // est utilisé pour les expressions régulières.

juste au cas où ce n'était pas évident pour vous ce que les caractéristiques offre Perl, voici une liste sélective des entrées peut-être pas totalement évident:

Duff "Dispositif de 1519220920" - en Perl

Portabilité et Standardness - Il y a probablement plus d'ordinateurs avec Perl qu'avec un compilateur C

a file/path manipulation class - fichier:: trouver des travaux sur encore plus de systèmes d'exploitation que .Net ne le fait

Guillemets pour listes délimitées par des espaces et chaînes de caractères - Perl vous permet de choisir des guillemets presque arbitraires pour vos délimiteurs de listes et de chaînes de caractères

Aliasable espaces de noms - Perl a ces par glob affectations:

*My::Namespace:: = \%Your::Namespace

initialisateurs statiques - Perl peut exécuter du code dans presque toutes les phases de la compilation et de l'objet l'instanciation, de BEGIN (code parse) CHECK (d'après le code de l'analyser) pour import (module d'importation) new (instanciation d'objet) DESTROY (destruction des objets) END (la sortie du programme)

les fonctions sont des citoyens de première classe - comme en Perl

Bloc de portée et à la fermeture de l'1519220920" - Perl a deux

méthodes D'appel et accesseurs indirectement à travers une variable - Perl fait aussi cela:

my $method = 'foo';
my $obj = My::Class->new();
$obj->$method( 'baz' ); # calls $obj->foo( 'baz' )

Définir les méthodes à l'aide de code - Perl permet que trop :

*foo = sub { print "Hello world" };

Pervasive online documentation - la documentation Perl est en ligne et probablement aussi sur votre système

méthodes Magiques qui est appelé chaque fois que vous appelez une fonction "non existante" - Perl implémente la fonction AUTOLOAD

références symboliques - vous êtes bien avisé de ne pas vous en approcher. ils mangeront vos enfants. mais bien sûr, Perl vous permet d'offrir vos enfants à des démons assoiffés de sang.

changement de valeur d'une ligne - Perl permet l'attribution de liste

possibilité de remplacer même les fonctions de base avec votre propre fonctionnalité

use subs 'unlink'; 
sub unlink { print 'No.' }

ou

BEGIN{
    *CORE::GLOBAL::unlink = sub {print 'no'}
};

unlink($_) for @ARGV
36
répondu Corion 2017-05-23 15:10:36
la source

Autovivification . Autant que je sache aucune autre langue il a .

35
répondu J.J. 2008-10-02 17:48:56
la source

il est simple de citer presque n'importe quelle sorte de chaîne étrange dans Perl.

my $url = q{http://my.url.com/any/arbitrary/path/in/the/url.html};

en fait, les différents mécanismes de citation en Perl sont assez intéressants. Les mécanismes de citation Perl regex-like vous permettent de citer n'importe quoi, en spécifiant les délimiteurs. Vous pouvez utiliser presque n'importe quel caractère spécial comme #, /, ou ouvrir/fermer des personnages comme (), [], ou {}. Exemples:

my $var  = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);

citant des mécanismes:

Q: littéral devis; seul caractère qui doit être échappé est le caractère de fin. qq: une citation interprétée; traite les variables et les caractères d'échappement. Idéal pour les cordes que vous devez citer:

my $var4 = qq{This "$mechanism" is broken.  Please inform "$user" at "$email" about it.};

qx: fonctionne comme qq, mais l'exécute ensuite comme une commande système, non interactivement. Renvoie tout le texte généré par le standard. (La Redirection, si elle est supportée dans le système D'exploitation, sort aussi) aussi fait avec des guillemets (le caractère`).

my $output  = qx{type "$path"};      # get just the output
my $moreout = qx{type "$path" 2>&1}; # get stuff on stderr too

qr: interprète comme qq, mais le compile ensuite comme une expression régulière. Fonctionne avec les différentes options sur les regex. Vous pouvez maintenant passer le regex comme une variable:

sub MyRegexCheck {
    my ($string, $regex) = @_;
    if ($string)
    {
       return ($string =~ $regex);
    }
    return; # returns 'null' or 'empty' in every context
}

my $regex = qr{http://[\w]\.com/([\w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);

qw : Un très, très utile citation de l'opérateur. Transforme un ensemble Cité de mots séparés par des espaces en une liste. Idéal pour remplir des données dans un test unitaire.


   my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
   my @badwords = qw(WORD1 word2 word3 word4);
   my @numbers = qw(one two three four 5 six seven); # works with numbers too
   my @list = ('string with space', qw(eight nine), "a $var"); # works in other lists
   my $arrayref = [ qw(and it works in arrays too) ]; 

ils sont parfaits pour les utiliser quand ça rend les choses plus claires. Pour qx, qq et q, J'utilise probablement les opérateurs {}. L'habitude la plus commune des gens utilisant qw est généralement l'opérateur (), mais parfois vous voyez aussi qw//.

31
répondu Robert P 2009-08-24 01:47:27
la source

pas vraiment caché, mais beaucoup de programmeurs Perl tous les jours ne savent pas sur CPAN . Cela s'applique particulièrement aux personnes qui ne sont pas programmeurs à temps plein ou ne programment pas en Perl à temps plein.

27
répondu mpeters 2009-03-19 02:26:31
la source

l'instruction " for "peut être utilisée de la même manière que" with "est utilisé en Pascal:

for ($item)
{
    s/&‎nbsp;/ /g;
    s/<.*?>/ /g;
    $_ = join(" ", split(" ", $_));
}

vous pouvez appliquer une séquence d'opérations s///, etc. à la même variable sans avoir à répéter le nom de la variable.

NOTE: l'espace de non-rupture ci-dessus ( ) y a caché Unicode pour contourner le Markdown. Ne pas copier coller :)

27
répondu timkay 2009-08-24 01:43:58
la source

l'opérateur quoteword est une de mes choses préférées. Comparer:

my @list = ('abc', 'def', 'ghi', 'jkl');

et

my @list = qw(abc def ghi jkl);

beaucoup moins de bruit, plus facile à regarder. Une autre chose vraiment agréable à propos de Perl, qu'on manque vraiment en écrivant SQL, est qu'une virgule traînante est légale:

print 1, 2, 3, ;

cela semble étrange, mais pas si vous indentez le code d'une autre façon:

print
    results_of_foo(),
    results_of_xyzzy(),
    results_of_quux(),
    ;

ajoutant un argument supplémentaire à la l'appel de fonction ne vous oblige pas à jouer avec les virgules sur les lignes précédentes ou de fuite. Le changement de ligne individuelle n'a aucune incidence sur les lignes environnantes.

cela rend très agréable de travailler avec des fonctions variadiques. C'est peut-être L'une des caractéristiques les moins bien notées de Perl.

26
répondu dland 2008-10-02 20:54:51
la source

la capacité à analyser des données directement collées dans un bloc ". Pas besoin d'enregistrer un fichier de test à être ouvert dans le programme ou similaire. Par exemple:

my @lines = <DATA>;
for (@lines) {
    print if /bad/;
}

__DATA__
some good data
some bad data
more good data 
more good data 
26
répondu 2 revs, 2 users 93%allan 2009-08-24 01:42:09
la source

Nouveau Bloc D'Activités

je dirais que la capacité d'étendre le langage, en créant des opérations de pseudo-bloc en est une.

  1. vous déclarez le prototype pour un sous-marin indiquant qu'il prend un code référence en premier:

    sub do_stuff_with_a_hash (&\%) {
        my ( $block_of_code, $hash_ref ) = @_;
        while ( my ( $k, $v ) = each %$hash_ref ) { 
            $block_of_code->( $k, $v );
        }
    }
    
  2. Vous pouvez ensuite appeler dans le corps comme

    use Data::Dumper;
    
    do_stuff_with_a_hash {
        local $Data::Dumper::Terse = 1;
        my ( $k, $v ) = @_;
        say qq(Hey, the key   is "$k"!);
        say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
    
    } %stuff_for
    ;
    

( Data::Dumper::Dumper est un autre bijou semi-caché.) Remarquez que vous n'avez pas besoin du mot-clé sub devant le bloc, ou de la virgule devant le hachage. Il finit par ressembler à: map { } @list

Source "Filtres De La 1519160920"

aussi, il y a des filtres source. Où Perl vous passera le code pour que vous puissiez le manipuler. Ceci, et les opérations de bloc, sont à peu près du genre ne pas-essayer-ceci-à-la-maison des choses.

j'ai fait quelques choses soignées avec les filtres source, par exemple, comme la création d'un langage très simple pour vérifier le temps, permettant des filtres Perl courts pour une prise de décision:

perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';

Lib::TL scannerait les "variables" et les constantes, les créerait et les remplacerait si nécessaire.

encore une fois, les filtres source peuvent être désordonnés, mais sont puissants. Mais ils peuvent brouiller quelque chose de terrible pour les débogueurs--et même les avertissements peuvent être imprimés avec les mauvais numéros de ligne. J'ai arrêté D'utiliser le commutateur de Damian parce que le débogueur perdrait toute capacité à me dire où j'étais vraiment. Mais j'ai découvert que vous pouvez minimiser les dégâts en modifiant de petites sections de code, en les gardant sur la même ligne.

Hameçons De Signalisation

c'est souvent assez fait, mais ce n'est pas si évident. Voici un tueur à gages qui s'en remet à l'ancien.

my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}       
    = sub { say q(Hey! I'm DYIN' over here!); goto &$old_die_handler; }
    ;

ça veut dire quand un autre module du code veut mourir, il doit venir à vous (à moins que quelqu'un d'autre ne fasse une réécriture destructive sur $SIG{__DIE__} ). Et vous pouvez être informé que quelqu'un fait quelque chose est une erreur.

bien sûr, pour assez de choses vous pouvez juste utiliser un bloc END { } , si tout ce que vous voulez faire est de nettoyer.

overload::constant

vous pouvez inspecter les littérales d'un certain type dans les paquets qui incluent votre module. Pour exemple, si vous l'utilisez dans votre import sub:

overload::constant 
    integer => sub { 
        my $lit = shift;
        return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit 
    };

signifie que chaque entier supérieur à 2 milliards dans les paquets appelant sera changé en un objet Math::BigInt . (Voir surcharge:: constante ).

Regroupées Les Littéraux Entiers

tant qu'on y est. Perl permet de briser un grand nombre dans les groupes de trois chiffres, et encore obtenir un analysée entier. Note 2_000_000_000 ci-dessus pour 2 milliards.

24
répondu Axeman 2009-08-24 01:53:26
la source

binaire "x" est le opérateur de répétition :

print '-' x 80;     # print row of dashes

il fonctionne aussi avec des listes:

print for (1, 4, 9) x 3; # print 149149149
24
répondu Bruno De Fraine 2010-03-19 20:01:19
la source

vérification de la contamination. Avec la vérification de l'altération activée, perl va mourir (ou Avertir, avec -t ) si vous essayez de passer des données altérées (en gros, des données provenant de l'extérieur du programme) à une fonction dangereuse (ouverture d'un fichier, exécution d'une commande externe, etc.). Il est très utile lors de l'écriture de scripts setuid ou CGIs ou n'importe quoi où le script a plus de privilèges que la personne l'alimentant des données.

Magie goto. goto &sub fait un appel de queue optimisé.

le débogueur.

use strict et use warnings . Cela peut vous sauver d'un tas de fautes de frappe.

24
répondu Glomek 2010-03-19 20:03:18
la source

basé sur la façon dont les commutateurs "-n" et "-p" sont implémentés dans Perl 5, vous pouvez écrire un programme apparemment incorrect incluant }{ :

ls |perl -lne 'print $_; }{ print "$. Files"'

qui est converti en interne à ce code:

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}
22
répondu Sec 2008-10-09 17:44:22
la source

commençons doucement avec le opérateur de vaisseau spatial .

$a = 5 <=> 7;  # $a is set to -1
$a = 7 <=> 5;  # $a is set to 1
$a = 6 <=> 6;  # $a is set to 0
18
répondu Sec 2008-10-02 16:09:33
la source

il s'agit d'une méta-réponse, mais les archives Perl Tips contiennent toutes sortes d'astuces intéressantes qui peuvent être faites avec Perl. L'archive des conseils précédents est en ligne pour la navigation, et peut être souscrite via la liste de diffusion ou atom feed.

certains de mes conseils préférés incluent construire des exécutables avec le PAR , en utilisant l'autodie pour lancer des exceptions automatiquement , et l'utilisation du commutateur et smart-match construit en Perl 5.10.

Divulgation: je suis l'un des auteurs et responsables de Perl Conseils, je pense évidemment très fortement à eux. ;)

18
répondu pjf 2008-10-02 17:30:52
la source

carte - non seulement parce qu'elle rend le code plus expressif, mais parce qu'il m'a donné une impulsion à lire un peu plus sur cette "programmation fonctionnelle".

18
répondu brunorc 2009-08-24 01:56:23
la source

la clause continue sur les boucles. Il sera exécuté au bas de chaque boucle, même ceux qui sont ensuite exécutés.

while( <> ){
  print "top of loop\n";
  chomp;

  next if /next/i;
  last if /last/i;

  print "bottom of loop\n";
}continue{
  print "continue\n";
}
15
répondu Shawn H Corey 2008-10-04 06:29:35
la source

mon vote irait pour le (?{}) et (??{}) groupes dans les expressions régulières de Perl. La première exécute le code Perl, ignorant la valeur de retour, la seconde exécute le code, en utilisant la valeur de retour comme une expression régulière.

15
répondu Leon Timmermans 2009-08-24 01:53:59
la source
while(/\G(\b\w*\b)/g) {
     print "\n";
}

l'ancre \G. C'est hot .

13
répondu J.J. 2008-10-02 18:25:00
la source

l'opérateur m// a des cas spéciaux obscurs:

  • si vous utilisez ? comme délimiteur, il ne correspond qu'une seule fois sauf si vous appelez reset .
  • Si vous utilisez ' comme séparateur le motif n'est pas interpolées.
  • si le motif est vide, il utilise le motif de la dernière correspondance réussie.
13
répondu Michael Carman 2010-11-11 18:35:59
la source

blocs de code Spéciaux tels que BEGIN , CHECK et END . Ils viennent de Awk, mais travaillent différemment en Perl, parce qu'il n'est pas basé sur des disques.

le bloc BEGIN peut être utilisé pour spécifier un code pour la phase d'analyse; il est également exécuté lorsque vous faites la syntaxe-et-variable-check perl -c . Par exemple, pour charger les variables de configuration:

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ([email protected]) {
        require 'config.default.pl';
    }
}
11
répondu Bruno De Fraine 2008-10-02 17:26:30
la source
rename("$_.part", $_) for "data.txt";

renomme data.txt.une partie des données.txt sans avoir à me répéter.

11
répondu timkay 2008-10-02 21:12:40
la source

un peu obscur est l'opérateur" tilde-tilde " qui force le contexte scalaire.

print ~~ localtime;

est le même que

print scalar localtime;

et différent de

print localtime;
10
répondu Sec 2008-10-02 16:42:14
la source

tie, l'interface de liaison variable.

9
répondu davidnicol 2008-10-04 01:15:27
la source

le "mode de désespoir" des constructions de contrôle de boucle de Perl qui leur fait chercher la pile pour trouver une étiquette correspondante permet quelques comportements curieux qui testent:: More en profite, pour le meilleur ou pour le pire.

SKIP: {
    skip() if $something;

    print "Never printed";
}

sub skip {
    no warnings "exiting";
    last SKIP;
}

voilà le peu connu .pmc fichier. "use Foo" va chercher Foo.pmc in @INC avant Foo.pm. Cela a été prévu pour permettre au bytecode compilé d'être chargé en premier, mais Module:: Compile en profite pour modules filtrés par source de cache pour des temps de chargement plus rapides et un débogage plus facile.

capacité de transformer des avertissements en erreurs.

local $SIG{__WARN__} = sub { die @_ };
$num = "two";
$sum = 1 + $num;
print "Never reached";

C'est ce que je peux penser du haut de ma tête qui n'a pas été mentionné.

9
répondu Schwern 2008-10-15 19:13:09
la source

goatse opérateur * :

$_ = "foo bar";
my $count =()= /[aeiou]/g; #3

ou

sub foo {
    return @_;
}

$count =()= foo(qw/a b c d/); #4

cela fonctionne parce que l'assignation de liste dans un contexte scalaire fournit le nombre d'éléments dans la liste assignée.

* Note, pas vraiment un opérateur

9
répondu Chas. Owens 2009-05-31 07:13:52
la source

Autres questions sur perl hidden-features