Perl gizli özellikleri?

aslında yararlı iş yapmak için istihdam mümkün oldum Perl bazı gerçekten yararlı ama ezoterik dil özellikleri nelerdir?

kurallar:

  • Perl çekirdeğine cevap sınırlamaya çalışın ve CPAN
  • değil
  • bir örnek ve kısa bir açıklama verin

gizli özellikler de diğer dillerde bulunan ' gizli özellikleri:

(hepsi Corion'un cevabı dan)

  • C
    • Duff'un cihazı
    • taşınabilirlik ve standart
  • C#
    • boşluk ayrılmış listeleri ve dizeleri için tırnak
    • Aliasable namespaces
  • Java
    • Statik İnitalizers
  • '
    • fonksiyonları birinci sınıf vatandaşlardır
    • blok kapsamı ve kapatma
    • dolaylı olarak
    • değişkeniyle yöntem ve erişimcileri çağırma
  • Ruby
    • kod aracılığıyla yöntemleri tanımlama
  • PHP
    • yaygın Çevrimiçi belgeler
    • sihirli yöntemler
    • sembolik referanslar
  • '
    • bir satır değeri değiştirme
    • yeteneği kendi işlevinizle bile çekirdek işlevlerini değiştirin

Diğer Gizli Özellikler:

işleçleri:

alıntı yapıları:

sözdizimi ve İsimleri:

modüller, Pragmalar ve komut satırı seçenekleri:

değişkenler:

döngüler ve akış kontrolü:

düzenli ifadeler:

diğer özellikler:

diğer hileler ve meta-cevaplar:


Ayrıca Bakınız:

143
tarihinde sordu Adam Bellaire 2008-10-02 15:49:22
kaynak

30 ответов

flip-flop operatörü, bir bayrak değişkeni kullanmadan bir dosya tutamağı tarafından döndürülen kayıtlar (genellikle çizgiler) aracılığıyla döngü yaparken ilk yinelemeyi atlamak için yararlıdır:

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

Run perldoc perlop ve daha fazla bilgi ve örnekler için "flip-flop" arayın.

54
cevap John Siracusa 2008-10-02 16:41:44
kaynak

Perl birçok belirgin olmayan özellikleri vardır.

örneğin, bir sigil'den sonra bir boşluk olabileceğini biliyor muydunuz?

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

veya sembolik referanslar kullanırsanız subs sayısal adları verebilir misiniz?

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

true expressions için 1 döndüren" bool " quasi operatörü ve false için boş dize de var:

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

diğer ilginç şeyler: ile use overload dize harfleri ve sayıları aşırı yükleyebilir (ve örneğin onları Bigİnts veya her neyse).

bunların çoğu aslında bir yerde belgelenir veya belgelenmiş özelliklerden mantıksal olarak takip edilir, ancak yine de bazıları çok iyi bilinmemektedir.

güncelleme : başka güzel bir. q{...} alıntı yapılarının altında bahsedildi, ancak harfleri sınırlayıcı olarak kullanabileceğinizi biliyor muydunuz?

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

: düzenli ifadeler yazabilirsiniz

m xabcx
# same as m/abc/
47
cevap moritz 2009-08-24 01:39:45
kaynak

magic ARGV :

ile sıkıştırılmış dosyalar için destek Ekle
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;

(kabuk metacharacters ile dosya adları işlemek için gerekli $_ etrafında tırnak)

şimdi <> özelliği " ile biten herhangi bir @ARGV dosyalarını açacaktır.gz "veya".Z":

while (<>) {
    print;
}
46
cevap timkay 2010-10-31 01:34:06
kaynak

Perl'deki en sevdiğim özelliklerden biri, bir dizi seçenek arasında seçim yapmak için boolean || operatörünü kullanıyor.

 $x = $a || $b;

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

bu bir yazabilirsiniz anlamına gelir:

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

ilk gerçek değeri $a , $b ve $c veya 0 varsayılanından başka bir şekilde almak için.

Perl 5.10'da, // operatörü de var, bu da sol tarafı döndürüyor tanımlanmış ve sağ taraf aksi halde. Aşağıdaki ilk seçer tanımlı değeri $a , $b , $c , veya 0 aksi takdirde:

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

bunlar, varsayılanları sağlamak için çok yararlı olan kısa el formlarıyla da kullanılabilir:

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

'

40
cevap pjf 2010-11-11 18:09:37
kaynak

operatörler ++ ve unary-sadece sayılar üzerinde değil, aynı zamanda dizelerde de çalışmaz.

my $_ = "a"
print -$_

- - a

print ++$_

baskılar b

$_ = 'z'
print ++$_

- aa

39
cevap Leon Timmermans 2008-10-02 16:26:31
kaynak

Perl, diğer listelerden hemen hemen tüm "ezoterik" parçalara sahip olduğu için, perl'in yapamayacağı bir şeyi anlatacağım:

yapamayacağınız tek şey kodunuzda çıplak rasgele URL'ler var, çünkü // operatörü düzenli ifadeler için kullanılıyor.

Perl'in sunduğu özelliklerin size açık olmaması durumunda, belki de tamamen açık olmayan girişlerin seçici bir listesi:

Duff'un cihazı - Perl

taşınabilirlik ve Standartlık - muhtemelen Perl ile bir C derleyici ile daha fazla bilgisayar vardır

a file/path manipulation class - File::Find works on even more operating systems than. net does

ve dizeleri - Perl listesi ve dize sınırlayıcıları için neredeyse keyfi tırnak seçmenize olanak sağlar

Aliasable namespaces - Perl bu atamaları aracılığıyla vardır:

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

statik başlatıcılar - Perl derleme ve nesnenin hemen hemen her aşamasında kod çalıştırabilirsiniz 151960920 '(kod ayrıştırma) CHECK (kod ayrıştırma sonra) import (modül içe aktarma) new (nesne örneği) DESTROY (nesne imha) END (program çıkışı)

işlevleri birinci sınıf vatandaşlardır - tıpkı Perl'de olduğu gibi

blok kapsamı ve kapatılması - Perl

arama yöntemleri ve dolaylı olarak değişkeniyle erişenler-Perl bunu da yapar:

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

kod ile yöntemleri tanımlama - Perl de izin verir:

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

Pervasive online documentation - Perl documentation is online and likely on your system too

sihirli yöntemler "nonexisting" işlevini çağırdığınızda çağrılır - Perl, AUTOLOAD işlevinde

uygular

sembolik referanslar - bunlardan uzak durmanız önerilir. çocuklarınızı yiyeceklerdir. ama tabii ki, Perl kana susamış iblislere çocuklarınızı sunmak için izin verir.

one line value swapping - Perl, liste atamasına izin verir

kendi işlevselliği ile bile çekirdek fonksiyonları yerine yeteneği

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

veya

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

unlink($_) for @ARGV
36
cevap Corion 2017-05-23 15:10:36
kaynak

Autovivification . AFAİK başka bir dil yok .

35
cevap J.J. 2008-10-02 17:48:56
kaynak

Perl'de neredeyse her türlü garip dizeyi alıntı yapmak basit.

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

aslında, Perl çeşitli alıntı mekanizmaları oldukça ilginç. Perl regex benzeri alıntı mekanizmaları, sınırlayıcıları belirterek herhangi bir şey teklif etmenize izin verir. # , / Veya (), [] veya {} gibi açık/kapalı karakterler gibi hemen hemen her özel karakteri kullanabilirsiniz. Örnekler:

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

alıntı mekanizmaları:

s: literal alıntı; kaçması gereken tek karakter son karakterdir. qq: yorumlanmış bir alıntı; değişkenleri işler ve karakterleri kaçış. Alıntı yapmanız gereken dizeler için harika:

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

qx: qq gibi çalışır, ancak daha sonra etkileşimli olmayan bir sistem komutu olarak yürütür. Standarttan oluşturulan tüm metni döndürür. (Yönlendirme, işletim sisteminde destekleniyorsa, aynı zamanda ortaya çıkar) geri alıntılar (`karakter) ile de yapılır.

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

qr: QQ gibi yorumlar, ancak daha sonra düzenli bir ifade olarak derler. De normal bir çeşitli seçenekleri ile çalışır. Şimdi regex'i bir değişken olarak geçirebilirsiniz:

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: çok, çok kullanışlı bir alıntı operatörü. Bir liste içine boşluk ayrılmış kelimelerin alıntı kümesi döner. Bir birim testinde verileri doldurmak için harika.


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

şeyleri daha net hale getirdiğinde onları kullanmak harikalar. Qx için, qq, ve q, Büyük olasılıkla {} operatörlerini kullanıyorum. Qw'yi kullanan insanların en yaygın alışkanlığı genellikle () operatörüdür, ancak bazen de qw// ' yi de görürsünüz.

31
cevap Robert P 2009-08-24 01:47:27
kaynak

gerçekten gizli değil, ama birçok her gün Perl programcılar CPAN hakkında bilmiyorum . Bu, özellikle tam zamanlı programcılar olmayan veya tam zamanlı olarak programlamayan kişiler için geçerlidir.

27
cevap mpeters 2009-03-19 02:26:31
kaynak

"for" ifadesi Pascal'da " ile " aynı şekilde kullanılabilir:

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

s/// işlemleri, vb bir dizi uygulayabilirsiniz. değişken adını tekrarlamak zorunda kalmadan aynı değişkene.

Not: Yukarıdaki kırılma dışı alan ( ), Markdown'u aşmak için Unicode gizledi. Yapıştırmayın :)

27
cevap timkay 2009-08-24 01:43:58
kaynak

quoteword operatörü en sevdiğim şeylerden biridir. Karşılaştırmak:

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

ve

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

çok daha az gürültü, göze daha kolay. Perl hakkında bir başka gerçekten güzel şey, SQL yazarken gerçekten özlüyor, bir son virgülün yasal olmasıdır:

print 1, 2, 3, ;

garip görünüyor, ancak kodu başka bir şekilde girerseniz değil:

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

ek bir argüman ekleme işlev çağrısı, önceki veya sondaki satırlardaki virgüllerle dolaşmanızı gerektirmez. Tek satır değişikliği çevreleyen çizgileri üzerinde hiçbir etkisi yoktur.

bu, değişken işlevlerle çalışmayı çok keyifli hale getirir. Bu belki de Perl'in en düşük puan alan özelliklerinden biridir.

26
cevap dland 2008-10-02 20:54:51
kaynak

doğrudan bir veri bloğuna yapıştırılan verileri ayrıştırma yeteneği. Programda veya benzer şekilde açılacak bir test dosyasına kaydetmenize gerek yok. Örneğin:

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

__DATA__
some good data
some bad data
more good data 
more good data 
26
cevap 2 revs, 2 users 93%allan 2009-08-24 01:42:09
kaynak

Yeni Blok İşlemleri

dili genişletme, sözde blok işlemleri oluşturma yeteneğinin bir olduğunu söyleyebilirim.

  1. önce bir kod referansı aldığını belirten bir alt prototip beyan edersiniz:

    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. daha sonra

    gibi vücutta arayabilirsiniz
    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 ıs başka bir yarı gizli mücevher.) Blok önünde sub anahtar sözcüğüne veya karma öncesi virgüle nasıl ihtiyacınız olmadığına dikkat edin. Çok gibi görünüyor biter: map { } @list

Kaynak Filtreleri

ayrıca, kaynak filtreler vardır. Nerede Perl bunu manipüle böylece kodu geçecek. Hem bu, hem de blok işlemleri, evdeki bu tür şeyleri denemiyorlar.

bazı düzgün şeyler yaptım kaynak filtreler, örneğin zamanı kontrol etmek için çok basit bir dil oluşturmak gibi, bazı karar verme için kısa Perl tek gömlekleri sağlar:

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

Lib::TL , hem "değişkenler" hem de sabitleri tarar, bunları oluşturur ve gerektiğinde yerine geçer.

yine, kaynak filtreleri dağınık olabilir, ancak güçlüdür. Ancak hata ayıklayıcıları korkunç bir şey haline getirebilirler-ve hatta uyarılar yanlış satır numaralarıyla basılabilir. Damian'ın anahtarını kullanmayı bıraktım, çünkü hata ayıklayıcı bana gerçekten nerede olduğumu söyleme yeteneğini kaybedecekti. Ancak, küçük kod bölümlerini değiştirerek, aynı çizgide tutarak hasarı en aza indirebileceğinizi buldum.

Sinyal Kancası

genellikle yeterince yapılır, ancak hepsi bu kadar açık değildir. İşte eski domuzcuk sırtında bir kalıp işleyicisi.

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

anlamına gelir. koddaki diğer bazı modül ölmek istiyor, size gelmelidirler (başkası $SIG{__DIE__} üzerinde yıkıcı bir etki yapmazsa). Bir şey düzgün çalışmıyor ve ne olduğundan emin değiliz.

tabii ki, yeterli şeyler için sadece bir END { } blok kullanabilirsiniz, yapmanız gereken tek şey temizlemek ise.

overload::constant

modülünüzü içeren paketlerde belirli bir türün litrelerini inceleyebilirsiniz. İçinde örnek, bunu import alt kısmında kullanırsanız:

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

arama paketlerinde 2 milyardan büyük her tamsayının Math::BigInt nesnesi olarak değiştirileceği anlamına gelecektir. (Bkz. aşırı yük:: sabit ).

Gruplandırılmış Tamsayı Değişmez Değerleri

biz oradayken. Perl, çok sayıda üç basamaklı gruba ayrılmanıza ve hala ayrıştırılabilir bir tamsayı elde etmenize olanak tanır. Not 2_000_000_000 2 milyar için yukarıda.

24
cevap Axeman 2009-08-24 01:53:26
kaynak

ikili " X " tekrarlama operatörü :

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

aynı zamanda listelerle çalışır:

print for (1, 4, 9) x 3; # print 149149149
24
cevap Bruno De Fraine 2010-03-19 20:01:19
kaynak

Taint kontrolü. Taint denetimi etkinleştirildiğinde, kusurlu verileri (kabaca konuşan, programın dışından gelen verileri) güvenli olmayan bir işleve (bir dosyayı açma, harici bir komut çalıştırma vb.) geçmeye çalışırsanız, Perl ölür (veya -t ile uyarılır).). Setuid komut dosyaları veya cgıs veya komut dosyasının veri besleyen kişiden daha büyük ayrıcalıklara sahip olduğu bir şey yazarken çok yararlıdır.

Magic goto. goto &sub optimize edilmiş bir kuyruk çağrısı yapar.

hata ayıklayıcı.

use strict ve use warnings . Bunlar bir sürü yazım hatası sizi kurtarabilir.

24
cevap Glomek 2010-03-19 20:03:18
kaynak

, "-n" ve "-p" anahtarlarının Perl 5'te uygulanmasıyla, }{ de dahil olmak üzere görünüşte yanlış bir program yazabilirsiniz :

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

DAHİLİ olarak bu koda dönüştürülür:

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}
22
cevap Sec 2008-10-09 17:44:22
kaynak

uzay gemisi operatörü ile kolay başlayalım.

$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
cevap Sec 2008-10-02 16:09:33
kaynak

bu bir meta cevap, ancak Perl ipuçları arşivleri Perl ile yapılabilir ilginç hileler her türlü içerir. Önceki ipuçları arşiv tarama için On-line olduğunu ve posta listesi veya atom feed üzerinden abone olabilir.

en sevdiğim ipuçlarından bazıları , , , , , ve ve Smart-match yapılarını Perl 5.10'da değiştirin.

Açıklama: Perl ipuçlarının yazarlarından ve koruyucularından biriyim, bu yüzden açıkçası çok fazla düşünüyorum. ;)

18
cevap pjf 2008-10-02 17:30:52
kaynak

' - sadece kişinin kodunu daha etkileyici hale getirdiği için değil, aynı zamanda bana bu "işlevsel programlama"hakkında biraz daha fazla okumak için bir dürtü verdi.

18
cevap brunorc 2009-08-24 01:56:23
kaynak

döngüler üzerinde devam yan tümcesi. Her döngünün alt kısmında, hatta bir sonraki döngüde idam edilecektir.

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
cevap Shawn H Corey 2008-10-04 06:29:35
kaynak

oyum (?{}) ve (??{}) perl'in düzenli ifadelerindeki gruplar. İlk Perl kodunu yürütür, return değerini yoksayar, ikinci dönüş değerini normal bir ifade olarak kullanarak kodu yürütür.

15
cevap Leon Timmermans 2009-08-24 01:53:59
kaynak
while(/\G(\b\w*\b)/g) {
     print "\n";
}

\ g çapa. sıcak .

13
cevap J.J. 2008-10-02 18:25:00
kaynak

m// operatörü bazı belirsiz özel durumlar vardır:

  • sınırlayıcı olarak ? kullanırsanız, reset dediğiniz sürece yalnızca bir kez eşleşir .
  • sınırlayıcı olarak ' kullanırsanız desen enterpolasyon değildir.
  • desen boş ise son başarılı maçtan desen kullanır.
13
cevap Michael Carman 2010-11-11 18:35:59
kaynak

null filehandle elmas operatörü <> komut satırı araçları inşa yerini alır. <FH> gibi davranır bir tutamaçtan okumak, ancak önce hangisi bulunuyorsa sihirli bir şekilde seçer: komut satırı dosya adları veya STDİN. Perlop alınan:

while (<>) {
...         # code for each line
}
12
cevap spoulson 2008-10-02 17:06:18
kaynak

özel kod blokları gibi BEGIN , CHECK ve END . Awk'den geliyorlar, ancak perl'de farklı çalışıyorlar, çünkü kayıt tabanlı değil.

BEGIN blok ayrıştırma aşaması için bazı kod belirtmek için kullanılabilir; sözdizimi ve değişken denetimi perl -c yaptığınızda da yürütülür . Örneğin, yapılandırma değişkenlerinde yüklemek için:

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

verileri yeniden adlandırıyor.txt.veri parçası.txt kendimi tekrarlamak zorunda kalmadan.

11
cevap timkay 2008-10-02 21:12:40
kaynak

biraz belirsiz skaler bağlamı zorlayan tilde-tilde "operatör" dir.

print ~~ localtime;

ile aynıdır
print scalar localtime;

ve

farklı
print localtime;
10
cevap Sec 2008-10-02 16:42:14
kaynak

kravat, değişken bağlama arayüzü.

9
cevap davidnicol 2008-10-04 01:15:27
kaynak

perl'in döngü kontrol yapılarının "çaresizlik modu", eşleşen bir etiket bulmak için yığına bakmalarına neden olan bazı meraklı davranışlara izin verir:: daha iyi veya daha kötüsü için avantaj sağlar.

SKIP: {
    skip() if $something;

    print "Never printed";
}

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

az bilinen var.pmc dosyası. "foo kullan" Foo'yu arayacak.Foo önce @ İNC pmc.pm. Bu, derlenmiş bytecode'un ilk önce yüklenmesine izin vermek için tasarlanmıştır, ancak Modülü:: Compile bundan yararlanır daha hızlı yükleme süreleri ve daha kolay hata ayıklama için önbellek kaynağı filtrelenmiş modüller.

hataları içine uyarıları açmak için yeteneği.

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

söz edilmemiş kafamın tepesinden düşünebildiğim şey bu.

9
cevap Schwern 2008-10-15 19:13:09
kaynak

goatse operatörü * :

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

veya

sub foo {
    return @_;
}

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

skaler bağlamında liste atama atanan listedeki öğelerin sayısını verir çünkü çalışır.

* not, gerçekten bir operatör değil

9
cevap Chas. Owens 2009-05-31 07:13:52
kaynak

Diğer sorular perl hidden-features