it-swarm.com.de

Versteckte Funktionen von Perl?

Was sind einige wirklich nützliche, aber esoterische Sprachfunktionen in Perl, mit denen Sie tatsächlich nützliche Arbeit leisten konnten?

Richtlinien:

  • Versuchen Sie, Antworten auf den Perl-Core und nicht auf CPAN zu beschränken
  • Bitte geben Sie ein Beispiel und eine kurze Beschreibung

Versteckte Funktionen auch gefunden in anderen Sprachen:

(Dies sind alles von Corions Antwort )

  • C
    • Duffs Gerät
    • Portabilität und Standardität
  • C #
    • Anführungszeichen für durch Leerzeichen getrennte Listen und Zeichenfolgen
    • Aliasable Namespaces
  • Java
    • Statische Initalisierer
  • JavaScript
    • Funktionen sind erstklassige Bürger
    • Block Umfang und Schließung
    • Methoden und Accessoren indirekt über eine Variable aufrufen
  • Ruby
    • Methoden durch Code definieren
  • PHP
    • Umfassende Online-Dokumentation
    • Magische Methoden
    • Symbolische Verweise
  • Python
    • Ein Zeilenwertaustausch
    • Möglichkeit, auch Kernfunktionen durch eigene Funktionen zu ersetzen

Weitere versteckte Features:

Betreiber:

Konstrukte zitieren:

Syntax und Namen:

Module, Pragmas und Befehlszeilenoptionen:

Variablen:

Schleifen und Flusskontrolle:

Reguläre Ausdrücke:

Andere Eigenschaften:

Andere Tricks und Meta-Antworten:


Siehe auch:

143
Adam Bellaire

Der Flip-Flop-Operator ist nützlich, um die erste Iteration zu überspringen, wenn die von einem Datei-Handle zurückgegebenen Datensätze (normalerweise Zeilen) ohne Verwendung einer Flag-Variablen durchlaufen werden:

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

Lauf perldoc perlop und suchen Sie nach "Flip-Flop" für weitere Informationen und Beispiele.

54
John Siracusa

Es gibt viele nicht offensichtliche Funktionen in Perl.

Wussten Sie zum Beispiel, dass nach einem Siegel ein Leerzeichen stehen kann?

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

Oder dass Sie unter numerischen Namen angeben können, wenn Sie symbolische Referenzen verwenden?

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

Es gibt auch den Quasi-Operator "bool", der 1 für wahre Ausdrücke und den leeren String für false zurückgibt:

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

Andere interessante Sachen: mit use overload Sie können String-Literale und -Zahlen überladen (und sie beispielsweise zu BigInts oder was auch immer machen).

Viele dieser Dinge sind tatsächlich irgendwo dokumentiert oder folgen logisch aus den dokumentierten Merkmalen, aber dennoch sind einige nicht sehr gut bekannt.

pdate: Noch ein Netter. Unter dem q{...} Zitierkonstrukte wurden erwähnt, aber wussten Sie, dass Sie Buchstaben als Trennzeichen verwenden können?

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

Ebenso können Sie reguläre Ausdrücke schreiben:

m xabcx
# same as m/abc/
47
moritz

Unterstützung für komprimierte Dateien über magic ARGV hinzufügen:

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

(Anführungszeichen um $ _ sind erforderlich, um Dateinamen mit Shell-Metazeichen zu behandeln)

Jetzt die <> Funktion dekomprimiert alle @ARGV Dateien, die mit ".gz" oder ".Z" enden:

while (<>) {
    print;
}
46
timkay

Eine meiner Lieblingsfunktionen in Perl ist die Verwendung des booleschen Operators ||, Um zwischen verschiedenen Optionen zu wählen.

 $x = $a || $b;

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

Das heißt, man kann schreiben:

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

um den ersten wahren Wert aus $a, $b und $c oder einem Standardwert von 0 zu erhalten.

In Perl 5.10 gibt es auch den Operator //, Der die linke Seite zurückgibt, wenn er definiert ist, und die rechte Seite, wenn er nicht definiert ist. Folgendes wählt den ersten definierten Wert aus $a, $b, $c Oder 0:

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

Diese können auch mit ihren Kurzformularen verwendet werden, die für die Bereitstellung von Standardeinstellungen sehr nützlich sind:

 $ x || = 0; # Wenn $ x falsch war, hat es jetzt den Wert 0. 
 
 $ X // = 0; # Wenn $ x undefiniert war, hat es jetzt den Wert Null. 

Cheerio,

Paul

40
pjf

Die Operatoren ++ und unary - arbeiten nicht nur mit Zahlen, sondern auch mit Zeichenketten.

my $_ = "a"
print -$_

druckt - a

print ++$_

druckt b

$_ = 'z'
print ++$_

druckt aa

39
Leon Timmermans

Da Perl fast alle "esoterischen" Teile aus den anderen Listen hat, sage ich Ihnen, was Perl nicht kann:

Das einzige, was Perl nicht tun kann, ist, dass Ihr Code beliebige URLs enthält, da der Operator // Für reguläre Ausdrücke verwendet wird.

Nur für den Fall, dass Ihnen nicht klar war, welche Funktionen Perl bietet, finden Sie hier eine Auswahl der möglicherweise nicht ganz offensichtlichen Einträge:

Duffs Gerät - in Perl

Portabilität und Standard - Es gibt wahrscheinlich mehr Computer mit Perl als mit einem C-Compiler

Eine Datei-/Pfadmanipulationsklasse - File :: Find funktioniert auf noch mehr Betriebssystemen als .Net

Anführungszeichen für durch Leerzeichen getrennte Listennd Zeichenfolgen - Perl ermöglicht die Auswahl nahezu beliebiger Anführungszeichen für Listen- und Zeichenfolgenbegrenzer

Aliasable Namespaces - Perl verfügt über folgende Glob-Zuweisungen:

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

Statische Initialisierer - Perl kann Code in fast jeder Phase der Kompilierung und Objektinstanziierung ausführen, von BEGIN (Code-Analyse) bis CHECK (nach Code-Analyse) bis import (beim Modulimport) nach new (Objektinstanziierung) nach DESTROY (Objektzerstörung) nach END (Programmende)

Funktionen sind erstklassige Bürger - genau wie in Perl

Gültigkeitsbereich und Schließung blockieren - Perl hat beides

Methoden und Accessoren indirekt über eine Variable aufrufen - Perl macht das auch:

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

