Ito ang command perlref na maaaring patakbuhin sa OnWorks free hosting provider gamit ang isa sa aming maramihang libreng online na workstation gaya ng Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator
PROGRAMA:
NAME
perlref - Mga sangguniang Perl at mga nested na istruktura ng data
NOTA
Ito ay kumpletong dokumentasyon tungkol sa lahat ng aspeto ng mga sanggunian. Para sa isang mas maikling, tutorial
panimula sa mga mahahalagang tampok lamang, tingnan ang perlreftut.
DESCRIPTION
Bago ilabas ang 5 ng Perl, mahirap kumatawan sa mga kumplikadong istruktura ng data, dahil
lahat ng mga sanggunian ay kailangang maging simboliko--at kahit na noon ay mahirap na sumangguni sa isang variable
sa halip na isang entry sa talahanayan ng simbolo. Ang Perl ngayon ay hindi lamang ginagawang mas madali ang paggamit ng simboliko
mga sanggunian sa mga variable, ngunit nagbibigay-daan din sa iyong magkaroon ng "mahirap" na mga sanggunian sa anumang piraso ng data o
code. Anumang scalar ay maaaring magkaroon ng isang hard reference. Dahil ang mga array at hash ay naglalaman ng mga scalar,
madali ka na ngayong makabuo ng mga arrays ng arrays, arrays ng mga hash, hash ng arrays, arrays ng
hash ng mga function, at iba pa.
Ang mga mahirap na sanggunian ay matalino--sinusubaybayan nila ang mga bilang ng sanggunian para sa iyo, awtomatiko
pagpapalaya sa bagay na tinutukoy kapag ang bilang ng sanggunian nito ay naging zero. (Bilang ng sanggunian
para sa mga value sa self-referential o cyclic data structures ay maaaring hindi pumunta sa zero nang walang a
kaunting tulong; tingnan ang "Circular References" para sa isang detalyadong paliwanag.) Kung nangyari ang bagay na iyon
upang maging isang bagay, ang bagay ay nasisira. Tingnan ang perlobj para sa higit pa tungkol sa mga bagay. (Sa isang
pakiramdam, lahat ng bagay sa Perl ay isang bagay, ngunit karaniwan naming inilalaan ang salita para sa mga sanggunian
mga bagay na opisyal na "pinagpala" sa isang pakete ng klase.)
Ang mga simbolikong sanggunian ay mga pangalan ng mga variable o iba pang mga bagay, bilang isang simbolikong link sa a
Ang Unix filesystem ay naglalaman lamang ng pangalan ng isang file. Ang *glob notation ay isang bagay ng a
simbolikong sanggunian. (Ang mga simbolikong sanggunian ay tinatawag minsan na "malambot na sanggunian", ngunit
mangyaring huwag tumawag sa kanila na; Ang mga sanggunian ay sapat na nakakalito nang walang walang silbi na kasingkahulugan.)
Sa kabaligtaran, ang mga hard reference ay mas katulad ng mga hard link sa isang Unix file system: Ginagamit ang mga ito
upang ma-access ang isang pinagbabatayan na bagay nang walang pag-aalala sa kung ano ang (iba pang) pangalan nito. Kapag ang
ang salitang "sanggunian" ay ginagamit nang walang pang-uri, tulad ng sa sumusunod na talata, ito ay
karaniwang pinag-uusapan ang isang mahirap na sanggunian.
Ang mga sanggunian ay madaling gamitin sa Perl. Mayroon lamang isang pangunahing prinsipyo: sa pangkalahatan,
Walang implicit na pagre-refer o dereferencing ang Perl. Kapag ang isang scalar ay may hawak na sanggunian,
ito ay palaging kumikilos bilang isang simpleng scalar. Hindi ito magically magsimula sa pagiging isang array o hash
o subroutine; kailangan mong sabihin ito nang tahasan upang gawin ito, sa pamamagitan ng pag-dereferencing dito.
Iyon ay sinabi, magkaroon ng kamalayan na ang Perl bersyon 5.14 ay nagpapakilala ng isang pagbubukod sa panuntunan, para sa
kaginhawaan ng syntactic. Ang pang-eksperimentong array at pag-uugali ng hash container ay nagbibigay-daan
array at hash na mga sanggunian na pangasiwaan ng Perl na parang tahasan ang mga ito
syntactically dereferenced. Tingnan ang "Mga Syntactical Enhancement" sa perl5140delta at perlfunc
para sa mga detalye.
Paggawa Mga sanggunian
Ang mga sanggunian ay maaaring gawin sa maraming paraan.
1. Sa pamamagitan ng paggamit ng backslash operator sa isang variable, subroutine, o value. (Ito ay gumagana nang labis
tulad ng & (address-of) operator sa C.) Ito ay karaniwang lumilikha isa pa sanggunian sa a
variable, dahil mayroon nang reference sa variable sa symbol table.
Ngunit ang reference ng simbolo ng talahanayan ay maaaring mawala, at magkakaroon ka pa rin ng reference na iyon
bumalik ang backslash. Narito ang ilang halimbawa:
$scalarref = \$foo;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*foo;
Hindi posibleng gumawa ng totoong reference sa isang IO handle (filehandle o dirhandle)
gamit ang backslash operator. Ang pinakamaraming makukuha mo ay isang reference sa isang typeglob,
na talagang isang kumpletong entry ng talahanayan ng simbolo. Ngunit tingnan ang paliwanag ng
*foo{THING} syntax sa ibaba. Gayunpaman, maaari mo pa ring gamitin ang mga uri ng glob at globref bilang
kahit na sila ay IO handles.
2. Maaaring gumawa ng reference sa isang hindi kilalang array gamit ang mga square bracket:
$arrayref = [1, 2, ['a', 'b', 'c']];
Dito nakagawa kami ng reference sa isang hindi kilalang hanay ng tatlong elemento na ang pangwakas
Ang elemento mismo ay isang sanggunian sa isa pang hindi kilalang hanay ng tatlong elemento. (Ang
Maaaring gamitin ang multidimensional syntax na inilarawan sa ibang pagkakataon upang ma-access ito. Halimbawa,
pagkatapos ng nasa itaas, ang "$arrayref->[2][1]" ay magkakaroon ng value na "b".)
Ang pagkuha ng reference sa isang enumerated list ay hindi katulad ng paggamit ng square
bracket--sa halip ito ay kapareho ng paggawa ng listahan ng mga sanggunian!
@list = (\$a, \@b, \%c);
@list = \($a, @b, %c); # parehas na bagay!
Bilang isang espesyal na kaso, ang "\(@foo)" ay nagbabalik ng isang listahan ng mga sanggunian sa mga nilalaman ng @foo, hindi
isang sanggunian sa @foo mismo. Gayundin para sa %foo, maliban na ang mga pangunahing sanggunian ay sa
mga kopya (dahil ang mga susi ay mga string lamang sa halip na ganap na mga scalar).
3. Maaaring gumawa ng reference sa isang hindi kilalang hash gamit ang mga curly bracket:
$hashref = {
'Adan' => 'Eba',
'Clyde' => 'Bonnie',
};
Ang mga anonymous na hash at array composers na tulad nito ay maaaring malayang ihalo upang makagawa bilang
kumplikado ang isang istraktura ayon sa gusto mo. Ang multidimensional na syntax na inilarawan sa ibaba
gumagana din para sa mga ito. Ang mga halaga sa itaas ay mga literal, ngunit mga variable at expression
gagana rin, dahil ang mga operator ng pagtatalaga sa Perl (kahit na sa loob lokal() or
aking()) ay mga executable na statement, hindi compile-time na mga deklarasyon.
Dahil ang mga kulot na bracket (braces) ay ginagamit para sa ilang iba pang mga bagay kabilang ang mga BLOCK,
maaaring kailanganin mong idismbiguate paminsan-minsan ang mga braces sa simula ng isang pahayag ni
paglalagay ng "+" o "return" sa unahan para malaman ni Perl na ang opening brace ay hindi
nagsisimula ng BLOCK. Ang ekonomiya at mnemonic na halaga ng paggamit ng mga kulot ay itinuturing na sulit
itong paminsan-minsang dagdag na abala.
Halimbawa, kung gusto mong gumawa ng bagong hash ang isang function at magbalik ng reference dito,
mayroon kang mga pagpipiliang ito:
sub hashem { { @_ } } # tahimik na mali
sub hashem { +{ @_ } } # ok
sub hashem { return { @_ } } # ok
Sa kabilang banda, kung gusto mo ng ibang kahulugan, magagawa mo ito:
sub showem { { @_ } } # hindi maliwanag (kasalukuyang ok,
# ngunit maaaring magbago)
sub showem { {; @_ } } # okay
sub showem { { return @_ } } # ok
Ang nangungunang "+{" at "{;" palaging nagsisilbi upang i-disambiguate ang expression na ibig sabihin ng alinman
ang HASH reference, o ang BLOCK.
4. Ang isang reference sa isang hindi kilalang subroutine ay maaaring gawin sa pamamagitan ng paggamit ng "sub" nang walang a
subname:
$coderef = sub { print "Boink!\n" };
Tandaan ang semicolon. Maliban sa code sa loob na hindi agad naisakatuparan, isang "sub
Ang {}" ay hindi gaanong deklarasyon kundi isa itong operator, tulad ng "do{}" o "eval{}".
(Gayunpaman, gaano man karaming beses mong isagawa ang partikular na linyang iyon (maliban kung ikaw ay nasa
isang "eval("...")"), ang $coderef ay magkakaroon pa rin ng reference sa pareho hindi kilala
subroutine.)
Ang mga hindi kilalang subroutine ay gumaganap bilang mga pagsasara patungkol sa aking() mga variable, iyon ay,
mga variable na leksikal na nakikita sa loob ng kasalukuyang saklaw. Ang pagsasara ay isang paniwala sa labas ng
Lisp world na nagsasabing kung tutukuyin mo ang isang anonymous na function sa isang partikular na lexical
konteksto, nagpapanggap itong tumatakbo sa kontekstong iyon kahit na ito ay tinatawag sa labas ng konteksto.
Sa mga termino ng tao, ito ay isang nakakatawang paraan ng pagpasa ng mga argumento sa isang subroutine kapag tinukoy mo
ito pati na rin kapag tinawag mo ito. Ito ay kapaki-pakinabang para sa pag-set up ng maliit na piraso ng code na tatakbo
mamaya, tulad ng mga callback. Maaari ka ring gumawa ng bagay na nakatuon sa object dito, kahit na Perl
nagbibigay na ng ibang mekanismo para gawin iyon--tingnan ang perlobj.
Maaari mo ring isipin ang pagsasara bilang isang paraan upang magsulat ng subroutine na template nang hindi gumagamit
eval(). Narito ang isang maliit na halimbawa kung paano gumagana ang mga pagsasara:
sub newprint {
aking $x = shift;
ibalik ang sub { my $y = shift; i-print ang "$x, $y!\n"; };
}
$h = newprint("Kamusta");
$g = newprint("Pagbati");
# Lumilipas ang oras...
&$h("mundo");
&$g("earthlings");
Ito ay nagpi-print
Kamusta, mundo!
Pagbati, mga taga-lupa!
Tandaan partikular na ang $x ay patuloy na tumutukoy sa halagang ipinasa newprint()
sa kabila ng "my $x" na nawala sa saklaw sa oras na tumakbo ang anonymous na subroutine.
Iyan ang ibig sabihin ng pagsasara.
Nalalapat lang ito sa mga lexical na variable. Patuloy ang mga dynamic na variable
magtrabaho gaya ng dati nilang ginagawa. Ang pagsasara ay hindi isang bagay na karamihan sa mga programmer ng Perl
kailangan ng problema sa kanilang sarili sa simula.
5. Ang mga sanggunian ay kadalasang ibinabalik ng mga espesyal na subroutine na tinatawag na mga constructor. Perl
Ang mga bagay ay mga sanggunian lamang sa isang espesyal na uri ng bagay na nangyayari na alam kung alin
package na nauugnay dito. Ang mga konstruktor ay mga espesyal na subroutine lamang na alam kung paano
upang lumikha ng asosasyong iyon. Ginagawa nila ito sa pamamagitan ng pagsisimula sa isang ordinaryong sanggunian, at ito
nananatiling isang ordinaryong sanggunian kahit na ito ay isang bagay din. Ang mga konstruktor ay
madalas na pinangalanang "bago ()". Ikaw maaari tawagan sila nang hindi direkta:
$objref = bagong Doggie( Buntot => 'maikli', Tenga => 'mahaba' );
Ngunit maaari itong makagawa ng hindi maliwanag na syntax sa ilang partikular na kaso, kaya madalas itong mas mahusay na gamitin
ang direktang paraan ng invocation approach:
$objref = Doggie->new(Tail => 'maikli', Ears => 'mahaba');
gamitin ang Termino::Cap;
$terminal = Termino::Cap->Tgetent( { OSPEED => 9600 });
gumamit ng Tk;
$main = MainWindow->new();
$menubar = $main->Frame(-relief => "itinaas",
-borderwidth => 2)
6. Ang mga sanggunian na may naaangkop na uri ay maaaring umiral kung hindi mo sila sanggunian
sa isang konteksto na ipinapalagay na sila ay umiiral. Dahil hindi namin napag-usapan ang tungkol sa dereferencing
gayunpaman, hindi pa kami makapagpapakita sa iyo ng anumang mga halimbawa.
7. Maaaring gumawa ng sanggunian sa pamamagitan ng paggamit ng isang espesyal na syntax, na buong pagmamahal na kilala bilang ang
*foo{THING} syntax. *foo{THING} ay nagbabalik ng reference sa THING slot sa *foo (which
ay ang simbolong table entry na nagtataglay ng lahat ng kilala bilang foo).
$scalarref = *foo{SCALAR};
$arrayref = *ARGV{ARRAY};
$hashref = *ENV{HASH};
$coderef = *handler{CODE};
$ioref = *STDIN{IO};
$globref = *foo{GLOB};
$formatref = *foo{FORMAT};
$globname = *foo{NAME}; # "foo"
$pkgname = *foo{PACKAGE}; # "pangunahing"
Karamihan sa mga ito ay nagpapaliwanag sa sarili, ngunit ang *foo{IO} ay nararapat na espesyal na atensyon. Ito
ibinabalik ang hawakan ng IO, na ginagamit para sa mga hawakan ng file ("bukas" sa perlfunc), mga socket ("socket"
sa perlfunc at "socketpair" sa perlfunc), at directory handles ("opendir" sa
perlfunc). Para sa pagiging tugma sa mga nakaraang bersyon ng Perl, ang *foo{FILEHANDLE} ay a
kasingkahulugan ng *foo{IO}, bagama't hindi na ito ginagamit noong 5.8.0. Kung ang mga babala sa paghinto sa paggamit
ay may bisa, babalaan nito ang paggamit nito.
*foo{THING} ay nagbabalik ng undef kung ang partikular na BAGAY na iyon ay hindi pa nagagamit, maliban sa
kaso ng mga scalar. Ang *foo{SCALAR} ay nagbabalik ng reference sa isang hindi kilalang scalar kung $foo
hindi pa nagagamit. Maaaring magbago ito sa isang release sa hinaharap.
Ang *foo{NAME} at *foo{PACKAGE} ay ang exception, sa halip ay nagbabalik sila ng mga string
kaysa sa mga sanggunian. Ibinabalik ng mga ito ang pakete at pangalan ng typeglob mismo, sa halip
kaysa sa isa na itinalaga dito. Kaya, pagkatapos ng "*foo=*Foo::bar", ang *foo ay magiging
"*Foo::bar" kapag ginamit bilang isang string, ngunit ang *foo{PACKAGE} at *foo{NAME} ay magpapatuloy sa
gumawa ng "pangunahing" at "foo", ayon sa pagkakabanggit.
Ang *foo{IO} ay isang alternatibo sa *HANDLE na mekanismo na ibinigay sa "Typeglobs and
Filehandles" sa perldata para sa pagpasa ng mga filehandles papasok o palabas ng mga subroutine, o
pag-iimbak sa mas malalaking istruktura ng data. Ang kawalan nito ay hindi ito gagawa ng bago
filehandle para sa iyo. Ang kalamangan nito ay mas kaunti ang iyong panganib na mag-clobbering nang higit pa kaysa
gusto mo sa isang typeglob assignment. (Pinagsasama-sama pa rin nito ang file at direktoryo
humahawak, bagaman.) Gayunpaman, kung itatalaga mo ang papasok na halaga sa isang scalar sa halip na a
typeglob gaya ng ginagawa namin sa mga halimbawa sa ibaba, walang panganib na mangyari iyon.
splutter(*STDOUT); # pumasa sa buong glob
splutter(*STDOUT{IO}); # ipasa ang parehong file at dir handle
sub splutter {
aking $fh = shift;
print $fh "her um well a hmmm\n";
}
$rec = get_rec(*STDIN); # pumasa sa buong glob
$rec = get_rec(*STDIN{IO}); # ipasa ang parehong file at dir handle
sub get_rec {
aking $fh = shift;
ibalik ang scalar <$fh>;
}
paggamit Mga sanggunian
Iyon lang para sa paggawa ng mga sanggunian. Sa ngayon, malamang na naghihingalo ka nang malaman kung paano gamitin
mga sanggunian upang makabalik sa iyong data na matagal nang nawala. Mayroong ilang mga pangunahing pamamaraan.
1. Kahit saan ka maglalagay ng identifier (o chain of identifier) bilang bahagi ng variable o
pangalan ng subroutine, maaari mong palitan ang identifier ng isang simpleng scalar variable
naglalaman ng isang sanggunian ng tamang uri:
$bar = $$scalarref;
push(@$arrayref, $filename);
$$arrayref[0] = "Enero";
$$hashref{"KEY"} = "VALUE";
&$coderef(1,2,3);
print $globref "output\n";
Mahalagang maunawaan na tayo ay partikular hindi dereferencing $arrayref[0]
o $hashref{"KEY"} doon. Ang dereference ng scalar variable ay nangyayari bago it
gumagawa ng anumang key lookup. Anumang bagay na mas kumplikado kaysa sa isang simpleng scalar variable ay dapat
gumamit ng mga pamamaraan 2 o 3 sa ibaba. Gayunpaman, ang isang "simpleng scalar" ay may kasamang identifier na
mismo ay gumagamit ng pamamaraan 1 nang paulit-ulit. Samakatuwid, ang mga sumusunod na kopya ay "kumusta".
$refrefref = \\\"kamusta";
i-print ang $$$$refref;
2. Kahit saan ka maglalagay ng identifier (o chain of identifier) bilang bahagi ng variable o
subroutine name, maaari mong palitan ang identifier ng isang BLOCK na nagbabalik ng reference ng
ang tamang uri. Sa madaling salita, ang mga nakaraang halimbawa ay maaaring isulat tulad nito:
$bar = ${$scalarref};
push(@{$arrayref}, $filename);
${$arrayref}[0] = "Enero";
${$hashref}{"KEY"} = "VALUE";
&{$coderef}(1,2,3);
$globref->print("output\n"); # iff IO::Naka-load ang hawakan
Totoo, medyo kalokohan ang paggamit ng mga kulot sa kasong ito, ngunit ang BLOCK ay maaari
naglalaman ng anumang di-makatwirang expression, sa partikular, mga naka-subscript na expression:
&{ $dispatch{$index} }(1,2,3); # tawag sa tamang gawain
Dahil sa kakayahang alisin ang mga kulot para sa simpleng kaso ng $$x, madalas ang mga tao
magkamali sa pagtingin sa mga simbolo ng dereferencing bilang mga wastong operator, at magtaka
tungkol sa kanilang precedence. Kung sila, gayunpaman, maaari kang gumamit ng mga panaklong sa halip na
braces. Hindi ganoon ang kaso. Isaalang-alang ang pagkakaiba sa ibaba; ang case 0 ay isang short-hand
bersyon ng case 1, hindi kaso 2:
$$hashref{"KEY"} = "VALUE"; # KASO 0
${$hashref}{"KEY"} = "VALUE"; # KASO 1
${$hashref{"KEY"}} = "VALUE"; # KASO 2
${$hashref->{"KEY"}} = "VALUE"; # KASO 3
Mapanlinlang din ang Case 2 dahil ina-access mo ang isang variable na tinatawag na %hashref, hindi
dereferencing sa pamamagitan ng $hashref sa hash na ito ay malamang na tumutukoy. Iyon ay
kaso 3.
3. Ang mga subroutine na tawag at paghahanap ng mga indibidwal na elemento ng array ay madalas na lumilitaw upang ito
nagiging mahirap gamitin ang paraan 2. Bilang isang anyo ng syntactic sugar, ang mga halimbawa para sa
paraan 2 ay maaaring isulat:
$arrayref->[0] = "Enero"; # Array na elemento
$hashref->{"KEY"} = "VALUE"; # Hash na elemento
$coderef->(1,2,3); # Subroutine na tawag
Ang kaliwang bahagi ng arrow ay maaaring maging anumang expression na nagbabalik ng reference, kabilang ang a
nakaraang dereference. Tandaan na ang $array[$x] ay hindi ang parehong bagay bilang "$array->[$x]"
dito:
$array[$x]->{"foo"}->[0] = "Enero";
Isa ito sa mga kaso na binanggit namin kanina kung saan maaaring magkaroon ng mga sanggunian
pagkakaroon kapag nasa konteksto ng halaga. Bago ang pahayag na ito, maaaring naging $array[$x].
hindi natukoy. Kung gayon, awtomatiko itong tinutukoy gamit ang isang hash reference para magawa natin
hanapin ang "{"foo"}" dito. Gayundin ang "$array[$x]->{"foo"}" ay awtomatikong makukuha
tinukoy gamit ang isang sanggunian ng array upang maaari naming hanapin ang "[0]" dito. Ang prosesong ito ay
tinatawag autovivification.
Isa pa dito. Ang arrow ay opsyonal sa pagitan ng mga bracket na subscript, para magawa mo
paliitin ang nasa itaas pababa sa
$array[$x]{"foo"}[0] = "Enero";
Na, sa lumalalang kaso ng paggamit lamang ng mga ordinaryong array, ay nagbibigay sa iyo
multidimensional arrays tulad ng C's:
$score[$x][$y][$z] += 42;
Well, okay, hindi ganap na katulad ng mga array ng C, talaga. Hindi alam ni C kung paano palaguin ito
arrays on demand. Ginagawa ni Perl.
4. Kung ang isang sanggunian ay isang sanggunian sa isang bagay, malamang na mayroong mga pamamaraan
upang ma-access ang mga bagay na tinutukoy, at malamang na dapat kang manatili sa mga pamamaraang iyon
maliban kung ikaw ay nasa class package na tumutukoy sa mga pamamaraan ng object. Sa ibang salita,
maging mabait, at huwag labagin ang encapsulation ng bagay nang walang napakagandang dahilan.
Ang Perl ay hindi nagpapatupad ng encapsulation. Hindi kami totalitarian dito. Inaasahan namin
ilang pangunahing pagkamagalang bagaman.
Ang paggamit ng string o numero bilang sanggunian ay gumagawa ng simbolikong sanggunian, gaya ng ipinaliwanag sa itaas.
Ang paggamit ng isang reference bilang isang numero ay gumagawa ng isang integer na kumakatawan sa lokasyon ng imbakan nito sa
alaala. Ang tanging kapaki-pakinabang na bagay na gagawin dito ay ang paghambingin ang dalawang sanggunian
ayon sa numero upang makita kung ang mga ito ay tumutukoy sa parehong lokasyon.
if ($ref1 == $ref2) { # murang numerong paghahambing ng mga sanggunian
i-print ang "ref 1 at 2 ay tumutukoy sa parehong bagay\n";
}
Ang paggamit ng reference bilang isang string ay gumagawa ng parehong uri ng referent nito, kasama ang anumang package
pagpapala tulad ng inilarawan sa perlobj, pati na rin ang numerong address na ipinahayag sa hex. Ang
ref() ibinabalik lamang ng operator ang uri ng bagay na itinuturo ng sanggunian, nang wala ang
tirahan. Tingnan ang "ref" sa perlfunc para sa mga detalye at mga halimbawa ng paggamit nito.
Ang pagpalain() operator ay maaaring gamitin upang iugnay ang bagay na isang reference point sa a
package na gumagana bilang isang object class. Tingnan ang perlobj.
Maaaring i-dereference ang isang typeglob sa parehong paraan na magagawa ng isang reference, dahil ang dereference
Ang syntax ay palaging nagpapahiwatig ng uri ng sanggunian na nais. Kaya pareho ang "${*foo}" at "${\$foo}".
ipahiwatig ang parehong scalar variable.
Narito ang isang trick para sa interpolation ng subroutine na tawag sa isang string:
print "Ang aking sub ay bumalik @{[mysub(1,2,3)]} sa oras na iyon.\n";
Ang paraan ng paggana nito ay kapag ang "@{...}" ay nakita sa double-quoted string, ito ay
sinusuri bilang isang bloke. Ang block ay lumilikha ng isang sanggunian sa isang hindi kilalang array na naglalaman ng
resulta ng tawag sa "mysub(1,2,3)". Kaya't ang buong bloke ay nagbabalik ng isang sanggunian sa isang
array, na pagkatapos ay i-dereference ng "@{...}" at dumikit sa double-quoted string.
Ang chicanery na ito ay kapaki-pakinabang din para sa mga arbitrary na expression:
print "Na nagbubunga ng @{[$n + 5]} widgets\n";
Katulad nito, ang isang expression na nagbabalik ng isang reference sa isang scalar ay maaaring i-dereference sa pamamagitan ng
"${...}". Kaya, ang expression sa itaas ay maaaring isulat bilang:
print "Na nagbubunga ng ${\($n + 5)} widgets\n";
Pabilog Mga sanggunian
Posibleng gumawa ng "circular reference" sa Perl, na maaaring humantong sa mga pagtagas ng memorya. A
Ang pabilog na sanggunian ay nangyayari kapag ang dalawang sanggunian ay naglalaman ng isang sanggunian sa isa't isa, tulad ng
ito:
aking $foo = {};
aking $bar = { foo => $foo };
$foo->{bar} = $bar;
Maaari ka ring lumikha ng isang pabilog na sanggunian na may iisang variable:
aking $foo;
$foo = \$foo;
Sa kasong ito, hindi kailanman aabot sa 0 ang bilang ng sanggunian para sa mga variable, at ang mga sanggunian
hindi kailanman mapupulot ng basura. Ito ay maaaring humantong sa mga pagtagas ng memorya.
Dahil ang mga bagay sa Perl ay ipinatupad bilang mga sanggunian, posibleng magkaroon ng pabilog
mga sanggunian na may mga bagay din. Isipin ang isang klase ng TreeNode kung saan ang bawat node ay tumutukoy nito
mga node ng magulang at anak. Ang anumang node na may magulang ay magiging bahagi ng isang circular reference.
Maaari mong sirain ang mga pabilog na sanggunian sa pamamagitan ng paggawa ng "mahina na sanggunian". Ang isang mahinang sanggunian ay ginagawa
hindi dagdagan ang bilang ng sanggunian para sa isang variable, na nangangahulugan na ang bagay ay maaaring lumabas
ng saklaw at masisira. Maaari mong pahinain ang isang reference gamit ang "weaken" function na na-export
sa pamamagitan ng Scalar::Util module.
Narito kung paano namin gagawing mas ligtas ang unang halimbawa:
gamitin ang Scalar::Util 'mahina';
aking $foo = {};
aking $bar = { foo => $foo };
$foo->{bar} = $bar;
pahinain ang $foo->{bar};
Ang reference mula sa $foo hanggang $bar ay humina. Kapag nawala ang $bar variable
saklaw, ito ay makokolekta ng basura. Sa susunod na titingnan mo ang halaga ng
"$foo->{bar}" key, ito ay magiging "undef".
Ang pagkilos na ito sa malayo ay maaaring nakakalito, kaya dapat kang maging maingat sa iyong paggamit ng
humina. Dapat mong pahinain ang reference sa variable na mawawala sa saklaw una.
Sa ganoong paraan, ang mas mahabang buhay na variable ay maglalaman ng inaasahang sanggunian hanggang sa mawala ito
ng saklaw.
Simbolo sanggunian
Sinabi namin na ang mga sanggunian ay umiral kung kinakailangan kung ang mga ito ay hindi natukoy, ngunit kami
ay hindi sinabi kung ano ang mangyayari kung ang isang halaga na ginamit bilang isang sanggunian ay tinukoy na, ngunit ay hindi a
mahirap na sanggunian. Kung gagamitin mo ito bilang isang sanggunian, ito ay ituturing bilang isang simbolikong sanggunian.
Iyon ay, ang halaga ng scalar ay kinuha na ang pangalan ng isang variable, sa halip na a
direktang link sa isang (posibleng) anonymous na halaga.
Madalas na inaasahan ng mga tao na ito ay gagana nang ganito. Kaya ginagawa nito.
$name = "foo";
$$pangalan = 1; # Sets $foo
${$pangalan} = 2; # Sets $foo
${$pangalan x 2} = 3; # Sets $foofoo
$name->[0] = 4; # Set $foo[0]
@$pangalan = (); # Nililinis ang @foo
&$pangalan(); # Mga tawag &foo()
$pack = "NA";
${"${pack}::$name"} = 5; # Sets $THAT::foo without eval
Ito ay makapangyarihan, at bahagyang mapanganib, sa kadahilanang ito ay posibleng magplano (nang sukdulan
sincerity) na gumamit ng hard reference, at hindi sinasadyang gumamit ng symbolic reference sa halip. Upang
protektahan laban diyan, masasabi mo
gumamit ng mahigpit na 'ref';
at pagkatapos ay ang mga mahirap na sanggunian lamang ang papayagan para sa natitirang bahagi ng kalakip na bloke. An
inner block ay maaaring countermand na may
walang mahigpit na 'ref';
Ang mga variable ng package lamang (mga pandaigdigan, kahit na naka-localize) ang nakikita ng mga simbolikong sanggunian.
Mga variable na leksikal (ipinahayag na may aking()) ay wala sa isang simbolo na talahanayan, at sa gayon ay hindi nakikita ng
mekanismong ito. Halimbawa:
lokal na $value = 10;
$ref = "halaga";
{
ang aking $value = 20;
i-print ang $$ref;
}
Magpi-print pa rin ito ng 10, hindi 20. Tandaan iyan lokal() nakakaapekto sa mga variable ng package, na
lahat ay "global" sa package.
Hindi-so-symbolic sanggunian
Ang mga bracket sa paligid ng isang simbolikong sanggunian ay maaaring magsilbi lamang upang ihiwalay ang isang identifier o variable
pangalan mula sa natitirang bahagi ng isang expression, tulad ng palagi nilang nasa loob ng isang string. Para sa
Halimbawa,
$push = "pop on";
i-print ang "${push}over";
ay palaging nilalayong i-print ang "pop on over", kahit na ang push ay isang nakalaan na salita. Ito ay
pangkalahatan upang gumana nang pareho nang walang kalakip na double quote, kaya na
i-print ang ${push} . "higit";
at kahit
i-print ang ${ push } . "higit";
magkakaroon ng parehong epekto. Ang construct na ito ay hindi itinuturing na isang simbolikong sanggunian
kapag gumagamit ka ng mahigpit na ref:
gumamit ng mahigpit na 'ref';
${ bareword }; # Okay, ibig sabihin ay $bareword.
${ "bareword" }; # Error, simbolikong sanggunian.
Katulad nito, dahil sa lahat ng pag-subscribe na ginagawa gamit ang mga solong salita, ang parehong panuntunan
nalalapat sa anumang bareword na ginagamit para sa pag-subscript ng hash. Kaya ngayon, sa halip na magsulat
$array{ "aaa" }{ "bbb" }{ "ccc" }
magsulat ka lang
$array{ aaa }{ bbb }{ ccc }
at huwag mag-alala kung ang mga subscript ay mga reserbang salita. Sa bihirang pangyayari na ikaw
gusto mong gumawa ng isang bagay tulad ng
$array{ shift }
maaari mong pilitin ang interpretasyon bilang isang nakalaan na salita sa pamamagitan ng pagdaragdag ng anumang bagay na ginagawang higit sa
isang bareword:
$array{ shift() }
$array{ +shift }
$array{ shift @_ }
Ang "use warnings" pragma o ang -w babalaan ka ng switch kung binibigyang-kahulugan nito ang isang nakalaan na salita
bilang isang string. Ngunit hindi ka na nito babalaan tungkol sa paggamit ng maliliit na salita, dahil ang
string ay epektibong sinipi.
Pseudo-hashes: paggamit an ayos as a sumira
Ang mga pseudo-hashes ay tinanggal mula sa Perl. Ang 'fields' pragma ay nananatiling magagamit.
tungkulin Template
Gaya ng ipinaliwanag sa itaas, isang anonymous na function na may access sa mga lexical na variable na nakikita
kapag na-compile ang function na iyon, lumilikha ng pagsasara. Pinapanatili nito ang access sa mga variable na iyon
kahit na hindi ito tatakbo hanggang sa ibang pagkakataon, tulad ng sa isang signal handler o isang Tk callback.
Ang paggamit ng pagsasara bilang template ng function ay nagbibigay-daan sa amin na bumuo ng maraming function na kumikilos
katulad. Ipagpalagay na gusto mo ng mga function na ipinangalan sa mga kulay na nakabuo ng HTML font
mga pagbabago para sa iba't ibang kulay:
print "Maging ", red("ingat"), "with that ", green("light");
Ang pula() at berde() ang mga pag-andar ay magiging magkatulad. Upang gawin ang mga ito, magtatalaga kami ng pagsasara
sa isang typeglob ng pangalan ng function na sinusubukan naming buuin.
@colors = qw(pula asul berde dilaw orange lilang violet);
para sa aking $name (@colors) {
walang mahigpit na 'ref'; # payagan ang pagmamanipula ng talahanayan ng simbolo
*$pangalan = *{uc $pangalan} = sub { " @_ " };
}
Ngayon ang lahat ng iba't ibang mga pag-andar na iyon ay lumilitaw na umiiral nang nakapag-iisa. Pwede kang tumawag pula(),
RED(), bughaw(), ASUL(), berde(), atbp. Ang diskarteng ito ay nakakatipid sa parehong oras ng pag-compile at memorya
gamitin, at hindi gaanong madaling kapitan ng error, dahil ang mga pagsusuri sa syntax ay nangyayari sa oras ng pag-compile. ito ay
kritikal na ang anumang mga variable sa anonymous na subroutine ay mga lexical upang lumikha ng a
tamang pagsasara. Iyan ang mga dahilan para sa "aking" sa variable na pag-ulit ng loop.
Ito ay isa sa mga tanging lugar kung saan ang pagbibigay ng prototype sa isang pagsasara ay may katuturan. Kung
gusto mong magpataw ng kontekstong scalar sa mga argumento ng mga function na ito (marahil hindi a
matalinong ideya para sa partikular na halimbawang ito), maaari mo na lang itong isulat sa ganitong paraan:
*$pangalan = sub ($) { " $_[0] " };
Gayunpaman, dahil nangyayari ang pagsusuri ng prototype sa oras ng pag-compile, nangyayari ang pagtatalaga sa itaas
huli na para magkaroon ng malaking pakinabang. Maaari mong tugunan ito sa pamamagitan ng paglalagay ng buong loop ng
mga takdang-aralin sa loob ng BEGIN block, na pinipilit itong mangyari sa panahon ng compilation.
Access sa mga lexical na nagbabago sa paglipas ng panahon--tulad ng mga nasa "para" na loop sa itaas, karaniwang
mga alyas sa mga elemento mula sa nakapalibot na lexical na saklaw-- gumagana lamang sa mga hindi kilalang sub,
hindi kasama ang mga pinangalanang subroutine. Karaniwang sinasabi, ang mga pinangalanang subroutine ay hindi namumugad nang maayos at
dapat lamang ideklara sa pangunahing saklaw ng pakete.
Ito ay dahil ang mga pinangalanang subroutine ay nilikha sa oras ng pag-compile kaya ang kanilang mga lexical na variable
italaga sa parent lexicals mula sa unang execution ng parent block. Kung ang
parent scope ay ipinasok sa pangalawang pagkakataon, ang mga lexical nito ay nilikha muli, habang ang nested
ang mga subs ay tumutukoy pa rin sa mga luma.
Nakukuha ng mga anonymous na subroutine ang bawat oras na isasagawa mo ang "sub" na operator, tulad ng mga ito
nilikha sa mabilisang. Kung nakasanayan mo nang gumamit ng mga nested subroutine sa ibang programming
mga wika na may sariling mga pribadong variable, kakailanganin mong magtrabaho nang kaunti sa Perl. Ang
Ang intuitive coding ng ganitong uri ng bagay ay nagdudulot ng mga mahiwagang babala tungkol sa "hindi mananatili
shared" dahil sa mga dahilan na ipinaliwanag sa itaas. Halimbawa, hindi ito gagana:
sub outer {
aking $x = $_[0] + 35;
sub inner { return $x * 19 } # MALI
ibalik ang $x + inner();
}
Ang isang work-around ay ang sumusunod:
sub outer {
aking $x = $_[0] + 35;
local *inner = sub { return $x * 19 };
ibalik ang $x + inner();
}
Ngayon panloob() matatawag lamang mula sa loob panlabas(), dahil sa mga pansamantalang takdang-aralin
ng hindi kilalang subroutine. Ngunit kapag nangyari ito, mayroon itong normal na access sa lexical
variable $x mula sa saklaw ng panlabas() sa oras na ang panlabas ay hinihingi.
Ito ay may kagiliw-giliw na epekto ng paglikha ng isang function na lokal sa isa pang function,
isang bagay na hindi karaniwang sinusuportahan sa Perl.
BABALA
Hindi ka maaaring (kapaki-pakinabang) gumamit ng isang sanggunian bilang susi sa isang hash. Ito ay gagawing a
string:
$x{ \$a } = $a;
Kung susubukan mong i-dereference ang susi, hindi ito gagawa ng isang mahirap na dereference, at hindi mo gagawin
matupad ang iyong sinusubukan. Baka gusto mong gumawa ng mas katulad
$r = \@a;
$x{ $r } = $r;
At pagkatapos ay hindi bababa sa maaari mong gamitin ang halaga (), na magiging totoong ref, sa halip na ang
mga susi(), na hindi.
Ang karaniwang Tie::RefHash module ay nagbibigay ng isang maginhawang solusyon para dito.
postfix Dereference palaugnayan
Simula sa v5.20.0, available ang isang postfix syntax para sa paggamit ng mga sanggunian. Ito ay kumikilos bilang
inilarawan sa "Paggamit ng Mga Sanggunian", ngunit sa halip na isang prefix na sigil, isang postfixed na sigil-at-
star ang ginagamit.
Halimbawa:
$r = \@a;
@b = $r->@*; # katumbas ng @$r o @{ $r }
$r = [ 1, [ 2, 3 ], 4 ];
$r->[1]->@*; # katumbas ng @{ $r->[1] }
Ang syntax na ito ay dapat na pinagana sa "gamitin ang tampok na 'postderef'". Ito ay pang-eksperimento, at gagawin
magbabala bilang default maliban kung "walang mga babala na 'experimental::postderef'" ay may bisa.
Dapat gumana ang postfix dereference sa lahat ng pagkakataon kung saan ang block (circumfix) dereference
nagtrabaho, at dapat ay ganap na katumbas. Ang syntax na ito ay nagpapahintulot sa dereferencing na maisulat
at basahin nang buo kaliwa-pakanan. Ang mga sumusunod na katumbas ay tinukoy:
$sref->$*; # pareho ng ${ $sref }
$aref->@*; # katulad ng @{ $aref }
$aref->$#*; # katulad ng $#{ $aref }
$href->%*; # pareho ng %{ $href }
$cref->&*; # katulad ng &{ $cref }
$gref->**; # katulad ng *{ $gref }
Tandaan lalo na ang "$cref->&*" ay hindi katumbas ng "$cref->()", at maaaring maghatid ng iba
mga layunin.
Maaaring makuha ang mga elemento ng glob sa pamamagitan ng tampok na postfix dereferencing:
$gref->*{SCALAR}; # pareho ng *{ $gref }{SCALAR}
Postfix array at scalar dereferencing maaari gamitin sa interpolating string (double quotes
o ang "qq" operator), ngunit kung ang karagdagang tampok na "postderef_qq" ay pinagana.
postfix Sanggunian Pagpuputol
Ang mga hiwa ng halaga ng mga array at hash ay maaari ding kunin gamit ang postfix dereferencing notation,
na may mga sumusunod na katumbas:
$aref->@[ ... ]; # katulad ng @$aref[ ... ]
$href->@{ ... }; # katulad ng @$href{ ... }
Postfix key/value pair slicing, idinagdag sa 5.20.0 at nakadokumento sa Key/Value Hash
Slice section ng perldata, kumikilos din gaya ng inaasahan:
$aref->%[ ... ]; # katulad ng %$aref[ ... ]
$href->%{ ... }; # katulad ng %$href{ ... }
Tulad ng postfix array, postfix value slice dereferencing maaari gamitin sa interpolating
string (double quotes o ang operator na "qq"), ngunit kung ang karagdagang "postderef_qq"
pinagana ang feature.
Pagtatalaga sa Mga sanggunian
Simula sa v5.22.0, ang operator ng pagtukoy ay maaaring italaga sa. Ito ay gumaganap ng isang
pagpapatakbo ng aliasing, upang ang variable na pangalan na tinutukoy sa kaliwang bahagi ay maging isang
alias para sa bagay na tinutukoy sa kanang bahagi:
\$a = \$b; # $a at $b ngayon ay tumuturo sa parehong scalar
\&foo = \&bar; Ang ibig sabihin ng # foo() ay bar()
Ang syntax na ito ay dapat na pinagana sa "gamitin ang tampok na 'refaliasing'". Ito ay pang-eksperimento, at
ay magbabala bilang default maliban kung "walang mga babala na 'experimental::refaliasing'" ay may bisa.
Ang mga form na ito ay maaaring italaga sa, at maging sanhi ng kanang bahagi upang masuri sa scalar
konteksto:
\$scalar
\@array
\%hash
\&sub
\aking $scalar
\my @array
\aking %hash
\state $scalar # o @array, atbp.
\aming $scalar # atbp.
\local $scalar # atbp.
\local ang aming $scalar # atbp.
\$some_array[$index]
\$some_hash{$key}
\local $some_array[$index]
\local $some_hash{$key}
kundisyon ? \$this : \$that[0] # etc.
Ang mga operasyon ng paghiwa at panaklong ay nagdudulot ng pagsusuri sa kanang bahagi sa listahan
konteksto:
\@array[5..7]
(\@array[5..7])
\(@array[5..7])
\@hash{'foo','bar'}
(\@hash{'foo','bar'})
\(@hash{'foo','bar'})
(\$scalar)
\($scalar)
\(aking $scalar)
\my($scalar)
(\@array)
(\%hash)
(\&sub)
\(&sub)
\($foo, @bar, %baz)
(\$foo, \@bar, \%baz)
Ang bawat elemento sa kanang bahagi ay dapat na isang sanggunian sa isang datum ng tamang uri.
Ang mga panaklong ay agad na pumapalibot sa isang array (at posibleng din
Gagawin ng "my"/"state"/"our"/"local") ang bawat elemento ng array na isang alias sa
katumbas na scalar na isinangguni sa kanang bahagi:
\(@a) = \(@b); Ang # @a at @b ay mayroon na ngayong parehong mga elemento
\my(@a) = \(@b); # gayundin
\(aking @a) = \(@b); # gayundin
push @a, 3; # ngunit ngayon ay may dagdag na elemento si @a na kulang sa @b
\(@a) = (\$a, \$b, \$c); Ang # @a ay naglalaman na ngayon ng $a, $b, at $c
Ang pagsasama-sama ng form na iyon sa "lokal" at paglalagay kaagad ng mga panaklong sa paligid ng isang hash ay
ipinagbabawal (dahil hindi malinaw kung ano ang dapat nilang gawin):
\local(@array) = foo(); # MALI
\(%hash) = bar(); # wRONG
Ang pagtatalaga sa mga sanggunian at hindi sanggunian ay maaaring pagsamahin sa mga listahan at may kondisyon
ternary expression, hangga't ang mga halaga sa kanang bahagi ay ang tamang uri para sa
bawat elemento sa kaliwa, kahit na ito ay maaaring gumawa ng obfuscated code:
(my $tom, \my $dick, \my @harry) = (\1, \2, [1..3]);
# $tom ay \1 na ngayon
# $dick ay 2 na ngayon (read-only)
Si # @harry ay (1,2,3)
ang aking $type = ref $thingy;
($type ? $type == 'ARRAY' ? \@foo : \$bar : $baz) = $thingy;
Ang "foreach" loop ay maaari ding kumuha ng reference na tagabuo para sa loop variable nito, kahit na ang
Ang syntax ay limitado sa isa sa mga sumusunod, na may opsyonal na "aking", "estado", o "aming" pagkatapos
ang backslash:
\$s
\@a
\%h
\&c
Walang panaklong ang pinahihintulutan. Ang tampok na ito ay partikular na kapaki-pakinabang para sa mga arrays-of-arrays,
o arrays-of-hashes:
foreach \my @a (@array_of_arrays) {
frobnicate($a[0], $a[-1]);
}
foreach \my %h (@array_of_hashes) {
$h{gelastic}++ kung $h{type} == 'nakakatawa';
}
CAVEAT: Hindi gumagana nang tama ang Aliasing sa mga pagsasara. Kung susubukan mong mag-alyas ng leksikal
mga variable mula sa isang panloob na subroutine o "eval", ang aliasing ay makikita lamang sa loob
na panloob na sub, at hindi makakaapekto sa panlabas na subroutine kung saan idineklara ang mga variable.
Ang kakaibang pag-uugali na ito ay maaaring magbago.
Gumamit ng perlref online gamit ang mga serbisyo ng onworks.net