Methoden durch Code definieren - Perl erlaubt das auch :

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

mfassende Online-Dokumentation - Perl-Dokumentation ist online und wahrscheinlich auch auf Ihrem System

Magic-Methoden die aufgerufen werden, wenn Sie eine "nicht vorhandene" Funktion aufrufen - Perl implementiert dies in der AUTOLOAD-Funktion

symbolische Verweise - Sie sollten sich von diesen fernhalten. Sie werden Ihre Kinder essen. Aber natürlich können Sie mit Perl Ihre Kinder blutrünstigen Dämonen anbieten.

Einzeiliger Wertewechsel - Perl erlaubt die Listenzuweisung

Möglichkeit, auch Kernfunktionen durch eigene Funktionen zu ersetzen

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

oder

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

unlink($_) for @ARGV
36
Corion

Autovivification . AFAIK keine andere Sprache hat es .

35
J.J.

Es ist einfach, in Perl fast jede Art von seltsamer Zeichenfolge zu zitieren.

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

Tatsächlich sind die verschiedenen Anführungszeichen in Perl sehr interessant. Mit den Perl-Regex-ähnlichen Zitierungsmechanismen können Sie alles zitieren und dabei die Begrenzer angeben. Sie können fast jedes Sonderzeichen wie #,/oder Zeichen zum Öffnen/Schließen wie (), [] oder {} verwenden. Beispiele:

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.);

Zitiermechanismen:

q: wörtliches Zitat; Das einzige Zeichen, das maskiert werden muss, ist das Endzeichen. qq: ein interpretiertes Zitat; verarbeitet Variablen und Escapezeichen. Ideal für Zeichenfolgen, die Sie zitieren müssen:

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

qx: Funktioniert wie qq, führt es jedoch nicht interaktiv als Systembefehl aus. Gibt den gesamten vom Standardausgang generierten Text zurück. (Die Umleitung wird, sofern vom Betriebssystem unterstützt, ebenfalls ausgegeben.) Auch mit Anführungszeichen (dem `-Zeichen) durchgeführt.

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

qr: Interpretiert wie qq, kompiliert es dann aber als regulären Ausdruck. Funktioniert auch mit den verschiedenen Optionen der Regex. Sie können den regulären Ausdruck jetzt als Variable übergeben:

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: Ein sehr, sehr nützlicher Anführungszeichenoperator. Verwandelt eine Gruppe von Wörtern in Anführungszeichen, die durch Leerzeichen getrennt sind, in eine Liste. Hervorragend zum Ausfüllen von Daten in einem Komponententest.


   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) ]; 

Sie sind großartig, wenn es die Dinge klarer macht. Für qx, qq und q verwende ich höchstwahrscheinlich die {} -Operatoren. Die häufigste Angewohnheit von Leuten, die qw verwenden, ist normalerweise der Operator (), aber manchmal wird auch qw // angezeigt.

31
Robert P

Die "for" -Anweisung kann genauso verwendet werden wie "with" in Pascal:

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

Sie können eine Folge von s /// Operationen usw. auf dieselbe Variable anwenden, ohne den Variablennamen wiederholen zu müssen.

HINWEIS: In dem nicht unterbrechenden Leerzeichen oben (& nbsp;) ist Unicode versteckt, um das Markdown zu umgehen. Nicht kopieren einfügen :)

27
timkay

Nicht wirklich versteckt, aber viele Perl-Programmierer wissen nichts über CPAN . Dies gilt insbesondere für Personen, die keine Vollzeitprogrammierer sind oder nicht Vollzeit in Perl programmieren.

27
mpeters

Der Quotewortoperator ist eines meiner Lieblingssachen. Vergleichen Sie:

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

und

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

Viel weniger Lärm, leichter für das Auge. Eine andere wirklich nette Sache an Perl, die man beim Schreiben von SQL wirklich vermisst, ist, dass ein nachgestelltes Komma zulässig ist:

print 1, 2, 3, ;

Das sieht seltsam aus, aber nicht, wenn Sie den Code auf eine andere Weise einrücken:

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

Wenn Sie dem Funktionsaufruf ein zusätzliches Argument hinzufügen, müssen Sie nicht mit Kommas in vorherigen oder nachfolgenden Zeilen herumspielen. Die Änderung einer einzelnen Linie hat keine Auswirkungen auf die umgebenden Linien.

Dies macht es sehr angenehm, mit verschiedenen Funktionen zu arbeiten. Dies ist möglicherweise eine der am meisten unterbewerteten Funktionen von Perl.

26
dland

Die Möglichkeit, Daten zu analysieren, die direkt in einen DATA -Block eingefügt wurden. Es muss nicht in einer Testdatei gespeichert werden, um im Programm oder ähnlichem geöffnet zu werden. Beispielsweise:

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

__DATA__
some good data
some bad data
more good data 
more good data 
26
allan

Binäres "x" ist der Wiederholungsoperator :

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

Es funktioniert auch mit Listen:

print for (1, 4, 9) x 3; # print 149149149
24
Bruno De Fraine

Neue Blockoperationen

Ich würde sagen, die Möglichkeit, die Sprache zu erweitern und Pseudoblockoperationen zu erstellen, ist eine davon.

  1. Sie deklarieren den Prototyp für ein Sub, indem Sie angeben, dass zuerst eine Codereferenz verwendet wird:

    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. Sie können es dann so im Körper nennen

    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 Ist ein weiteres verstecktes Juwel.) Beachten Sie, dass Sie das Schlüsselwort sub vor dem Block oder das Komma vor dem Hash nicht benötigen. Am Ende sieht es ungefähr so ​​aus: map { } @list

Quellfilter

Es gibt auch Quellfilter. Wo Perl Ihnen den Code weitergibt, damit Sie ihn bearbeiten können. Sowohl dies als auch die Blockoperationen sind so ziemlich alles, was man nicht zu Hause ausprobieren sollte.

Ich habe einige nette Dinge mit Quellfiltern gemacht, zum Beispiel das Erstellen einer sehr einfachen Sprache, um die Zeit zu überprüfen und kurze Perl-Einzeiler für einige Entscheidungen zuzulassen:

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

Lib::TL Scannt nur nach den "Variablen" und den Konstanten, erstellt sie und ersetzt sie nach Bedarf.

Auch hier können Quellfilter chaotisch sein, sind aber leistungsstark. Aber sie können Debugger durcheinander bringen - und sogar Warnungen können mit den falschen Zeilennummern gedruckt werden. Ich habe Damians Schalter nicht mehr verwendet, weil der Debugger die Fähigkeit verlieren würde, mir zu sagen, wo ich wirklich war. Ich habe jedoch festgestellt, dass Sie den Schaden minimieren können, indem Sie kleine Codeabschnitte so ändern, dass sie in derselben Zeile bleiben.

Signalhaken

Es ist oft genug erledigt, aber es ist nicht so offensichtlich. Hier ist ein Die-Handler, der sich an den alten hält.

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

Das heißt, wann immer ein anderes Modul im Code sterben möchte, muss es zu Ihnen kommen (es sei denn, jemand anderes führt ein destruktives Überschreiben von $SIG{__DIE__} Durch). Und Sie können benachrichtigt werden, dass jemand etwas falsch macht.

Natürlich können Sie für genügend Dinge einfach einen END { } - Block verwenden, wenn Sie nur aufräumen möchten.

overload::constant

Sie können Literale eines bestimmten Typs in Paketen überprüfen, die Ihr Modul enthalten. Wenn Sie dies beispielsweise in Ihrem import -Unter verwenden:

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

dies bedeutet, dass jede Ganzzahl, die größer als 2 Milliarden in den aufrufenden Paketen ist, in ein Math::BigInt - Objekt geändert wird. (Siehe Überlast :: Konstante ).

Gruppierte ganzzahlige Literale

Während wir gerade dabei sind. Mit Perl können Sie große Zahlen in Gruppen von drei Ziffern aufteilen und trotzdem eine analysierbare Ganzzahl daraus erhalten. Beachten Sie 2_000_000_000 Oben für 2 Milliarden.

24
Axeman

Makulaturprüfung. Bei aktivierter Makrokontrolle stirbt Perl (oder warnt mit -t) Wenn Sie versuchen, fehlerhafte Daten (etwa Daten von außerhalb des Programms) an eine unsichere Funktion zu übergeben (Öffnen einer Datei, Ausführen eines externen Befehls usw.). Es ist sehr hilfreich, wenn Sie Setuid-Skripte oder CGIs schreiben oder wenn das Skript über größere Berechtigungen verfügt als die Person, die die Daten eingibt.

Magie gehe. goto &sub führt einen optimierten Tail Call durch.

Der Debugger.

use strict und use warnings. Diese können Sie vor vielen Tippfehlern bewahren.

24
Andru Luvisi

Basierend auf der Art und Weise der "-n" und "-p" Schalter sind in Perl 5 implementiert. Sie können ein scheinbar falsches Programm schreiben, einschließlich }{:

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

welches intern in diesen Code konvertiert wird:

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}
22
Sec

map - nicht nur, weil es den eigenen Code ausdrucksvoller macht, sondern weil es mir den Impuls gab, ein bisschen mehr über diese "funktionale Programmierung" zu lesen.

18
brunorc

Beginnen wir einfach mit dem Spaceship Operator .

$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
Sec

Dies ist eine Meta-Antwort, aber die Archive Perl Tips enthalten alle möglichen interessanten Tricks, die mit Perl ausgeführt werden können. Das Archiv der vorherigen Tipps ist online verfügbar und kann per Mailingliste oder atom feed abonniert werden.

Einige meiner Lieblingstipps sind Erstellen von ausführbaren Dateien mit PAR , Verwenden von autodie zum automatischen Auslösen von Ausnahmen und die Verwendung der Schalter und smart-match Konstrukte in Perl 5.10.

Offenlegung: Ich bin einer der Autoren und Betreuer von Perl Tips, daher schätze ich sie offensichtlich sehr. ;)

18
pjf

Die continue-Klausel zu Schleifen. Es wird am Ende jeder Schleife ausgeführt, auch bei den nächsten.

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
Shawn H Corey

Meine Stimme würde für die Gruppen (? {}) Und (?? {}) in Perls regulären Ausdrücken abgegeben. Der erste führt Perl-Code aus und ignoriert den Rückgabewert, der zweite führt Code aus und verwendet den Rückgabewert als regulären Ausdruck.

15
Leon Timmermans
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

der\G Anker. Es ist heiß.

13
J.J.

Das m// Operator hat einige obskure Sonderfälle:

  • Wenn du benutzt ? als Trennzeichen stimmt nur einmal überein, es sei denn, Sie rufen reset auf.
  • Wenn du benutzt ' als Begrenzer wird das Muster nicht interpoliert.
  • Wenn das Muster leer ist, wird das Muster aus der letzten erfolgreichen Übereinstimmung verwendet.
13
Michael Carman

Das Null-Dateihandle Raute-Operator<> hat seinen Platz in der Erstellung von Befehlszeilentools. Es wirkt wie <FH>, um aus einem Handle zu lesen, mit der Ausnahme, dass es auf magische Weise auswählt, was zuerst gefunden wird: Befehlszeilen-Dateinamen oder STDIN. Entnommen aus perlop:

while (<>) {
...         # code for each line
}
12
spoulson

Spezielle Codeblöcke wie BEGIN, CHECK und END. Sie stammen aus Awk, funktionieren jedoch in Perl anders, da es nicht auf Datensätzen basiert.

Der BEGIN -Block kann verwendet werden, um Code für die Analysephase anzugeben. Es wird auch ausgeführt, wenn Sie die Syntax- und Variablenprüfung Perl -c durchführen. So laden Sie beispielsweise Konfigurationsvariablen:

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ([email protected]) {
        require 'config.default.pl';
    }
}
11
Bruno De Fraine
rename("$_.part", $_) for "data.txt";

benennt data.txt.part in data.txt um, ohne mich wiederholen zu müssen.

11
timkay

Etwas unklar ist der Tilde-Tilde-Operator, der den skalaren Kontext erzwingt.

print ~~ localtime;

ist das gleiche wie

print scalar localtime;

und anders als

print localtime;
10
Sec

Der "Verzweiflungsmodus" von Perls Schleifensteuerungskonstrukten, der sie veranlasst, den Stapel nachzuschlagen, um ein passendes Label zu finden, ermöglicht einige merkwürdige Verhaltensweisen, die Test :: More zum Guten oder Schlechten ausnutzt.

SKIP: {
    skip() if $something;

    print "Never printed";
}

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

Es gibt die wenig bekannte .pmc-Datei. "use Foo" sucht in @INC nach Foo.pmc vor Foo.pm. Dies sollte ermöglichen, dass kompilierter Bytecode zuerst geladen wird, aber Module :: Compile nutzt dies, um quellgefilterte Module für schnellere Ladezeiten und einfacheres Debuggen zwischenzuspeichern.

Die Fähigkeit, Warnungen in Fehler umzuwandeln.

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

Das ist es, woran ich denken kann, was nicht erwähnt wurde.

9
Schwern

Die Ziege operator*:

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

oder

sub foo {
    return @_;
}

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

Dies funktioniert, weil die Listenzuweisung im skalaren Kontext die Anzahl der Elemente in der Liste ergibt, die zugewiesen werden.

* Hinweis, nicht wirklich ein Operator

9
Chas. Owens

Das Trennzeichen für Eingabedatensätze kann auf einen Verweis auf eine Zahl zum Lesen von Datensätzen mit fester Länge festgelegt werden:

$/ = \3; print $_,"\n" while <>; # output three chars on each line
9
shmem

tie, die variable Bindeschnittstelle.

9
davidnicol

Dieser ist nicht besonders nützlich, aber extrem esoterisch. Ich bin darauf gestoßen, als ich mich im Perl-Parser umgesehen habe.

Bevor es POD gab, hatte Perl4 einen Trick, mit dem Sie die Manpage als nroff direkt in Ihr Programm einbetten konnten, damit sie nicht verloren ging. Perl4 verwendete ein Programm mit dem Namen wrapman (siehe Pink Camel Seite 319 für einige Details), um eine nroff-Manpage geschickt in Ihr Skript einzubetten.

Es funktionierte, indem nroff angewiesen wurde, den gesamten Code zu ignorieren und das Fleisch der Manpage nach einem [~ # ~] Ende [~ # ~] -Tag, das Perl anweist, die Verarbeitung von Code zu stoppen. Sah ungefähr so ​​aus:

#!/usr/bin/Perl
'di';
'ig00';

...Perl code goes here, ignored by nroff...

.00;        # finish .ig

'di         \" finish the diversion
.nr nl 0-1  \" fake up transition to first page
.nr % 0     \" start at page 1
'; __END__

...man page goes here, ignored by Perl...

Die Details der Roff-Magie entgehen mir, aber Sie werden feststellen, dass die Roff-Befehle Zeichenfolgen oder Zahlen im leeren Kontext sind. Normalerweise gibt eine Konstante im leeren Kontext eine Warnung aus. Es gibt spezielle Ausnahmen in op.c, Um ungültige Kontextzeichenfolgen zuzulassen, die mit bestimmten roff-Befehlen beginnen.

              /* Perl4's way of mixing documentation and code
                 (before the invention of POD) was based on a
                 trick to mix nroff and Perl code. The trick was
                 built upon these three nroff macros being used in
                 void context. The pink camel has the details in
                 the script wrapman near page 319. */
                const char * const maybe_macro = SvPVX_const(sv);
                if (strnEQ(maybe_macro, "di", 2) ||
                    strnEQ(maybe_macro, "ds", 2) ||
                    strnEQ(maybe_macro, "ig", 2))
                        useless = NULL;

Dies bedeutet, dass 'di'; Keine Warnung erzeugt, aber auch nicht 'die';'did you get that thing I sentcha?'; Oder 'ignore this line';.

Zusätzlich gibt es Ausnahmen für die numerischen Konstanten 0 Und 1, Die das bloße .00; Erlauben. Der Code behauptet, dies sei für allgemeinere Zwecke gedacht.

            /* the constants 0 and 1 are permitted as they are
               conventionally used as dummies in constructs like
                    1 while some_condition_with_side_effects;  */
            else if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
                useless = NULL;

Und was wissen Sie, 2 while condition Warnt!

7
Schwern

Mit @ {[...]} können Sie ein interpoliertes Ergebnis komplexer Perl-Ausdrücke erhalten

$a = 3;
$b = 4;

print "$a * $b = @{[$a * $b]}";

drucke: 3 * 4 = 12

7
user105090

Ich weiß nicht, wie esoterisch es ist, aber einer meiner Favoriten ist Hash-Slice . Ich benutze es für alle möglichen Dinge. Zum Beispiel, um zwei Hashes zusammenzuführen:

 meine% number_for = (eins => 1, zwei => 2, drei => 3); 
 meine% your_numbers = (zwei => 2, vier => 4, sechs => 6 ); 
 @ number_for {keys% your_numbers} = values% your_numbers; 
 print sort values% number_for; # 12346 
7
Vince Veselosky
use diagnostics;

Wenn Sie anfangen, mit Perl zu arbeiten, und dies noch nie zuvor getan haben, können Sie mit diesem Modul jede Menge Zeit und Ärger sparen. In diesem Modul wird für fast jede grundlegende Fehlermeldung ausführlich erläutert, warum der Code beschädigt ist, und es werden einige hilfreiche Hinweise zur Fehlerbehebung gegeben. Beispielsweise:

use strict;
use diagnostics;

$var = "foo";

gibt Ihnen diese hilfreiche Nachricht:

 Das globale Symbol "$ var" erfordert einen expliziten Paketnamen in Zeile 4. 
 Die Ausführung von - wurde aufgrund von Kompilierungsfehlern abgebrochen (# 1) 
 (F) Sie haben gesagt " use strict vars ", was angibt, dass alle Variablen 
 entweder lexikalisch (mit" my ") oder vorher mit 
" our "deklariert werden müssen oder explizit qualifiziert sind, welches Paket die globale Variable 
 ist in (mit "::"). 
 
 Ungefangene Ausnahme vom Benutzercode: 
 Das globale Symbol "$ var" erfordert einen expliziten Paketnamen in Zeile 4. 
 Ausführung von - wegen Übersetzungsfehlern abgebrochen. 
 In - Zeile 5 
use diagnostics;
use strict;

sub myname {
    print { " Some Error " };
};

sie erhalten diesen großen, hilfreichen Textblock:

 Syntaxfehler in Zeile 5, in der Nähe von "};" 
 Ausführung abgebrochen aufgrund von Kompilierungsfehlern (# 1) 
 (F) Bedeutet wahrscheinlich, dass Sie einen Syntaxfehler hatten. Häufige Gründe sind: 
 
 Ein Schlüsselwort ist falsch geschrieben. 
 Ein Semikolon fehlt. 
 Ein Komma fehlt. 
 Eine öffnende oder schließende Klammer ist fehlt. 
 Eine öffnende oder schließende Klammer fehlt. 
 Ein schließendes Anführungszeichen fehlt. 
 
 Häufig wird eine andere Fehlermeldung in Verbindung mit der Syntax 
 Fehler bei der Eingabe weiterer Informationen. (Manchmal hilft es, -w einzuschalten.) 
 Die Fehlermeldung selbst sagt Ihnen oft, wo sie sich in der Zeile befand, als 
 Beschlossen wurde, aufzugeben. Manchmal liegt der eigentliche Fehler mehrere Tokens 
 Vor, da Perl zufällige Eingaben gut versteht. 
 Gelegentlich kann die Zeilennummer irreführend sein, und einmal in einem blauen Mond 
 Nur Um herauszufinden, was den Fehler auslöst, rufen Sie wiederholt 
 Perl -c auf und hacken jedes Mal die Hälfte des Programms ab, um 
 zu überprüfen, ob der Fehler behoben wurde. Art der kybernetischen Version von S. 
 
 Ungefangene Ausnahme vom Benutzercode: 
 Syntaxfehler in Zeile 5, in der Nähe von "};" 
 Ausführung von - abgebrochen aufgrund von Übersetzungsfehlern. 
 in - Zeile 7 

Von dort aus können Sie feststellen, was mit Ihrem Programm möglicherweise nicht stimmt (in diesem Fall ist der Ausdruck völlig falsch formatiert). Es gibt eine große Anzahl bekannter Fehler bei der Diagnose. Dies wäre zwar keine gute Sache für die Produktion, kann aber als großartige Lernhilfe für diejenigen dienen, die Perl noch nicht kennen.

6
Robert P
sub load_file
{
    local(@ARGV, $/) = shift;
    <>;
}

und eine Version, die ein entsprechendes Array zurückgibt:

sub load_file
{
    local @ARGV = shift;
    local $/ = wantarray? $/: undef;
    <>;
}
6
timkay

($ x, $ y) = ($ y, $ x) hat mich dazu gebracht, Perl zu lernen.

Der Listenkonstruktor 1..99 oder 'a' .. 'zz' ist auch sehr nett.

5
Daniel

@Schwern erwähnte, Warnungen durch Lokalisierung von $SIG{__WARN__} In Fehler zu verwandeln. Sie können dies auch (lexikalisch) mit use warnings FATAL => "all"; Tun. Siehe perldoc lexwarn.

In diesem Sinne können Sie seit Perl 5.12 perldoc foo Anstelle des vollständigen perldoc perlfoo Sagen. Endlich! :)

5
wolverian

Es gibt auch $ [die Variable, die entscheidet, an welchem ​​Index ein Array beginnt. Der Standardwert ist 0, sodass ein Array bei 0 beginnt

$[=1;

Sie können Perl dazu bringen, sich mehr wie AWK (oder Fortran) zu verhalten, wenn Sie es wirklich wollen.

5
Sec

Verwenden Sie lvalues, um Ihren Code wirklich zu verwirren:

my $foo = undef ;
sub bar:lvalue{ return $foo ;}

# Then later

bar = 5 ;
print bar ;
4
Jeteve

Ein nützlicher zusammengesetzter Operator zum bedingten Hinzufügen von Zeichenfolgen oder Listen zu anderen Listen ist x!!Operator:

 print 'the meaning of ', join ' ' =>  
     'life,'                x!! $self->alive,
     'the universe,'        x!! ($location ~~ Universe),
     ('and', 'everything.') x!! 42; # this is added as a list

dieser Operator ermöglicht eine umgekehrte Syntax wie

 do_something() if test();
4
Eric Strom

Gut. Hier ist eine andere. Dynamisches Scoping . Es wurde in einem anderen Beitrag ein wenig darüber gesprochen, aber ich habe es hier bei den versteckten Funktionen nicht gesehen.

Dynamisches Scoping wie Autovivification wird nur in einer sehr begrenzten Anzahl von Sprachen verwendet. Perl und Common LISP sind die einzigen, von denen ich weiß, dass sie Dynamic Scoping verwenden.

4
J.J.

Wie wäre es mit der Fähigkeit zu verwenden

my @symbols = map { +{ 'key' => $_ } } @things;

um ein Array von Hashrefs aus einem Array zu generieren - das + vor dem Hashref macht den Block eindeutig, so dass der Interpreter weiß, dass es sich um einen Hashref und nicht um einen Codeblock handelt. Genial.

(Vielen Dank an Dave Doyle, der mir dies beim letzten Treffen von Toronto Perlmongers erklärt hat.)

4
talexb

Sichere Fächer.

Mit dem Safe-Modul können Sie Ihre eigene Sandbox-Umgebung nur mit Perl erstellen. Sie können dann Perl-Skripte in die Sandbox laden.

Freundliche Grüße,

4
melo

Ader IO::Handle Modul. Das Wichtigste für mich ist, dass es das automatische Spülen von Dateihandles ermöglicht. Beispiel:

use IO::Handle;    
$log->autoflush(1);
4

Dieser Einzeiler zeigt, wie mit glob alle Wortkombinationen eines Alphabets (A, T, C und G -> DNA) für Wörter einer bestimmten Länge (4) generiert werden:

Perl -MData::Dumper -e '@CONV = glob( "{A,T,C,G}" x 4 ); print Dumper( \@CONV )'
4
maasha

Quantum::Superpositions

use Quantum::Superpositions;

if ($x == any($a, $b, $c)) { ...  }
3
Dario

use re debug
Doc on Use Re-Debug

und

Perl -MO=Concise[,OPTIONS]
Doc on Concise

Neben der außerordentlichen Flexibilität, Ausdrucksstärke und Programmierbarkeit im Stil von C, Pascal, Python und anderen Sprachen gibt es mehrere Pragmas-Befehlsschalter, die Perl zu meiner 'goto'-Sprache für das anfängliche Kanudeln machen Ein Algorithmus, ein regulärer Ausdruck oder schnelle Probleme, die gelöst werden müssen. Diese beiden sind meines Erachtens einzigartig in Perl und gehören zu meinen Favoriten.

use re debug: Die meisten modernen Varianten regulärer Ausdrücke verdanken ihre aktuelle Form und Funktion Perl. Während es viele Perl-Formen von Regex gibt, die nicht in anderen Sprachen ausgedrückt werden können, gibt es fast keine Formen des Regex-Geschmacks anderer Sprachen, die nicht in Perl ausgedrückt werden können. Darüber hinaus verfügt Perl über einen wunderbaren Regex-Debugger, der zeigt, wie die Regex-Engine Ihren Regex interpretiert und mit der Zielzeichenfolge übereinstimmt.

Beispiel: Ich habe kürzlich versucht, eine einfache CSV-Routine zu schreiben. (Ja, ja, ich weiß, ich hätte Text :: CSV ... verwenden sollen, aber die CSV-Werte wurden nicht in Anführungszeichen gesetzt und sind einfach.

Meine erste Einstellung war /^(^(?:(.*?),){$i}/, um den i-Datensatz aus n CSV-Datensätzen zu extrahieren. Das funktioniert gut - bis auf den letzten Datensatz oder n von n. Ich könnte das ohne den Debugger sehen.

Als nächstes habe ich /^(?:(.*?),|$){$i}/ ausprobiert. Dies hat nicht funktioniert und ich konnte nicht sofort erkennen, warum. Ich dachte, ich sage (.*?) Gefolgt von einem Komma oder einer EOL. Dann habe ich oben in einem kleinen Testskript use re debug Hinzugefügt. Ahh ja, der Wechsel zwischen ,|$ Wurde nicht so interpretiert; es wurde interpretiert als ((.*?),) | ($) - nicht was ich wollte.

Eine neue Gruppierung wurde benötigt . Also bin ich bei der Arbeit /^(?:(.*?)(?:,|$)){$i}/ angekommen. Während ich im Regex-Debugger war, war ich überrascht, wie viele Schleifen für ein Match gegen Ende der Zeichenkette benötigt wurden. Es ist der Begriff .*?, Der ziemlich vieldeutig ist und übermäßiges Zurückverfolgen erfordert, um zu befriedigen. Also habe ich /^(?:(?:^|,)([^,]*)){$i}/ ausprobiert. Dies hat zwei Ursachen: 1) Reduziert das Backtracking, da alle außer einem Komma gierig übereinstimmen. 2) Erlaubte dem Regex-Optimierer, die Änderung nur einmal im ersten Feld zu verwenden. Mit Benchmark ist dies 35% schneller als der erste reguläre Ausdruck. Der Regex-Debugger ist wunderbar und nur wenige verwenden ihn.

Perl -MO=Concise[,OPTIONS]: Die Frameworks B und Concise sind hervorragende Tools, um zu sehen, wie Perl Ihr Meisterstück interpretiert. Mit -MO=Concise Wird das Ergebnis der Perl-Interpreter-Übersetzung Ihres Quellcodes gedruckt. Es gibt viele Optionen für Concise und in B können Sie Ihre eigene Darstellung der OP-Codes schreiben.

Als in diesem Beitrag können Sie Concise verwenden, um verschiedene Codestrukturen zu vergleichen. Sie können Ihre Quellzeilen mit den von diesen Zeilen generierten OP-Codes verschachteln. Hör zu.

3
dawg

Sehr spät zur Party, aber: Attribute.

Mit Attributen können Sie im Wesentlichen beliebigen Code definieren, der mit der Deklaration einer Variablen oder Unterroutine verknüpft werden soll. Der beste Weg, diese zu verwenden, ist mit Attribute :: Handlers ; Dies macht es einfach, Attribute zu definieren (in Bezug auf, was sonst, Attribute!).

Ich habe auf der YAPC :: 2006, online hier einen Vortrag über die deklarative Assemblierung einer pluggable-Klasse und ihrer Plugins gehalten. Dies ist eine ziemlich einzigartige Funktion.

3
Joe McMahon

Ich persönlich liebe den/e-Modifikator für die s /// -Operation:

while(<>) {
  s/(\w{0,4})/reverse($1);/e; # reverses all words between 0 and 4 letters
  print;
}

Eingang:

This is a test of regular expressions
^D

Ausgabe (denke ich):

sihT si a tset fo regular expressions
3
Chris Lutz

Sie können unterschiedliche Anführungszeichen in HEREDOCS verwenden, um unterschiedliche Verhaltensweisen zu erhalten.

my $interpolation = "We will interpolated variables";
print <<"END";
With double quotes, $interpolation, just like normal HEREDOCS.
END

print <<'END';
With single quotes, the variable $foo will *not* be interpolated.
(You have probably seen this in other languages.)
END

## this is the fun and "hidden" one
my $Shell_output = <<`END`;
echo With backticks, these commands will be executed in Shell.
echo The output is returned.
ls | wc -l
END

print "Shell output: $Shell_output\n";
3
Justin

Es gibt eine leistungsfähigere Möglichkeit, das Programm auf Syntaxfehler zu überprüfen:

Perl -w -MO=Lint,no-context myscript.pl

Das Wichtigste, was es tun kann, ist das Melden von "nicht vorhandenen Unterprogramm" -Fehlern.

3
Alexey

Mein Lieblingsmerkmal von Perl ist die Funktion eof. Hier ist ein Beispiel so ziemlich direkt von perldoc -f eof das zeigt, wie Sie es verwenden können, um den Dateinamen zurückzusetzen und $. (die aktuelle Zeilennummer) leicht über mehrere Dateien verteilt, die in der Befehlszeile geladen werden:

while (<>) {
  print "$ARGV:$.\t$_";
} 
continue {
  close ARGV if eof
}
3
Telemachus

Sie können das Trennzeichen in regulären Ausdrücken und Zeichenfolgen durch fast alles andere ersetzen. Dies ist besonders nützlich für das "Leaning Toothpick-Syndrom", das hier beispielhaft dargestellt wird:

$url =~ /http:\/\/www\.stackoverflow\.com\//;

Sie können den größten Teil des Back-Whacking beseitigen, indem Sie das Trennzeichen ändern. /bar/ steht für m/bar/ das ist das gleiche wie m!bar!.

$url =~ m!http://www\.stackoverflow\.com/!;

Sie können sogar Trennzeichen wie {} und [] verwenden. Ich persönlich liebe diese. q{foo} ist das gleiche wie 'foo'.

$code = q{
    if( this is awesome ) {
        print "Look ma, no escaping!";
    }
};

Versuchen Sie Folgendes, um Ihre Freunde (und Ihren Syntax-Textmarker) zu verwirren:

$string = qq'You owe me $1,000 dollars!';
3

Axeman erinnerte mich daran, wie einfach es ist, einige der integrierten Funktionen zu verpacken.

Vor Perl 5.10 hatte Perl keinen hübschen Aufdruck wie Python.

In Ihrem lokalen Programm können Sie also Folgendes tun:

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

oder fügen Sie ein Debug hinzu.

sub print {
    exists $ENV{DEVELOPER} ?
    print Dumper(@_) :
    print @_;
}
2
J.J.

Die folgenden Angaben sind genauso kurz, aber aussagekräftiger als "~~", da sie angeben, was zurückgegeben wird, und es besteht keine Verwechslung mit dem Smart-Match-Operator:

print "".localtime;   # Request a string

print [email protected];       # Request a number
2
ikegami

Die Möglichkeit, einen Hash als sichtbaren Filter in einer Schleife zu verwenden. Ich habe noch etwas ganz Nettes in einer anderen Sprache gesehen. Zum Beispiel war ich nicht in der Lage, dies in Python zu duplizieren.

Zum Beispiel möchte ich eine Zeile drucken, wenn sie noch nicht gesehen wurde.

my %seen;

for (<LINE>) {
  print $_ unless $seen{$_}++;
}
2
Jauder Ho

Zwei Dinge, die gut zusammenarbeiten: IO behandelt In-Core-Strings und verwendet Funktionsprototypen, damit Sie Ihre eigenen Funktionen mit grep/map-ähnlicher Syntax schreiben können.

sub with_output_to_string(&) {           # allows compiler to accept "yoursub {}" syntax.
  my $function = shift;
  my $string   = '';
  my $handle   = IO::Handle->new();
  open($handle, '>', \$string) || die $!; # IO handle on a plain scalar string ref
  my $old_handle = select $handle;
  eval { $function->() };
  select $old_handle;
  die [email protected] if [email protected];
  return $string;
}

my $greeting = with_output_to_string {
  print "Hello, world!";
};

print $greeting, "\n";
2
Danny Woods

Die Funktion, die mir am besten gefällt, sind Anweisungsmodifikatoren.

Ich weiß nicht, wie oft ich wollte:

say 'This will output' if 1;
say 'This will not output' unless 1;
say 'Will say this 3 times. The first Time: '.$_ for 1..3;

in anderen Sprachen. etc...

Das 'etc' erinnerte mich an ein weiteres 5.12-Feature, den Yada-Yada-Operator.

Das ist großartig für Zeiten, in denen Sie nur einen Platzhalter haben möchten.

sub something_really_important_to_implement_later {
    ...
} 

Probieren Sie es aus: Perl Docs auf Yada Yada Operator .

2
gdey

Die neue Option -E in der Befehlszeile:

> Perl -e "say 'hello"" # does not work 

String found where operator expected at -e line 1, near "say 'hello'"
        (Do you need to predeclare say?)
syntax error at -e line 1, near "say 'hello'"
Execution of -e aborted due to compilation errors.

> Perl -E "say 'hello'" 
hello
2
knb

Sie können Funktionsaufrufe beispielsweise in einer Zeichenfolge erweitern.

print my $foo = "foo @{[scalar(localtime)]} bar";

foo Mi 26 Mai 15:50:30 2010 bar

2
trapd00r

Interpolation von regulären Match-Ausdrücken. Eine nützliche Anwendung ist das Matching auf einer Blacklist. Ohne Interpolation ist es so geschrieben:

#detecting blacklist words in the current line
/foo|bar|baz/;

Kann stattdessen geschrieben werden

@blacklistWords = ("foo", "bar", "baz");
$anyOfBlacklist = join "|", (@blacklistWords);
/$anyOfBlacklist/;

Dies ist ausführlicher, ermöglicht jedoch das Auffüllen aus einer Datendatei. Auch wenn die Liste aus irgendeinem Grund in der Quelle verwaltet wird, ist es einfacher, das Array als RegExp zu verwalten.

1
Erick

Verwenden von Hashes (wobei die Schlüssel eindeutig sind), um die eindeutigen Elemente einer Liste zu erhalten:

my %unique = map { $_ => 1 } @list;
my @unique = keys %unique;
1
Nick Dixon

Sie könnten denken, Sie können dies tun, um Speicherplatz zu sparen:

@is_month{qw(jan feb mar apr may jun jul aug sep oct nov dec)} = undef;

print "It's a month" if exists $is_month{lc $mon};

aber das tut es nicht. Perl weist weiterhin jedem Schlüssel einen anderen Skalarwert zu. Devel :: Peek zeigt dies. PVHV ist der Hash. Elt ist ein Schlüssel und das folgende SV ist sein Wert. Beachten Sie, dass jeder SV eine andere Speicheradresse hat, die angibt, dass sie nicht gemeinsam genutzt werden.

Dump \%is_month, 12;

SV = RV(0x81c1bc) at 0x81c1b0
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x812480
  SV = PVHV(0x80917c) at 0x812480
    REFCNT = 2
    FLAGS = (SHAREKEYS)
    ARRAY = 0x206f20  (0:8, 1:4, 2:4)
    hash quality = 101.2%
    KEYS = 12
    FILL = 8
    MAX = 15
    RITER = -1
    EITER = 0x0
    Elt "feb" HASH = 0xeb0d8580
    SV = NULL(0x0) at 0x804b40
      REFCNT = 1
      FLAGS = ()
    Elt "may" HASH = 0xf2290c53
    SV = NULL(0x0) at 0x812420
      REFCNT = 1
      FLAGS = ()

Ein Undef-Skalar belegt genauso viel Speicher wie ein Integer-Skalar. Sie sollten also alle auf 1 setzen und vermeiden, dass Sie vergessen, mit exists zu prüfen.

my %is_month = map { $_ => 1 } qw(jan feb mar apr may jun jul aug sep oct nov dec);

print "It's a month" if $is_month{lc $mon});
1
timkay

Wenn du das nächste Mal auf einer Geek-Party bist, zieh diesen Einzeiler in einer Bash-Shell aus und die Frauen werden dich schwärmen und deine Freunde werden dich anbeten:

finden . -name "* .txt" | xargs Perl -pi -es/1: (\ S +)/uc ($ 1)/ge '

Verarbeiten Sie alle * .txt-Dateien und führen Sie eine direkte Suche und Ersetzung mit Perls regulärem Ausdruck durch. Dieser konvertiert Text nach einem '1:' in Großbuchstaben und entfernt das '1:'. Verwendet Perls Modifikator 'e', ​​um den zweiten Teil der Regex zum Suchen/Ersetzen als ausführbaren Code zu behandeln. Sofortiges einzeiliges Vorlagensystem. Mit xargs können Sie eine große Anzahl von Dateien verarbeiten, ohne die maximale Befehlszeilenlänge von bash zu überschreiten.

1
Mark Maunder

Der Ausdruck defined &DB::DB gibt true zurück, wenn das Programm im Debugger ausgeführt wird.

1
Kiffin

Fügen Sie eine für die Funktionen unpack () und pack () hinzu, die sich hervorragend eignen, wenn Sie Daten in einem Format importieren und/oder exportieren müssen, das von anderen Programmen verwendet wird.

In den meisten Programmen können Sie heutzutage natürlich Daten in XML exportieren, und für viele häufig verwendete proprietäre Dokumentformate sind Perl-Module geschrieben. Aber dies ist eine dieser Funktionen, die unglaublich nützlich ist, wenn Sie sie brauchen, und pack ()/unpack () sind wahrscheinlich der Grund , warum die Leute das getan haben CPAN-Module für so viele proprietäre Datenformate schreiben können.

1
Peter

Ich bin ein bisschen zu spät zur Party, aber eine Abstimmung für die eingebaute gebundene Hash-Funktion dbmopen() - es hat mir sehr geholfen. Es ist nicht gerade eine Datenbank, aber wenn Sie Daten auf der Festplatte speichern müssen, werden viele Probleme beseitigt und Just Works. Es hat mir den Einstieg erleichtert, als ich keine Datenbank hatte und Storable.pm nicht verstand, aber ich wusste, dass ich über das Lesen und Schreiben von Textdateien hinausgehen wollte.

1
AmbroseChapel

B :: Deparse - Perl-Compiler-Backend zur Erzeugung von Perl-Code. Nicht etwas, das Sie in Ihrer täglichen Perl-Programmierung verwenden würden, aber unter bestimmten Umständen nützlich sein könnte.

Wenn Sie auf einen verschleierten Code oder einen komplexen Ausdruck stoßen, übergeben Sie ihn an Deparse. Nützlich, um einen JAPH- oder Perl-Code herauszufinden, der Golf spielt.

$ Perl -e '$"=$,;*{;qq{@{[(A..Z)[qq[0020191411140003]=~m[..]g]]}}}=*_=sub{print/::(.*)/};$\=$/;q<Just another Perl Hacker>->();'
Just another Perl Hacker

$ Perl -MO=Deparse -e '$"=$,;*{;qq{@{[(A..Z)[qq[0020191411140003]=~m[..]g]]}}}=*_=sub{print/::(.*)/};$\=$/;q<Just another Perl Hacker>->();'
$" = $,;
*{"@{[('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')['0020191411140003' =~ /../g]];}";} = *_ = sub {
    print /::(.*)/;
}
;
$\ = $/;
'Just another Perl Hacker'->();
-e syntax OK

Ein nützlicheres Beispiel ist deparse, um den Code hinter einem Coderef herauszufinden, den Sie möglicherweise von einem anderen Modul erhalten haben, oder

use B::Deparse;
my $deparse = B::Deparse->new;
$code = $deparse->coderef2text($coderef);
print $code;
0
Prakash K

verwenden von leeren Blöcken mit redo oder anderen Steuerwörtern, um benutzerdefinierte Schleifenkonstrukte zu erstellen.

durchlaufen einer verknüpften Liste von Objekten, die die erste ->can('print') -Methode zurückgeben:

sub get_printer {
    my $self = shift;
    {$self->can('print') or $self = $self->next and redo}
}
0
Eric Strom

Einer noch...

Perl-Cache:

my $processed_input = $records || process_inputs($records_file);

Auf Elpeleg Open Source, Perl CMS http://www.web-app.net/

0
On Elpeleg

Anzeigen des Fortschritts im Skript durch Drucken in derselben Zeile:

$| = 1; # flush the buffer on the next output 

for $i(1..100) {
    print "Progress $i %\r"
}
0
Tomasz

Perl eignet sich hervorragend als flexible awk/sed.

Verwenden wir zum Beispiel einen einfachen Ersatz für ls | xargs stat, naiv gemacht wie:

$ ls | Perl -pe 'print "stat "' | sh 

Dies funktioniert nicht gut, wenn die Eingabe (Dateinamen) Leerzeichen oder Shell-Sonderzeichen wie |$\. Daher werden in der Perl-Ausgabe häufig einfache Anführungszeichen benötigt.

Eine Komplikation beim Aufruf von Perl über die Kommandozeile -ne ist, dass die Shell zuerst an Ihrem Einzeiler knabbert. Dies führt oft zu einer qualvollen Flucht, um sie zu befriedigen.

Eine 'versteckte' Funktion, die ich die ganze Zeit benutze, ist \x27 um ein einfaches Anführungszeichen einzufügen, anstatt zu versuchen, Shell-Escapezeichen zu verwenden '\''

So:

$ ls | Perl -nle 'chomp; print "stat '\''$_'\''"' | sh

kann sicherer geschrieben werden:

$ ls | Perl -pe 's/(.*)/stat \x27$1\x27/' | sh

Das funktioniert nicht mit lustigen Zeichen in den Dateinamen, auch so zitiert. Aber das wird:

$ ls | Perl -pe 's/\n/\0/' | xargs -0 stat
0
Terry

"jetzt"

sub _now { 
        my ($now) = localtime() =~ /([:\d]{8})/;
        return $now;
}

print _now(), "\n"; #  15:10:33
0
Jet

@Corion - Bare URLs in Perl? Natürlich können Sie auch in interpolierten Zeichenfolgen. Das einzige Mal, dass es darauf ankommt, ist eine Zeichenfolge, die Sie tatsächlich als regulären Ausdruck verwenden.

0
Toby

$ 0 ist der Name des ausgeführten Perl-Skripts. Es kann verwendet werden, um den Kontext abzurufen, aus dem ein Modul ausgeführt wird.

# MyUsefulRoutines.pl

sub doSomethingUseful {
  my @args = @_;
  # ...
}

if ($0 =~ /MyUsefulRoutines.pl/) {
  # someone is running  Perl MyUsefulRoutines.pl [args]  from the command line
  &doSomethingUseful (@ARGV);
} else {
  # someone is calling  require "MyUsefulRoutines.pl"  from another script
  1;
}

Diese Redewendung ist hilfreich, um ein eigenständiges Skript mit einigen nützlichen Unterroutinen in einer Bibliothek zu behandeln, die in andere Skripts importiert werden kann. Python hat eine ähnliche Funktionalität wie das object.__== "__main__" idiom.

0
mob