ນີ້ແມ່ນຄໍາສັ່ງ perlref ທີ່ສາມາດດໍາເນີນການໄດ້ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີໂດຍໃຊ້ຫນຶ່ງໃນຫຼາຍສະຖານີເຮັດວຽກອອນໄລນ໌ຂອງພວກເຮົາເຊັ່ນ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator
ໂຄງການ:
NAME
perlref - ການອ້າງອິງ Perl ແລະໂຄງສ້າງຂໍ້ມູນ nested
ຫມາຍເຫດ
ນີ້ແມ່ນເອກະສານຄົບຖ້ວນສົມບູນກ່ຽວກັບທຸກດ້ານຂອງການອ້າງອີງ. ສໍາລັບສັ້ນ, tutorial
ການແນະນໍາພຽງແຕ່ລັກສະນະທີ່ສໍາຄັນ, ເບິ່ງ perlreftut.
ລາຍລະອຽດ
ກ່ອນທີ່ຈະປ່ອຍ 5 ຂອງ Perl ມັນຍາກທີ່ຈະເປັນຕົວແທນຂອງໂຄງສ້າງຂໍ້ມູນທີ່ສັບສົນ, ເພາະວ່າ
ການອ້າງອິງທັງຫມົດຕ້ອງເປັນສັນຍາລັກ - ແລະເຖິງແມ່ນວ່າຫຼັງຈາກນັ້ນມັນກໍ່ເປັນການຍາກທີ່ຈະອ້າງອີງເຖິງຕົວແປ
ແທນການເຂົ້າຕາຕະລາງສັນຍາລັກ. Perl ໃນປັດຈຸບັນບໍ່ພຽງແຕ່ເຮັດໃຫ້ມັນງ່າຍຕໍ່ການໃຊ້ສັນຍາລັກ
ການອ້າງອິງເຖິງຕົວແປ, ແຕ່ຍັງຊ່ວຍໃຫ້ທ່ານມີ "ຍາກ" ການອ້າງອີງເຖິງຂໍ້ມູນໃດໆຫຼື
ລະຫັດ. ຕາຕະລາງໃດນຶ່ງອາດຈະຖືເປັນການອ້າງອີງຍາກ. ເນື່ອງຈາກວ່າ arrays ແລະ hashes ມີ scalar,
ໃນປັດຈຸບັນທ່ານສາມາດສ້າງ array ຂອງ array, array ຂອງ hashes, hashes ຂອງ array, arrays ໄດ້ຢ່າງງ່າຍດາຍ.
hashes ຂອງຫນ້າທີ່, ແລະອື່ນໆ.
ການອ້າງອິງຍາກແມ່ນສະຫຼາດ - ພວກເຂົາຕິດຕາມການນັບອ້າງອີງສໍາລັບທ່ານ, ໂດຍອັດຕະໂນມັດ
ການປົດປ່ອຍສິ່ງທີ່ອ້າງເຖິງເມື່ອການນັບອ້າງອີງຂອງມັນໄປຫາສູນ. (ການນັບອ້າງອີງ
ສໍາລັບຄ່າໃນໂຄງສ້າງຂໍ້ມູນການອ້າງອິງຕົນເອງ ຫຼືຮອບວຽນອາດຈະບໍ່ໄປເຖິງສູນໂດຍບໍ່ມີການ a
ການຊ່ວຍເຫຼືອພຽງເລັກນ້ອຍ; ເບິ່ງ "Circular References" ສໍາລັບຄໍາອະທິບາຍລາຍລະອຽດ.) ຖ້າສິ່ງນັ້ນເກີດຂຶ້ນ
ເປັນວັດຖຸ, ວັດຖຸຖືກທໍາລາຍ. ເບິ່ງ perlobj ສໍາລັບເພີ່ມເຕີມກ່ຽວກັບວັດຖຸ. (ຢູ່ໃນ
ຄວາມຮູ້ສຶກ, ທຸກສິ່ງທຸກຢ່າງໃນ Perl ແມ່ນວັດຖຸ, ແຕ່ພວກເຮົາປົກກະຕິແລ້ວສະຫງວນຄໍາສໍາລັບການອ້າງອີງເຖິງ
ວັດຖຸທີ່ໄດ້ຮັບ "ພອນ" ຢ່າງເປັນທາງການເຂົ້າໄປໃນຊຸດຊັ້ນຮຽນ.)
ການອ້າງອິງສັນຍາລັກແມ່ນຊື່ຂອງຕົວແປຫຼືວັດຖຸອື່ນໆ, ຄືກັນກັບການເຊື່ອມຕໍ່ສັນຍາລັກໃນ a
ລະບົບໄຟລ໌ Unix ປະກອບມີພຽງແຕ່ຊື່ຂອງໄຟລ໌. * ສັນ ຍາ ລັກ ໂລກ ແມ່ນ ບາງ ສິ່ງ ບາງ ຢ່າງ ຂອງ a
ເອກະສານສັນຍາລັກ. (ການອ້າງອິງສັນຍາລັກບາງຄັ້ງເອີ້ນວ່າ "ການອ້າງອິງອ່ອນ", ແຕ່
ກະລຸນາຢ່າໂທຫາພວກເຂົາວ່າ; ການອ້າງອີງແມ່ນສັບສົນພຽງພໍໂດຍບໍ່ມີຄໍາສັບຄ້າຍຄືທີ່ບໍ່ມີປະໂຫຍດ.)
ໃນທາງກົງກັນຂ້າມ, ການອ້າງອິງຍາກແມ່ນຄ້າຍຄືກັບການເຊື່ອມຕໍ່ຍາກໃນລະບົບໄຟລ໌ Unix: ພວກມັນຖືກນໍາໃຊ້
ເພື່ອເຂົ້າເຖິງວັດຖຸທີ່ຕິດພັນໂດຍບໍ່ສົນໃຈວ່າຊື່ (ອື່ນໆ) ຂອງມັນແມ່ນຫຍັງ. ໃນເວລາທີ່
ຄໍາວ່າ "ອ້າງອິງ" ແມ່ນໃຊ້ໂດຍບໍ່ມີຄໍານາມ, ຄືກັບວັກຕໍ່ໄປນີ້, ມັນແມ່ນ
ປົກກະຕິແລ້ວເວົ້າກ່ຽວກັບການອ້າງອິງຍາກ.
ເອກະສານອ້າງອີງແມ່ນງ່າຍທີ່ຈະໃຊ້ໃນ Perl. ມີພຽງແຕ່ຫນຶ່ງຫຼັກການ overriding: ໂດຍທົ່ວໄປ,
Perl ບໍ່ມີການອ້າງອິງຫຼືການອ້າງອິງ implicit. ໃນເວລາທີ່ scalar ກໍາລັງຖືເອກະສານອ້າງອີງ,
ມັນສະເຫມີປະຕິບັດຕົວເປັນ scalar ງ່າຍດາຍ. ມັນບໍ່ໄດ້ເລີ່ມເປັນ array ຫຼື hash ຢ່າງມະຫັດສະຈັນ
ຫຼື subroutine; ເຈົ້າຕ້ອງບອກມັນຢ່າງຈະແຈ້ງເພື່ອເຮັດແນວນັ້ນ, ໂດຍການອ້າງອິງມັນ.
ທີ່ເວົ້າວ່າ, ຈົ່ງຮູ້ວ່າ Perl ຮຸ່ນ 5.14 ແນະນໍາການຍົກເວັ້ນກົດລະບຽບ, ສໍາລັບ
ຄວາມສະດວກສະບາຍ syntactic. ພຶດຕິກຳການທໍາງານຂອງອາເຣແບບທົດລອງ ແລະ hash container ອະນຸຍາດໃຫ້
ການອ້າງອິງ array ແລະ hash ຈະຖືກຈັດການໂດຍ Perl ຄືກັບວ່າພວກເຂົາຖືກປະຕິບັດຢ່າງຈະແຈ້ງ
ຫຍໍ້ມາຈາກ syntactically. ເບິ່ງ "ການເພີ່ມປະສິດທິພາບ syntactical" ໃນ perl5140delta ແລະ perlfunc
ສໍາລັບລາຍລະອຽດ.
ການເຮັດໃຫ້ ເອກະສານ
ການອ້າງອິງສາມາດສ້າງໄດ້ໃນຫຼາຍວິທີ.
1. ໂດຍໃຊ້ຕົວປະຕິບັດການ backslash ໃນຕົວແປ, ບັນຊີຍ່ອຍ, ຫຼືຄ່າ. (ນີ້ເຮັດວຽກຫຼາຍ
ເຊັ່ນ & (ທີ່ຢູ່ - ຂອງ) operator ໃນ C.) ນີ້ປົກກະຕິສ້າງ ອື່ນ ກະສານອ້າງອີງ a
ຕົວແປ, ເພາະວ່າມີການອ້າງອີງເຖິງຕົວແປໃນຕາຕະລາງສັນຍາລັກແລ້ວ.
ແຕ່ການອ້າງອິງຕາຕະລາງສັນຍາລັກອາດຈະຫາຍໄປ, ແລະທ່ານຍັງຄົງມີຄໍາອ້າງອີງທີ່
backslash ກັບຄືນມາ. ນີ້ແມ່ນບາງຕົວຢ່າງ:
$scalarref = \$foo;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*foo;
ມັນເປັນໄປບໍ່ໄດ້ທີ່ຈະສ້າງການອ້າງອິງທີ່ແທ້ຈິງກັບ IO handle (filehandle ຫຼື dirhandle)
ໃຊ້ຕົວປະຕິບັດການ backslash. ທີ່ສຸດທີ່ທ່ານສາມາດໄດ້ຮັບແມ່ນການອ້າງອີງເຖິງ typeglob,
ທີ່ຈິງແລ້ວແມ່ນການເຂົ້າຕາຕະລາງສັນຍາລັກທີ່ສົມບູນ. ແຕ່ເບິ່ງຄໍາອະທິບາຍຂອງ
*foo{THING} syntax ຂ້າງລຸ່ມນີ້. ຢ່າງໃດກໍຕາມ, ທ່ານຍັງສາມາດໃຊ້ globs ປະເພດແລະ globrefs ເປັນ
ເຖິງແມ່ນວ່າພວກເຂົາເປັນມືຈັບ IO.
2. ການອ້າງອີງເຖິງ array ທີ່ບໍ່ເປີດເຜີຍຊື່ສາມາດສ້າງໄດ້ໂດຍໃຊ້ວົງເລັບສີ່ຫຼ່ຽມ:
$arrayref = [1, 2, ['a', 'b', 'c']];
ໃນທີ່ນີ້ພວກເຮົາໄດ້ສ້າງການອ້າງອີງເຖິງ array ທີ່ບໍ່ເປີດເຜີຍຊື່ຂອງສາມອົງປະກອບສຸດທ້າຍ
ອົງປະກອບຂອງຕົວມັນເອງແມ່ນການອ້າງອີງເຖິງ array ອື່ນບໍ່ລະບຸຊື່ຂອງສາມອົງປະກອບ. (ໄດ້
ໄວຍະກອນຫຼາຍມິຕິທີ່ອະທິບາຍຕໍ່ມາສາມາດຖືກນໍາໃຊ້ເພື່ອເຂົ້າເຖິງນີ້. ຍົກຕົວຢ່າງ,
ຫຼັງຈາກຂ້າງເທິງ, "$arrayref->[2][1]" ຈະມີຄ່າ "b".)
ການອ້າງອິງເຖິງບັນຊີລາຍຊື່ທີ່ນັບບໍ່ຖ້ວນແມ່ນບໍ່ຄືກັນກັບການໃຊ້ສີ່ຫຼ່ຽມມົນ
ວົງເລັບ - ແທນທີ່ມັນຄືກັນກັບການສ້າງລາຍຊື່ອ້າງອີງ!
@list = (\$a, \@b, \%c);
@list = \($a, @b, %c); #ອັນດຽວກັນ!
ເປັນກໍລະນີພິເສດ, "\(@foo)" ສົ່ງຄືນລາຍຊື່ການອ້າງອີງເຖິງເນື້ອໃນຂອງ @foo, ບໍ່ແມ່ນ.
ອ້າງເຖິງ @foo ຕົວຂອງມັນເອງ. ເຊັ່ນດຽວກັນສໍາລັບ %foo, ຍົກເວັ້ນການອ້າງອິງທີ່ສໍາຄັນແມ່ນ
ສໍາເນົາ (ເນື່ອງຈາກວ່າກະແຈແມ່ນພຽງແຕ່ສະຕຣິງແທນທີ່ຈະກ່ວາສະເກັດທີ່ເຕັມທີ່).
3. ການອ້າງອີງເຖິງ hash ທີ່ບໍ່ເປີດເຜີຍຊື່ສາມາດສ້າງໄດ້ໂດຍໃຊ້ວົງເລັບ curly:
$hashref = {
'ອາດາມ' => 'ເອວາ',
'Clyde' => 'ໂບນີ',
};
ຜູ່ຂຽນ hash ແລະ array ແບບບໍ່ເປີດເຜີຍຊື່ຄືສິ່ງເຫຼົ່ານີ້ສາມາດຖືກປະສົມເຂົ້າກັນຢ່າງເສລີເພື່ອຜະລິດເປັນ
ຊັບຊ້ອນໂຄງສ້າງຕາມທີ່ທ່ານຕ້ອງການ. syntax ຫຼາຍມິຕິທີ່ອະທິບາຍຂ້າງລຸ່ມນີ້
ເຮັດວຽກສໍາລັບການເຫຼົ່ານີ້ເຊັ່ນດຽວກັນ. ຄ່າຂ້າງເທິງແມ່ນຕົວໜັງສື, ແຕ່ຕົວແປ ແລະສະແດງອອກ
ຈະເຮັດວຽກເຊັ່ນດຽວກັນ, ເພາະວ່າຜູ້ປະຕິບັດການມອບຫມາຍໃນ Perl (ເຖິງແມ່ນວ່າພາຍໃນ ທ້ອງຖິ່ນ() or
ຂອງຂ້ອຍ()) ແມ່ນຄໍາຖະແຫຼງທີ່ປະຕິບັດໄດ້, ບໍ່ແມ່ນການລວບລວມການປະກາດເວລາ.
ເນື່ອງຈາກວ່າວົງເລັບ curly (ວົງເລັບ) ຖືກນໍາໃຊ້ສໍາລັບສິ່ງອື່ນໆຈໍານວນຫນຶ່ງລວມທັງ BLOCKs,
ບາງຄັ້ງທ່ານອາດຕ້ອງ disambiguate braces ໃນຕອນຕົ້ນຂອງຄໍາຖະແຫຼງການໂດຍ
ວາງ "+" ຫຼື "ກັບຄືນ" ຢູ່ທາງຫນ້າເພື່ອໃຫ້ Perl ຮູ້ວ່າວົງເລັບເປີດບໍ່ແມ່ນ.
ເລີ່ມ BLOCK. ເສດຖະກິດແລະມູນຄ່າ mnemonic ຂອງການນໍາໃຊ້ curlies ແມ່ນຖືວ່າມີມູນຄ່າ
ນີ້ hassle ພິເສດເປັນບາງໂອກາດ.
ຕົວຢ່າງ, ຖ້າທ່ານຕ້ອງການຟັງຊັນເພື່ອເຮັດໃຫ້ hash ໃໝ່ ແລະສົ່ງຄືນການອ້າງອີງໃສ່ມັນ,
ທ່ານມີທາງເລືອກເຫຼົ່ານີ້:
sub hashem { { @_ } } # ຜິດຢ່າງງຽບໆ
sub hashem { +{ @_ } } # ok
sub hashem { return { @_ } } # ok
ໃນທາງກົງກັນຂ້າມ, ຖ້າທ່ານຕ້ອງການຄວາມຫມາຍອື່ນ, ທ່ານສາມາດເຮັດໄດ້:
ການສະແດງຍ່ອຍ { { @_ } } # ບໍ່ຊັດເຈນ (ຕອນນີ້ແມ່ນແລ້ວ,
# ແຕ່ອາດຈະມີການປ່ຽນແປງ)
ການສະແດງຍ່ອຍ { { ; @_ } } # ຕົກລົງ
sub showem { { return @_ } } # ok
ຊັ້ນນໍາ "+{" ແລະ "{;" ສະເຫມີໃຫ້ບໍລິການເພື່ອ disambiguate ການສະແດງອອກເພື່ອຫມາຍຄວາມວ່າບໍ່ວ່າຈະ
ການອ້າງອີງ HASH, ຫຼື BLOCK.
4. ການອ້າງອີງເຖິງການຍ່ອຍທີ່ບໍ່ເປີດເຜີຍຊື່ສາມາດຖືກສ້າງໄດ້ໂດຍໃຊ້ "sub" ໂດຍບໍ່ມີ a
ຊື່ຍ່ອຍ:
$coderef = ຍ່ອຍ {ພິມ "Boink!\n" };
ສັງເກດເຄື່ອງໝາຍຈຸດ. ຍົກເວັ້ນລະຫັດພາຍໃນບໍ່ຖືກປະຕິບັດທັນທີ, ເປັນ "sub
{}" ບໍ່ແມ່ນການປະກາດຫຼາຍເທົ່າທີ່ມັນເປັນຕົວປະຕິບັດການ, ເຊັ່ນ "do{}" ຫຼື "eval{}".
(ຢ່າງໃດກໍຕາມ, ບໍ່ວ່າທ່ານຈະປະຕິບັດເສັ້ນສະເພາະນັ້ນຫຼາຍປານໃດ (ເວັ້ນເສຍແຕ່ວ່າທ່ານຢູ່ໃນ
"eval("...")"), $coderef ຈະຍັງຄົງມີການອ້າງອີງເຖິງ ດຽວກັນ anonymous
ປົກກະຕິຍ່ອຍ.)
ກິດຈະກໍາຍ່ອຍທີ່ບໍ່ເປີດເຜີຍຊື່ເຮັດຫນ້າທີ່ເປັນການປິດທີ່ກ່ຽວຂ້ອງກັບ ຂອງຂ້ອຍ() ຕົວແປ, ນັ້ນແມ່ນ,
ຕົວແປທີ່ເຫັນໄດ້ຊັດເຈນຢູ່ໃນຂອບເຂດປະຈຸບັນ. ການປິດແມ່ນຄວາມຄິດທີ່ອອກຈາກ
ໂລກ Lisp ທີ່ເວົ້າວ່າຖ້າທ່ານກໍານົດຫນ້າທີ່ບໍ່ເປີດເຜີຍຊື່ໃນ lexical ໂດຍສະເພາະ
context, ມັນທໍາທ່າທີ່ຈະດໍາເນີນການໃນສະພາບການນັ້ນເຖິງແມ່ນວ່າໃນເວລາທີ່ມັນຖືກເອີ້ນວ່າຢູ່ນອກບໍລິບົດ.
ໃນແງ່ຂອງມະນຸດ, ມັນເປັນວິທີທີ່ຕະຫລົກທີ່ຈະຖ່າຍທອດການໂຕ້ແຍ້ງໄປຫາກິດຈະວັດຍ່ອຍໃນເວລາທີ່ທ່ານກໍານົດ
ມັນເຊັ່ນດຽວກັນກັບເວລາທີ່ທ່ານໂທຫາມັນ. ມັນເປັນປະໂຫຍດສໍາລັບການຕັ້ງລະຫັດເລັກນ້ອຍເພື່ອດໍາເນີນການ
ຕໍ່ມາ, ເຊັ່ນການໂທກັບ. ເຈົ້າສາມາດເຮັດສິ່ງຂອງຈຸດປະສົງກັບມັນ, ເຖິງແມ່ນວ່າ Perl
ມີກົນໄກທີ່ແຕກຕ່າງກັນເພື່ອເຮັດແນວນັ້ນແລ້ວ - ເບິ່ງ perlobj.
ທ່ານອາດຈະຄິດວ່າການປິດເປັນວິທີການຂຽນແບບປົກກະຕິຍ່ອຍໂດຍບໍ່ຕ້ອງໃຊ້
eval(). ນີ້ແມ່ນຕົວຢ່າງເລັກນ້ອຍຂອງວິທີການປິດເຮັດວຽກ:
ພິມໃຫມ່ຍ່ອຍ {
$x ຂອງຂ້ອຍ = shift;
return sub { my $y = shift; ພິມ "$x, $y!\n"; } ;
}
$h = newprint("ສະບາຍດີ");
$g = newprint("ສະບາຍດີ");
#ເວລາຜ່ານໄປ...
&$h("ໂລກ");
&$g("earthlings");
ນີ້ພິມ
ສະບາຍດີ, ໂລກ!
ຊົມເຊີຍ, earthlings!
ໃຫ້ສັງເກດໂດຍສະເພາະວ່າ $x ສືບຕໍ່ອ້າງອີງເຖິງມູນຄ່າທີ່ຜ່ານເຂົ້າໄປໃນ ພິມໃໝ່()
ເຖິງວ່າຈະມີ "$x ຂອງຂ້ອຍ" ອອກຈາກຂອບເຂດໂດຍເວລາທີ່ routine ຍ່ອຍທີ່ບໍ່ເປີດເຜີຍຊື່ເຮັດວຽກ.
ນັ້ນແມ່ນສິ່ງທີ່ການປິດແມ່ນທັງຫມົດກ່ຽວກັບ.
ນີ້ໃຊ້ພຽງແຕ່ກັບຕົວແປ lexical, ໂດຍວິທີທາງການ. ຕົວແປແບບໄດນາມິກຍັງສືບຕໍ່
ເຮັດວຽກຕາມທີ່ເຂົາເຈົ້າໄດ້ເຮັດວຽກສະເຫມີໄປ. ການປິດແມ່ນບໍ່ແມ່ນສິ່ງທີ່ນັກຂຽນໂປລແກລມ Perl ສ່ວນໃຫຍ່
ຕ້ອງການບັນຫາດ້ວຍຕົນເອງກ່ຽວກັບການເລີ່ມຕົ້ນດ້ວຍ.
5. ການອ້າງອິງມັກຈະຖືກສົ່ງຄືນໂດຍ subroutines ພິເສດທີ່ເອີ້ນວ່າ constructors. Perl
ວັດຖຸແມ່ນພຽງແຕ່ການອ້າງອີງເຖິງປະເພດພິເສດຂອງວັດຖຸທີ່ເກີດຂື້ນເພື່ອຮູ້ວ່າອັນໃດ
ຊຸດທີ່ມັນເຊື່ອມໂຍງກັບ. Constructors ແມ່ນພຽງແຕ່ subroutine ພິເສດທີ່ຮູ້ວິທີການ
ເພື່ອສ້າງສະມາຄົມນັ້ນ. ພວກເຂົາເຮັດແນວນັ້ນໂດຍການເລີ່ມຕົ້ນດ້ວຍການອ້າງອີງທໍາມະດາ, ແລະມັນ
ຍັງຄົງເປັນເອກະສານອ້າງອີງທຳມະດາ ເຖິງແມ່ນວ່າມັນຍັງເປັນວັດຖຸ. ຜູ້ກໍ່ສ້າງແມ່ນ
ມັກຈະມີຊື່ວ່າ "new()". ເຈົ້າ ສາມາດເຮັດໄດ້ ໂທຫາພວກເຂົາທາງອ້ອມ:
$objref = new Doggie(ຫາງ => 'ສັ້ນ', ຫູ => 'ຍາວ' );
ແຕ່ວ່າສາມາດຜະລິດ syntax ທີ່ບໍ່ຊັດເຈນໃນບາງກໍລະນີ, ສະນັ້ນມັນມັກຈະດີກວ່າທີ່ຈະໃຊ້
ວິທີການຮຽກຮ້ອງໂດຍກົງ:
$objref = Doggie->new(ຫາງ => 'ສັ້ນ', ຫູ => 'ຍາວ');
ການນໍາໃຊ້ຄໍາສັບ::Cap;
$terminal = ໄລຍະ::Cap->Tgetent( { OSPEED => 9600 });
ໃຊ້ Tk;
$main = MainWindow->new();
$menubar = $main->Frame(-relief => "ຍົກຂຶ້ນມາ",
-ຄວາມກວ້າງຂວາງ => 2)
6. ການອ້າງອິງຂອງປະເພດທີ່ເຫມາະສົມສາມາດເກີດຂຶ້ນໄດ້ຖ້າຫາກວ່າທ່ານ dereference ໃຫ້ເຂົາເຈົ້າ
ໃນສະພາບການທີ່ສົມມຸດວ່າພວກມັນມີຢູ່. ເພາະວ່າພວກເຮົາບໍ່ໄດ້ເວົ້າກ່ຽວກັບການອ້າງອິງ
ແຕ່, ພວກເຮົາບໍ່ສາມາດສະແດງຕົວຢ່າງໃດໆໃຫ້ທ່ານໄດ້.
7. ການອ້າງອິງສາມາດສ້າງໄດ້ໂດຍການໃຊ້ syntax ພິເສດ, ຮູ້ຈັກດ້ວຍຄວາມຮັກເປັນ
*foo{THING} syntax. *foo{THING} ສົ່ງຄືນການອ້າງອີງໃສ່ຊ່ອງ THING ໃນ *foo (ເຊິ່ງ
ແມ່ນການເຂົ້າຕາຕະລາງສັນຍາລັກທີ່ຖືທຸກສິ່ງທຸກຢ່າງທີ່ເອີ້ນວ່າ foo).
$scalarref = *foo{SCALAR};
$arrayref = *ARGV{ARRAY};
$hashref = *ENV{HASH};
$coderef = *ຕົວຈັດການ{CODE};
$ioref = *STDIN{IO};
$globref = *foo{GLOB};
$formatref = *foo{FORMAT};
$globname = *foo{NAME}; # "ຟູ"
$pkgname = *foo{PACKAGE}; # "ຫຼັກ"
ສ່ວນໃຫຍ່ເຫຼົ່ານີ້ເປັນການອະທິບາຍດ້ວຍຕົນເອງ, ແຕ່ *foo{IO} ສົມຄວນໄດ້ຮັບຄວາມສົນໃຈເປັນພິເສດ. ມັນ
ສົ່ງຄືນຕົວຈັບ IO, ໃຊ້ສຳລັບຕົວຈັດການໄຟລ໌ ("ເປີດ" ໃນ perlfunc), ເຕົ້າຮັບ ("ເຕົ້າຮັບ"
ໃນ perlfunc ແລະ "socketpair" ໃນ perlfunc), ແລະຕົວຈັດການບັນຊີ ("opendir" ໃນ
perlfunc). ເພື່ອຄວາມເຂົ້າກັນໄດ້ກັບ Perl ລຸ້ນກ່ອນໜ້າ, *foo{FILEHANDLE} ແມ່ນ a
ຄໍາສັບຄ້າຍຄື *foo{IO}, ເຖິງແມ່ນວ່າມັນຖືກປະຕິເສດເປັນ 5.8.0. ຖ້າການຍົກເລີກການເຕືອນໄພ
ມີຜົນບັງຄັບໃຊ້, ມັນຈະເຕືອນການນໍາໃຊ້ຂອງມັນ.
*foo{THING} ກັບຄືນ undef ຖ້າສິ່ງທີ່ສະເພາະນັ້ນຍັງບໍ່ໄດ້ຖືກນໍາໃຊ້ເທື່ອ, ຍົກເວັ້ນໃນ
ກໍລະນີຂອງເກັດ. *foo{SCALAR} ສົ່ງຄືນການອ້າງອີງເຖິງ scalar ທີ່ບໍ່ເປີດເຜີຍຊື່ ຖ້າ $foo
ຍັງບໍ່ໄດ້ຖືກນໍາໃຊ້ເທື່ອ. ນີ້ອາດຈະມີການປ່ຽນແປງໃນການປ່ອຍໃນອະນາຄົດ.
*foo{NAME} ແລະ *foo{PACKAGE} ແມ່ນຂໍ້ຍົກເວັ້ນ, ໃນການທີ່ພວກມັນສົ່ງຄືນສະຕຣິງ, ແທນທີ່ຈະ.
ກ່ວາການອ້າງອີງ. ເຫຼົ່ານີ້ສົ່ງຄືນຊຸດແລະຊື່ຂອງ typeglob ຕົວຂອງມັນເອງ, ແທນທີ່ຈະ
ຫຼາຍກ່ວາຫນຶ່ງທີ່ໄດ້ຮັບການມອບຫມາຍໃຫ້ມັນ. ດັ່ງນັ້ນ, ຫຼັງຈາກ "*foo=*Foo::bar", *foo ຈະກາຍເປັນ
"*Foo::bar" ເມື່ອໃຊ້ເປັນສະຕຣິງ, ແຕ່ *foo{PACKAGE} ແລະ *foo{NAME} ຈະສືບຕໍ່ເປັນ.
ຜະລິດ "ຕົ້ນຕໍ" ແລະ "foo", ຕາມລໍາດັບ.
*foo{IO} ເປັນທາງເລືອກໜຶ່ງຕໍ່ກັບກົນໄກ *HANDLE ທີ່ໃຫ້ໄວ້ໃນ "Typeglobs ແລະ
Filehandles" ໃນ perldata ສໍາລັບການຖ່າຍທອດ filehandles ເຂົ້າໄປໃນຫຼືອອກຈາກ subroutines, ຫຼື
ການເກັບຮັກສາເຂົ້າໄປໃນໂຄງສ້າງຂໍ້ມູນຂະຫນາດໃຫຍ່. ຂໍ້ເສຍຂອງມັນແມ່ນວ່າມັນຈະບໍ່ສ້າງໃຫມ່
filehandle ສໍາລັບທ່ານ. ປະໂຫຍດຂອງມັນແມ່ນວ່າທ່ານມີຄວາມສ່ຽງຫນ້ອຍທີ່ຈະ clobbering ຫຼາຍກ່ວາ
ທ່ານຕ້ອງການດ້ວຍການມອບໝາຍ typeglob. (ມັນຍັງ conflates ໄຟລ໌ແລະໄດເລກະທໍລີ
handles, ເຖິງແມ່ນວ່າ.) ຢ່າງໃດກໍຕາມ, ຖ້າທ່ານກໍານົດມູນຄ່າຂາເຂົ້າກັບ scalar ແທນທີ່ຈະເປັນ a
typeglob ດັ່ງທີ່ພວກເຮົາເຮັດໃນຕົວຢ່າງຂ້າງລຸ່ມນີ້, ບໍ່ມີຄວາມສ່ຽງທີ່ຈະເກີດຂຶ້ນ.
sputter(*STDOUT); # ຜ່ານໄປທົ່ວໂລກ
sputter(*STDOUT{IO}); # ຜ່ານທັງໄຟລ໌ແລະຕົວຈັບ dir
subsputter {
ຂອງຂ້ອຍ $fh = shift;
ພິມ $fh "her um well a hmmm\n";
}
$rec = get_rec(*STDIN); # ຜ່ານໄປທົ່ວໂລກ
$rec = get_rec(*STDIN{IO}); # ຜ່ານທັງໄຟລ໌ແລະຕົວຈັບ dir
ຍ່ອຍ get_rec {
ຂອງຂ້ອຍ $fh = shift;
return scalar <$fh>;
}
ການນໍາໃຊ້ ເອກະສານ
ນັ້ນແມ່ນມັນສໍາລັບການສ້າງເອກະສານອ້າງອີງ. ມາເຖິງຕອນນີ້ເຈົ້າຄົງຈະຕາຍທີ່ຈະຮູ້ວິທີໃຊ້
ການອ້າງອິງເພື່ອກັບຄືນໄປຫາຂໍ້ມູນທີ່ສູນເສຍໄປດົນນານຂອງທ່ານ. ມີຫຼາຍວິທີພື້ນຖານ.
1. ບ່ອນໃດກໍ່ຕາມທີ່ເຈົ້າຕ້ອງການໃສ່ຕົວລະບຸ (ຫຼືລະບົບຕ່ອງໂສ້ຂອງຕົວລະບຸ) ເປັນສ່ວນໜຶ່ງຂອງຕົວແປ ຫຼື
subroutine ຊື່, ທ່ານສາມາດທົດແທນຕົວລະບຸດ້ວຍຕົວແປທີ່ງ່າຍດາຍ
ປະກອບມີການອ້າງອີງຂອງປະເພດທີ່ຖືກຕ້ອງ:
$bar = $$scalarref;
push(@$arrayref, $filename);
$$arrayref[0] = "ມັງກອນ";
$$hashref{"KEY"} = "VALUE";
&$coderef(1,2,3);
ພິມ $globref "output\n";
ມັນເປັນສິ່ງສໍາຄັນທີ່ຈະເຂົ້າໃຈວ່າພວກເຮົາໂດຍສະເພາະ ບໍ່ ການອ້າງອິງ $arrayref[0]
ຫຼື $hashref{"KEY"} ຢູ່ທີ່ນັ້ນ. dereference ຂອງຕົວແປ scalar ເກີດຂຶ້ນ ກ່ອນທີ່ຈະ it
ເຮັດການຄົ້ນຫາທີ່ສໍາຄັນໃດໆ. ສິ່ງໃດທີ່ສັບສົນກວ່າຕົວແປ scalar ງ່າຍດາຍຕ້ອງ
ໃຊ້ວິທີການ 2 ຫຼື 3 ຂ້າງລຸ່ມນີ້. ຢ່າງໃດກໍ່ຕາມ, "ການຄິດໄລ່ແບບງ່າຍໆ" ປະກອບມີຕົວລະບຸວ່າ
ຕົວຂອງມັນເອງໃຊ້ວິທີການ 1 recursively. ດັ່ງນັ້ນ, ພິມຕໍ່ໄປນີ້ "ສະບາຍດີ".
$refrefref = \\\"ສະບາຍດີ";
ພິມ $$$$refrefref;
2. ບ່ອນໃດກໍ່ຕາມທີ່ເຈົ້າຕ້ອງການໃສ່ຕົວລະບຸ (ຫຼືລະບົບຕ່ອງໂສ້ຂອງຕົວລະບຸ) ເປັນສ່ວນໜຶ່ງຂອງຕົວແປ ຫຼື
subroutine ຊື່, ທ່ານສາມາດປ່ຽນແທນຕົວລະບຸດ້ວຍ BLOCK ທີ່ສົ່ງຄືນການອ້າງອີງຂອງ
ປະເພດທີ່ຖືກຕ້ອງ. ໃນຄໍາສັບຕ່າງໆອື່ນໆ, ຕົວຢ່າງກ່ອນຫນ້ານີ້ສາມາດຖືກຂຽນເຊັ່ນນີ້:
$bar = ${$scalarref};
push(@{$arrayref}, $filename);
${$arrayref}[0] = "ມັງກອນ";
${$hashref}{"KEY"} = "VALUE";
&{$coderef}(1,2,3);
$globref->print("output\n"); # iff IO::Handle ຖືກໂຫລດແລ້ວ
ຍອມຮັບ, ມັນເປັນເລື່ອງໂງ່ເລັກນ້ອຍທີ່ຈະໃຊ້ curlies ໃນກໍລະນີນີ້, ແຕ່ BLOCK ສາມາດ
ປະກອບດ້ວຍການສະແດງອອກທີ່ຕົນເອງມັກ, ໂດຍສະເພາະ, ການສະແດງອອກ subscripted:
&{ $dispatch{$index} }(1,2,3); # ໂທປົກກະຕິທີ່ຖືກຕ້ອງ
ເນື່ອງຈາກວ່າສາມາດຍົກເລີກ curlies ສໍາລັບກໍລະນີທີ່ງ່າຍດາຍຂອງ $$x, ປະຊາຊົນມັກຈະ
ເຮັດຜິດພາດຂອງການເບິ່ງສັນຍາລັກ deferencing ເປັນຜູ້ປະຕິບັດການທີ່ເຫມາະສົມ, ແລະສິ່ງມະຫັດ
ກ່ຽວກັບການນໍາຫນ້າຂອງເຂົາເຈົ້າ. ຖ້າພວກເຂົາເປັນ, ເຖິງແມ່ນວ່າ, ທ່ານສາມາດນໍາໃຊ້ວົງເລັບແທນ
ວົງເລັບ. ນັ້ນບໍ່ແມ່ນກໍລະນີ. ພິຈາລະນາຄວາມແຕກຕ່າງຂ້າງລຸ່ມນີ້; ກໍລະນີ 0 ເປັນມືສັ້ນ
ສະບັບຂອງກໍລະນີ 1, ບໍ່ ກໍລະນີ 2:
$$hashref{"KEY"} = "VALUE"; # ກໍລະນີ 0
${$hashref}{"KEY"} = "VALUE"; #ກໍລະນີທີ 1
${$hashref{"KEY"}} = "VALUE"; #ກໍລະນີ 2
${$hashref->{"KEY"}} = "VALUE"; #ກໍລະນີ 3
ກໍລະນີ 2 ຍັງເປັນການຫຼອກລວງທີ່ທ່ານກໍາລັງເຂົ້າເຖິງຕົວແປທີ່ເອີ້ນວ່າ %hashref, ບໍ່ແມ່ນ
ການອ້າງອິງຜ່ານ $hashref ໄປຫາ hash ມັນອາດຈະເປັນການອ້າງອີງ. ນັ້ນຈະເປັນ
ກໍລະນີ 3.
3. Subroutine ໂທ ແລະຊອກຫາອົງປະກອບ array ສ່ວນບຸກຄົນເກີດຂຶ້ນເລື້ອຍໆພຽງພໍທີ່ມັນ
ໄດ້ ຮັບ ການ cumbersome ໃນ ການ ນໍາ ໃຊ້ ວິ ທີ ການ 2. ເປັນ ຮູບ ແບບ ຂອງ ້ ໍ າ ຕານ syntactic, ຕົວ ຢ່າງ ສໍາ ລັບ
ວິທີການ 2 ອາດຈະຂຽນ:
$arrayref->[0] = "ມັງກອນ"; # ອົງປະກອບອາເຣ
$hashref->{"KEY"} = "VALUE"; # ອົງປະກອບຂອງ Hash
$coderef->(1,2,3); # ໂທແບບປົກກະຕິ
ເບື້ອງຊ້າຍຂອງລູກສອນສາມາດເປັນການສະແດງຜົນໃດໆທີ່ສົ່ງຄືນການອ້າງອີງ, ລວມທັງ a
ການອ້າງອີງກ່ອນໜ້ານີ້. ໃຫ້ສັງເກດວ່າ $array[$x] ແມ່ນ ບໍ່ ອັນດຽວກັນກັບ "$array->[$x]"
ທີ່ນີ້:
$array[$x]->{"foo"}->[0] = "ມັງກອນ";
ນີ້ແມ່ນ ໜຶ່ງ ໃນກໍລະນີທີ່ພວກເຮົາໄດ້ກ່າວມາກ່ອນ ໜ້າ ນີ້ທີ່ການອ້າງອີງສາມາດເຂົ້າມາ
ທີ່ມີຢູ່ແລ້ວໃນເວລາທີ່ຢູ່ໃນບໍລິບົດ lvalue. ກ່ອນຄຳຖະແຫຼງນີ້, $array[$x] ອາດຈະເປັນ
ບໍ່ໄດ້ກໍານົດ. ຖ້າເປັນດັ່ງນັ້ນ, ມັນຖືກກໍານົດໂດຍອັດຕະໂນມັດດ້ວຍການອ້າງອິງ hash ເພື່ອໃຫ້ພວກເຮົາສາມາດ
ຊອກຫາ "{"foo"}" ໃນມັນ. ເຊັ່ນດຽວກັນ "$array[$x]->{"foo"}" ຈະໄດ້ຮັບອັດຕະໂນມັດ
ຖືກກໍານົດດ້ວຍການອ້າງອິງ array ເພື່ອໃຫ້ພວກເຮົາສາມາດຊອກຫາ "[0]" ໃນມັນ. ຂະບວນການນີ້ແມ່ນ
ເອີ້ນວ່າ autovivification.
ອີກອັນໜຶ່ງຢູ່ທີ່ນີ້. ລູກສອນແມ່ນທາງເລືອກ ລະຫວ່າງ ວົງເລັບ subscripts, ດັ່ງນັ້ນທ່ານສາມາດເຮັດໄດ້
ຫຍໍ້ຂ້າງເທິງລົງໄປ
$array[$x]{"foo"}[0] = "ມັງກອນ";
ເຊິ່ງ, ໃນກໍລະນີທີ່ degenerate ຂອງການນໍາໃຊ້ພຽງແຕ່ arrays ທໍາມະດາ, ໃຫ້ທ່ານ
arrays ຫຼາຍມິຕິລະດັບຄືກັນກັບ C's:
$score[$x][$y][$z] += 42;
ດີ, ບໍ່ເປັນຫຍັງ, ບໍ່ຄືກັບ C's arrays, ຕົວຈິງແລ້ວ. C ບໍ່ຮູ້ວິທີການປູກຂອງມັນ
arrays ຕາມຄວາມຕ້ອງການ. Perl ເຮັດ.
4. ຖ້າການອ້າງອິງເກີດຂຶ້ນເປັນການອ້າງອີງເຖິງວັດຖຸ, ມັນອາດຈະມີວິທີການ
ເພື່ອເຂົ້າເຖິງສິ່ງທີ່ອ້າງເຖິງ, ແລະທ່ານອາດຈະຕິດກັບວິທີການເຫຼົ່ານັ້ນ
ເວັ້ນເສຍແຕ່ວ່າທ່ານຢູ່ໃນຊຸດຊັ້ນຮຽນທີ່ກໍານົດວິທີການຂອງວັດຖຸ. ໃນຄໍາສັບຕ່າງໆອື່ນໆ,
ຈົ່ງດີ, ແລະຢ່າລະເມີດການຫຸ້ມຫໍ່ຂອງວັດຖຸໂດຍບໍ່ມີເຫດຜົນທີ່ດີ.
Perl ບໍ່ໄດ້ບັງຄັບໃຊ້ encapsulation. ພວກເຮົາບໍ່ແມ່ນຜູ້ຜະເດັດການທັງຫມົດທີ່ນີ້. ພວກເຮົາຄາດຫວັງ
ພົນລະເຮືອນພື້ນຖານບາງອັນ.
ການນໍາໃຊ້ສະຕຣິງຫຼືຕົວເລກເປັນການອ້າງອີງຜະລິດເປັນການອ້າງອີງສັນຍາລັກ, ດັ່ງທີ່ອະທິບາຍຂ້າງເທິງ.
ການນໍາໃຊ້ກະສານອ້າງອີງເປັນຈໍານວນຜະລິດເປັນຈໍານວນເຕັມທີ່ເປັນຕົວແທນຂອງສະຖານທີ່ເກັບຮັກສາຂອງຕົນໃນ
ຄວາມຊົງຈໍາ. ສິ່ງດຽວທີ່ເປັນປະໂຫຍດທີ່ຈະເຮັດກັບນີ້ແມ່ນການປຽບທຽບສອງເອກະສານອ້າງອີງ
ຕົວເລກເພື່ອເບິ່ງວ່າພວກເຂົາອ້າງເຖິງສະຖານທີ່ດຽວກັນ.
ຖ້າ ($ref1 == $ref2) { # ການປຽບທຽບຕົວເລກລາຄາຖືກຂອງການອ້າງອີງ
ພິມ "refs 1 ແລະ 2 ຫມາຍເຖິງສິ່ງດຽວກັນ\n";
}
ການນໍາໃຊ້ການອ້າງອິງເປັນສະຕຣິງຜະລິດທັງສອງປະເພດຂອງການອ້າງອິງຂອງມັນ, ລວມທັງຊຸດໃດໆ
ພອນທີ່ອະທິບາຍໄວ້ໃນ perlobj, ເຊັ່ນດຽວກັນກັບທີ່ຢູ່ຕົວເລກທີ່ສະແດງອອກໃນ hex. ໄດ້
ອ້າງອີງ() operator ກັບຄືນພຽງແຕ່ປະເພດຂອງສິ່ງທີ່ກະສານອ້າງອີງແມ່ນຊີ້ໃຫ້ເຫັນ, ໂດຍບໍ່ມີການ
ທີ່ຢູ່. ເບິ່ງ "ref" ໃນ perlfunc ສໍາລັບລາຍລະອຽດແລະຕົວຢ່າງຂອງການນໍາໃຊ້ຂອງມັນ.
ໄດ້ ອວຍພອນ() ໂຕປະຕິບັດການອາດຈະຖືກໃຊ້ເພື່ອເຊື່ອມໂຍງວັດຖຸຈຸດອ້າງອີງກັບ a
ແພັກເກັດເຮັດວຽກເປັນຫ້ອງຮຽນວັດຖຸ. ເບິ່ງ perlobj.
typeglob ອາດຈະຖືກອ້າງອິງແບບດຽວກັນກັບການອ້າງອິງ, ເພາະວ່າການອ້າງອີງ
syntax ສະເຫມີຊີ້ບອກປະເພດຂອງການອ້າງອີງທີ່ຕ້ອງການ. ດັ່ງນັ້ນ "${*foo}" ແລະ "${\$foo}" ທັງສອງ
ຊີ້ບອກຕົວແປສະເກັດເງິນດຽວກັນ.
ນີ້ແມ່ນ trick ສໍາລັບການ interpolating ການເອີ້ນ subroutine ເປັນ string ເປັນ:
ພິມ "ການຍ່ອຍຂອງຂ້ອຍສົ່ງຄືນ @{[mysub(1,2,3)]} ເວລານັ້ນ.\n";
ວິທີທີ່ມັນເຮັດວຽກແມ່ນວ່າເມື່ອ "@{...}" ຖືກເຫັນຢູ່ໃນສະຕຣິງທີ່ອ້າງອີງສອງເທົ່າ, ມັນກໍ່ແມ່ນ.
ປະເມີນເປັນຕັນ. ບລັອກສ້າງການອ້າງອີງເຖິງ array ທີ່ບໍ່ເປີດເຜີຍຊື່ທີ່ປະກອບດ້ວຍ
ຜົນໄດ້ຮັບຂອງການໂທຫາ "mysub(1,2,3)". ດັ່ງນັ້ນທ່ອນໄມ້ທັງຫມົດສົ່ງຄືນການອ້າງອີງເຖິງ an
array, ເຊິ່ງຫຼັງຈາກນັ້ນຖືກອ້າງອີງໂດຍ "@{...}" ແລະຕິດຢູ່ໃນສະຕຣິງທີ່ອ້າງອີງສອງເທົ່າ.
chicanery ນີ້ຍັງເປັນປະໂຫຍດສໍາລັບການສະແດງອອກ arbitrary:
ພິມ "ທີ່ໃຫ້ຜົນຜະລິດ @{[$n + 5]} widget\n";
ເຊັ່ນດຽວກັນ, ການສະແດງອອກທີ່ສົ່ງຄືນການອ້າງອີງເຖິງ scalar ສາມາດ dereferenced ຜ່ານ
"${...}". ດັ່ງນັ້ນ, ການສະແດງອອກຂ້າງເທິງອາດຈະຖືກຂຽນເປັນ:
ພິມ "ທີ່ໃຫ້ຜົນຜະລິດ ${\($n + 5)} widget\n";
Circular ເອກະສານ
ມັນເປັນໄປໄດ້ທີ່ຈະສ້າງ "ການອ້າງອິງວົງກົມ" ໃນ Perl, ເຊິ່ງສາມາດນໍາໄປສູ່ການຮົ່ວໄຫລຂອງຄວາມຊົງຈໍາ. ກ
ການອ້າງອິງເປັນວົງວຽນເກີດຂື້ນໃນເວລາທີ່ສອງເອກະສານອ້າງອີງມີການອ້າງອີງເຊິ່ງກັນແລະກັນ, ເຊັ່ນ
ນີ້:
$foo ຂອງຂ້ອຍ = {};
$bar ຂອງຂ້ອຍ = { foo => $foo };
$foo->{bar} = $bar;
ນອກນັ້ນທ່ານຍັງສາມາດສ້າງການອ້າງອິງເປັນວົງທີ່ມີຕົວແປດຽວ:
$foo ຂອງຂ້ອຍ;
$foo = \$foo;
ໃນກໍລະນີນີ້, ການນັບອ້າງອີງສໍາລັບຕົວປ່ຽນແປງຈະບໍ່ມີເຖິງ 0, ແລະການອ້າງອີງ
ຈະບໍ່ຖືກເກັບຂີ້ເຫຍື້ອ. ນີ້ສາມາດນໍາໄປສູ່ການຮົ່ວໄຫລຂອງຫນ່ວຍຄວາມຈໍາ.
ເນື່ອງຈາກວ່າວັດຖຸໃນ Perl ຖືກປະຕິບັດເປັນການອ້າງອິງ, ມັນເປັນໄປໄດ້ທີ່ຈະມີວົງກົມ
ການອ້າງອິງກັບວັດຖຸເຊັ່ນກັນ. ຈິນຕະນາການຫ້ອງຮຽນ TreeNode ທີ່ແຕ່ລະ node ອ້າງອີງຂອງມັນ
ຂໍ້ຂອງພໍ່ແມ່ແລະລູກ. ໂນດໃດນຶ່ງທີ່ມີພໍ່ແມ່ຈະເປັນສ່ວນໜຶ່ງຂອງການອ້າງອີງເປັນວົງ.
ທ່ານສາມາດທໍາລາຍການອ້າງອິງເປັນວົງໂດຍການສ້າງ "ການອ້າງອິງທີ່ອ່ອນແອ". ການອ້າງອິງທີ່ອ່ອນແອເຮັດ
ບໍ່ເພີ່ມຈໍານວນອ້າງອີງສໍາລັບຕົວແປ, ຊຶ່ງຫມາຍຄວາມວ່າວັດຖຸສາມາດອອກໄປໄດ້
ຂອບເຂດແລະຖືກທໍາລາຍ. ທ່ານສາມາດເຮັດໃຫ້ການອ້າງອິງອ່ອນແອລົງດ້ວຍຟັງຊັນ "ອ່ອນແອ" ທີ່ສົ່ງອອກ
ໂດຍ Scalar::Util module.
ນີ້ແມ່ນວິທີທີ່ພວກເຮົາສາມາດເຮັດໃຫ້ຕົວຢ່າງທໍາອິດທີ່ປອດໄພກວ່າ:
ໃຊ້ Scalar::Util 'ອ່ອນແອ';
$foo ຂອງຂ້ອຍ = {};
$bar ຂອງຂ້ອຍ = { foo => $foo };
$foo->{bar} = $bar;
ອ່ອນຄ່າ $foo->{bar};
ການອ້າງອີງຈາກ $foo ຫາ $bar ໄດ້ອ່ອນລົງ. ເມື່ອຕົວແປ $bar ອອກຈາກ
ຂອບເຂດ, ມັນຈະຖືກເກັບຂີ້ເຫຍື້ອ. ໃນເວລາຕໍ່ໄປທ່ານເບິ່ງມູນຄ່າຂອງ
ລະຫັດ "$foo->{bar}", ມັນຈະເປັນ "undef".
ການປະຕິບັດນີ້ຢູ່ໃນໄລຍະຫ່າງສາມາດສັບສົນ, ສະນັ້ນທ່ານຄວນລະມັດລະວັງກັບການນໍາໃຊ້ຂອງທ່ານ
ອ່ອນເພຍ. ທ່ານຄວນອ່ອນຄ່າການອ້າງອີງໃນຕົວແປທີ່ຈະອອກໄປນອກຂອບເຂດ ຄັ້ງທໍາອິດ.
ດ້ວຍວິທີນັ້ນ, ຕົວແປທີ່ມີອາຍຸຍືນກວ່າຈະມີການອ້າງອີງທີ່ຄາດໄວ້ຈົນກ່ວາມັນອອກໄປ
ຂອງຂອບເຂດ.
ສັນຍາລັກ ເອກະສານ
ພວກເຮົາໄດ້ກ່າວວ່າການອ້າງອີງພາກຮຽນ spring ເຂົ້າໄປໃນການມີຢູ່ເປັນສິ່ງຈໍາເປັນຖ້າຫາກວ່າພວກເຂົາເຈົ້າແມ່ນບໍ່ໄດ້ກໍານົດ, ແຕ່ພວກເຮົາ
ບໍ່ໄດ້ບອກວ່າຈະເກີດຫຍັງຂຶ້ນຖ້າຄ່າທີ່ໃຊ້ເປັນການອ້າງອີງຖືກກຳນົດແລ້ວ, ແຕ່ ບໍ່ແມ່ນ a
ກະສານອ້າງອີງຍາກ. ຖ້າທ່ານໃຊ້ມັນເປັນການອ້າງອິງ, ມັນຈະຖືກປະຕິບັດເປັນການອ້າງອິງສັນຍາລັກ.
ນັ້ນແມ່ນ, ມູນຄ່າຂອງ scalar ໄດ້ຖືກປະຕິບັດເປັນ ຊື່ ຂອງຕົວແປ, ແທນທີ່ຈະເປັນ
ການເຊື່ອມຕໍ່ໂດຍກົງກັບມູນຄ່າທີ່ບໍ່ເປີດເຜີຍຕົວຕົນ (ອາດຈະ).
ຄົນມັກຈະຄາດຫວັງວ່າມັນຈະເຮັດວຽກແບບນີ້. ດັ່ງນັ້ນມັນເຮັດ.
$name = "foo";
$$name = 1; # ຊຸດ $foo
${$name} = 2; # ຊຸດ $foo
${$name x 2} = 3; # ຊຸດ $foofoo
$name->[0] = 4; # ຊຸດ $foo[0]
@$name = (); # ລ້າງ @foo
&$name(); # ໂທ &foo()
$pack = "ນັ້ນ";
${"${pack}::$name"} = 5; # ຕັ້ງ $THAT::foo ໂດຍບໍ່ມີການ eval
ນີ້ແມ່ນມີອໍານາດ, ແລະເປັນອັນຕະລາຍເລັກນ້ອຍ, ໃນທີ່ມັນເປັນໄປໄດ້ທີ່ຈະຕັ້ງໃຈ (ໂດຍທີ່ສຸດ
ຄວາມຈິງໃຈ) ໃຊ້ການອ້າງອີງຍາກ, ແລະບັງເອີນໃຊ້ການອ້າງອິງທີ່ເປັນສັນຍາລັກແທນ. ເຖິງ
ປົກປ້ອງສິ່ງນັ້ນ, ເຈົ້າສາມາດເວົ້າໄດ້
ໃຊ້ 'refs' ທີ່ເຄັ່ງຄັດ;
ແລະຫຼັງຈາກນັ້ນພຽງແຕ່ການອ້າງອິງຍາກຈະຖືກອະນຸຍາດໃຫ້ສໍາລັບສ່ວນທີ່ເຫຼືອຂອງຕັນ enclosing. ອັນ
ຕັນພາຍໃນອາດຈະຕ້ານກັບວ່າ
ບໍ່ມີ 'refs' ທີ່ເຄັ່ງຄັດ;
ມີພຽງແຕ່ຕົວແປຂອງແພັກເກັດ (ທົ່ວໂລກ, ເຖິງແມ່ນວ່າຈະຖືກແປເປັນທ້ອງຖິ່ນ) ເທົ່ານັ້ນທີ່ເຫັນໄດ້ຈາກການອ້າງອີງທີ່ເປັນສັນຍາລັກ.
ຕົວແປ lexical (ປະກາດດ້ວຍ ຂອງຂ້ອຍ()) ບໍ່ຢູ່ໃນຕາຕະລາງສັນຍາລັກ, ແລະດັ່ງນັ້ນຈຶ່ງແມ່ນເບິ່ງບໍ່ເຫັນ
ກົນໄກນີ້. ຍົກຕົວຢ່າງ:
ທ້ອງຖິ່ນ $value = 10;
$ref = "ມູນຄ່າ";
{
$value ຂອງຂ້ອຍ = 20;
ພິມ $$ref;
}
ນີ້ຈະຍັງຄົງພິມ 10, ບໍ່ແມ່ນ 20. ຈື່ໄວ້ວ່າ ທ້ອງຖິ່ນ() ຜົນກະທົບຕໍ່ຕົວແປຊຸດ, ເຊິ່ງ
ທັງຫມົດແມ່ນ "ທົ່ວໂລກ" ກັບຊຸດ.
ບໍ່ເປັນສັນຍາລັກ ເອກະສານ
ວົງເລັບອ້ອມຮອບການອ້າງອິງສັນຍາລັກພຽງແຕ່ສາມາດຮັບໃຊ້ເພື່ອແຍກຕົວລະບຸຫຼືຕົວແປ
ຊື່ຈາກສ່ວນທີ່ເຫຼືອຂອງການສະແດງຜົນ, ຄືກັນກັບວ່າພວກມັນມີຢູ່ໃນສະຕຣິງຢູ່ສະເໝີ. ສໍາລັບ
ຍົກຕົວຢ່າງ,
$push = "ປະກົດຂຶ້ນ";
ພິມ "${push}over";
ສະເຫມີຫມາຍເຖິງການພິມ "pop on over", ເຖິງແມ່ນວ່າ push ເປັນຄໍາສະຫງວນ. ນີ້ແມ່ນ
generalized ເຮັດວຽກດຽວກັນໂດຍບໍ່ມີການວົງຢືມ double enclosing, ດັ່ງນັ້ນ
ພິມ ${push} . "ເກີນ";
ແລະເຖິງແມ່ນວ່າ
ພິມ ${ push } . "ເກີນ";
ຈະມີຜົນຄືກັນ. ການກໍ່ສ້າງນີ້ແມ່ນ ບໍ່ ຖືວ່າເປັນສັນຍາລັກອ້າງອີງ
ເມື່ອເຈົ້າໃຊ້ການອ້າງອີງຢ່າງເຂັ້ມງວດ:
ໃຊ້ 'refs' ທີ່ເຄັ່ງຄັດ;
${ bareword }; # ໂອເຄ, ຫມາຍຄວາມວ່າ $bareword.
${ "bareword" }; # ຄວາມຜິດພາດ, ການອ້າງອີງສັນຍາລັກ.
ເຊັ່ນດຽວກັນ, ເນື່ອງຈາກວ່າການສະຫມັກທັງຫມົດແມ່ນເຮັດໂດຍໃຊ້ຄໍາດຽວ, ກົດລະບຽບດຽວກັນ
ນຳໃຊ້ກັບຄຳເປົ່າທີ່ໃຊ້ສຳລັບການສະໝັກສະມາຊິກ hash. ດັ່ງນັ້ນໃນປັດຈຸບັນ, ແທນທີ່ຈະຂຽນ
$array{ "aaa" }{ "bbb" { "ccc" }
ທ່ານສາມາດຂຽນພຽງແຕ່
$array{ aaa }{ bbb { ccc }
ແລະບໍ່ກັງວົນກ່ຽວກັບວ່າ subscripts ເປັນຄໍາທີ່ສະຫງວນໄວ້. ໃນກໍລະນີທີ່ຫາຍາກທີ່ທ່ານ
ຕ້ອງການເຮັດບາງສິ່ງບາງຢ່າງເຊັ່ນ:
$array{ shift }
ທ່ານສາມາດບັງຄັບການຕີຄວາມຫມາຍເປັນຄໍາສະຫງວນໂດຍການເພີ່ມສິ່ງໃດແດ່ທີ່ເຮັດໃຫ້ມັນຫຼາຍກວ່າ
ຄໍາແປເປັນ:
$array{ shift() }
$array{ +shift }
$array{ shift @_ }
"ການເຕືອນໄພການນໍາໃຊ້" pragma ຫຼື -w switch ຈະເຕືອນທ່ານຖ້າມັນຕີຄວາມຫມາຍຂອງຄໍາທີ່ສະຫງວນໄວ້
ເປັນສາຍ. ແຕ່ວ່າມັນຈະບໍ່ມີຕໍ່ໄປອີກແລ້ວເຕືອນທ່ານກ່ຽວກັບການນໍາໃຊ້ຄໍາສັບນ້ອຍ, ເພາະວ່າ
string ຖືກອ້າງອີງຢ່າງມີປະສິດທິພາບ.
Pseudo-hashes: ການນໍາໃຊ້ an array as a hash
Pseudo-hashes ໄດ້ຖືກໂຍກຍ້າຍອອກຈາກ Perl. Pragma 'ທົ່ງນາ' ຍັງມີຢູ່.
ຫນ້າທີ່ ແມ່ແບບ
ດັ່ງທີ່ໄດ້ອະທິບາຍຂ້າງເທິງ, ຟັງຊັນທີ່ບໍ່ເປີດເຜີຍຊື່ທີ່ມີການເຂົ້າເຖິງຕົວແປ lexical ທີ່ເຫັນໄດ້
ເມື່ອຟັງຊັນນັ້ນຖືກລວບລວມ, ສ້າງການປິດ. ມັນຮັກສາການເຂົ້າເຖິງຕົວແປເຫຼົ່ານັ້ນ
ເຖິງແມ່ນວ່າມັນບໍ່ໄດ້ຮັບການແລ່ນຈົນກ່ວາຕໍ່ມາ, ເຊັ່ນໃນຕົວຈັບສັນຍານຫຼື Tk callback.
ການນໍາໃຊ້ການປິດເປັນແມ່ແບບຟັງຊັນຊ່ວຍໃຫ້ພວກເຮົາສາມາດສ້າງຫນ້າທີ່ເຮັດວຽກຫຼາຍຢ່າງ
ເຊັ່ນດຽວກັນ. ສົມມຸດວ່າທ່ານຕ້ອງການຟັງຊັນທີ່ມີຊື່ຕາມສີທີ່ສ້າງຕົວອັກສອນ HTML
ການປ່ຽນແປງຂອງສີຕ່າງໆ:
ພິມ "Be", ສີແດງ("ລະມັດລະວັງ"), "ກັບວ່າ", ສີຂຽວ("ແສງສະຫວ່າງ");
ໄດ້ ສີແດງ() ແລະ ສີຂຽວ() ຫນ້າທີ່ຈະຄ້າຍຄືກັນ. ເພື່ອສ້າງສິ່ງເຫຼົ່ານີ້, ພວກເຮົາຈະກໍານົດການປິດ
ໄປຫາ typeglob ຂອງຊື່ຂອງຟັງຊັນທີ່ພວກເຮົາກໍາລັງພະຍາຍາມສ້າງ.
@colors = qw(ສີແດງ ສີຟ້າ ສີຂຽວ ສີເຫຼືອງ ສີສົ້ມ ສີມ່ວງ ສີມ່ວງ);
ສໍາລັບ $name ຂອງຂ້ອຍ (@colors) {
ບໍ່ມີ 'refs' ທີ່ເຄັ່ງຄັດ; # ອະນຸຍາດໃຫ້ການຈັດການຕາຕະລາງສັນຍາລັກ
*$name = *{uc $name} = sub { " @_ " };
}
ດຽວນີ້ ໜ້າ ທີ່ທີ່ແຕກຕ່າງກັນທັງ ໝົດ ປະກົດວ່າເປັນເອກະລາດ. ທ່ານສາມາດໂທຫາ ສີແດງ(),
ສີແດງ(), ສີຟ້າ(), ສີຟ້າ(), ສີຂຽວ(), ແລະອື່ນໆ. ເຕັກນິກນີ້ປະຫຍັດທັງເວລາລວບລວມແລະຄວາມຊົງຈໍາ
ໃຊ້, ແລະມີຄວາມຜິດພາດຫນ້ອຍເຊັ່ນດຽວກັນ, ນັບຕັ້ງແຕ່ການກວດສອບ syntax ເກີດຂື້ນໃນເວລາລວບລວມ. ມັນ
ສໍາຄັນວ່າຕົວແປໃດໆໃນ subroutine ທີ່ບໍ່ເປີດເຜີຍຊື່ເປັນ lexicals ເພື່ອສ້າງເປັນ.
ການປິດທີ່ເຫມາະສົມ. ນັ້ນແມ່ນເຫດຜົນຂອງ "ຂອງຂ້ອຍ" ໃນຕົວແປ loop.
ນີ້ແມ່ນຫນຶ່ງໃນສະຖານທີ່ດຽວທີ່ໃຫ້ເຄື່ອງຕົ້ນແບບກັບການປິດເຮັດໃຫ້ມີຄວາມຮູ້ສຶກຫຼາຍ. ຖ້າ
ທ່ານຕ້ອງການທີ່ຈະກໍານົດສະເລ່ຍກ່ຽວກັບການໂຕ້ຖຽງຂອງຫນ້າທີ່ເຫຼົ່ານີ້ (ອາດຈະບໍ່ແມ່ນ a
ຄວາມຄິດທີ່ສະຫລາດສໍາລັບຕົວຢ່າງນີ້ໂດຍສະເພາະ), ທ່ານສາມາດຂຽນມັນດ້ວຍວິທີນີ້ແທນ:
*$name = ຍ່ອຍ ($) { " $_[0] " };
ຢ່າງໃດກໍ່ຕາມ, ນັບຕັ້ງແຕ່ການກວດສອບຕົ້ນແບບເກີດຂຶ້ນໃນເວລາລວບລວມ, ການມອບຫມາຍຂ້າງເທິງຈະເກີດຂື້ນ
ຊ້າເກີນໄປທີ່ຈະເປັນປະໂຫຍດຫຼາຍ. ທ່ານສາມາດແກ້ໄຂນີ້ໂດຍການວາງ loop ທັງຫມົດຂອງ
ການມອບຫມາຍພາຍໃນບລັອກ BEGIN, ບັງຄັບໃຫ້ມັນເກີດຂຶ້ນໃນລະຫວ່າງການລວບລວມ.
ການເຂົ້າເຖິງ lexicals ທີ່ມີການປ່ຽນແປງໃນໄລຍະເວລາທີ່ຄ້າຍຄືກັບ "ສໍາລັບ" loop ຂ້າງເທິງ, ໂດຍພື້ນຖານແລ້ວ
ນາມແຝງກັບອົງປະກອບຈາກຂອບເຂດ lexical ອ້ອມຂ້າງ - ພຽງແຕ່ເຮັດວຽກກັບ subs ທີ່ບໍ່ເປີດເຜີຍຊື່,
ບໍ່ແມ່ນການກຳນົດເວລາຍ່ອຍທີ່ມີຊື່. ໂດຍທົ່ວໄປແລ້ວ, subroutines ທີ່ມີຊື່ບໍ່ໄດ້ຮັງຢ່າງຖືກຕ້ອງແລະ
ຄວນຖືກປະກາດຢູ່ໃນຂອບເຂດຊຸດຫຼັກເທົ່ານັ້ນ.
ນີ້ແມ່ນຍ້ອນວ່າ subroutines ທີ່ມີຊື່ຖືກສ້າງຂື້ນໃນເວລາລວບລວມສະນັ້ນຕົວແປ lexical ຂອງມັນ
ໄດ້ຮັບການມອບຫມາຍໃຫ້ lexicals ພໍ່ແມ່ຈາກການປະຕິບັດຄັ້ງທໍາອິດຂອງຕັນແມ່. ຖ້າ ກ
ຂອບເຂດຂອງພໍ່ແມ່ຖືກໃສ່ເປັນຄັ້ງທີສອງ, lexicals ຂອງມັນໄດ້ຖືກສ້າງຂື້ນອີກເທື່ອຫນຶ່ງ, ໃນຂະນະທີ່ຮັງ
subs ຍັງອ້າງເຖິງອັນເກົ່າ.
routines ຍ່ອຍທີ່ບໍ່ເປີດເຜີຍຊື່ສາມາດຈັບແຕ່ລະຄັ້ງທີ່ທ່ານປະຕິບັດຕົວປະຕິບັດການ "ຍ່ອຍ", ຍ້ອນວ່າພວກເຂົາເປັນ.
ສ້າງຂຶ້ນໃນການບິນໄດ້. ຖ້າເຈົ້າຄຸ້ນເຄີຍກັບການໃຊ້ໂປຣເຈັກຍ່ອຍທີ່ຕິດກັນໃນການຂຽນໂປຼແກຼມອື່ນ
ພາສາທີ່ມີຕົວແປສ່ວນຕົວຂອງເຂົາເຈົ້າເອງ, ທ່ານຈະຕ້ອງໄດ້ເຮັດວຽກຢູ່ໃນມັນເລັກນ້ອຍໃນ Perl. ໄດ້
ການເຂົ້າລະຫັດ intuitive ຂອງປະເພດນີ້ incurs ເຕືອນ mysterious ກ່ຽວກັບ "ຈະບໍ່ຢູ່
ແບ່ງປັນ" ເນື່ອງຈາກເຫດຜົນທີ່ອະທິບາຍຂ້າງເທິງ. ຕົວຢ່າງ, ອັນນີ້ຈະບໍ່ເຮັດວຽກ:
ຍ່ອຍນອກ {
$x ຂອງຂ້ອຍ = $_[0] + 35;
sub inner { return $x * 19 } # WRONG
ກັບຄືນ $x + inner();
}
A work-round ແມ່ນດັ່ງຕໍ່ໄປນີ້:
ຍ່ອຍນອກ {
$x ຂອງຂ້ອຍ = $_[0] + 35;
local *inner = sub { return $x * 19 };
ກັບຄືນ $x + inner();
}
ໃນປັດຈຸບັນ ພາຍໃນ() ສາມາດເອີ້ນໄດ້ຈາກພາຍໃນເທົ່ານັ້ນ ນອກ(), ເນື່ອງຈາກການມອບຫມາຍຊົ່ວຄາວ
ຂອງ routine ຍ່ອຍທີ່ບໍ່ເປີດເຜີຍຊື່. ແຕ່ໃນເວລາທີ່ມັນເຮັດ, ມັນມີການເຂົ້າເຖິງປົກກະຕິກັບ lexical
ຕົວແປ $x ຈາກຂອບເຂດຂອງ ນອກ() ໃນເວລານອກຖືກເອີ້ນ.
ນີ້ມີຜົນກະທົບທີ່ຫນ້າສົນໃຈຂອງການສ້າງຫນ້າທີ່ທ້ອງຖິ່ນກັບຫນ້າທີ່ອື່ນ,
ບາງສິ່ງບາງຢ່າງທີ່ປົກກະຕິບໍ່ໄດ້ຮັບການສະຫນັບສະຫນູນໃນ Perl.
ຄໍາເຕືອນ
ທ່ານອາດຈະບໍ່ (ເປັນປະໂຫຍດ) ໃຊ້ການອ້າງອິງເປັນກຸນແຈຂອງ hash. ມັນຈະຖືກປ່ຽນເປັນ ກ
ຊ່ອຍແນ່:
$x{ \$a } = $a;
ຖ້າທ່ານພະຍາຍາມ dereference ທີ່ສໍາຄັນ, ມັນຈະບໍ່ເປັນການ dereference ຍາກ, ແລະທ່ານຈະບໍ່
ເຮັດສໍາເລັດໃນສິ່ງທີ່ເຈົ້າພະຍາຍາມ. ທ່ານອາດຈະຕ້ອງການເຮັດບາງສິ່ງບາງຢ່າງເຊັ່ນ:
$r = \@a;
$x{ $r } = $r;
ແລະຫຼັງຈາກນັ້ນຢ່າງຫນ້ອຍທ່ານສາມາດນໍາໃຊ້ໄດ້ ຄຸນຄ່າ (), ເຊິ່ງຈະເປັນການອ້າງອີງທີ່ແທ້ຈິງ, ແທນທີ່ຈະເປັນ
ກະແຈ(), ເຊິ່ງຈະບໍ່.
Tie ມາດຕະຖານ::ໂມດູນ RefHash ສະຫນອງການແກ້ໄຂສະດວກຕໍ່ກັບເລື່ອງນີ້.
postfix ການອ້າງອິງ syntax
ເລີ່ມຕົ້ນໃນ v5.20.0, syntax postfix ສໍາລັບການນໍາໃຊ້ການອ້າງອີງແມ່ນມີຢູ່. ມັນປະຕິບັດຕົວເປັນ
ອະທິບາຍໄວ້ໃນ "ການນໍາໃຊ້ການອ້າງອິງ", ແຕ່ແທນທີ່ຈະເປັນ sigil prefixed, postfixed sigil-and-
ດາວຖືກນໍາໃຊ້.
ຍົກຕົວຢ່າງ:
$r = \@a;
@b=$r->@*; # ເທົ່າກັບ @$r ຫຼື @{ $r }
$r = [ 1 , [ 2 , 3 ], 4 ];
$r->[1]->@*; # ເທົ່າກັບ @{ $r->[1] }
syntax ນີ້ຕ້ອງຖືກເປີດໃຊ້ດ້ວຍ "ໃຊ້ຄຸນສົມບັດ 'postderef'". ມັນເປັນການທົດລອງ, ແລະຈະ
ເຕືອນໂດຍຄ່າເລີ່ມຕົ້ນເວັ້ນເສຍແຕ່ "ບໍ່ມີຄໍາເຕືອນ 'ທົດລອງ::postderef'" ຈະມີຜົນ.
Postfix dereference ຄວນເຮັດວຽກໃນທຸກສະຖານະການທີ່ block (circumfix) dereference
ເຮັດວຽກ, ແລະຄວນຈະທຽບເທົ່າທັງຫມົດ. syntax ນີ້ອະນຸຍາດໃຫ້ຂຽນ dereferencing
ແລະອ່ານທັງໝົດຈາກຊ້າຍຫາຂວາ. ການທຽບເທົ່າຕໍ່ໄປນີ້ແມ່ນຖືກກໍານົດ:
$sref->$*; # ຄືກັນກັບ ${ $sref }
$aref->@*; # ຄືກັນກັບ @{ $aref }
$aref->$#*; # ຄືກັນກັບ $#{ $aref }
$href->%*; # ຄືກັນກັບ %{ $href }
$cref->&*; # ຄືກັນກັບ &{ $cref }
$gref->**; # ຄືກັນກັບ *{ $gref }
ໃຫ້ສັງເກດວ່າໂດຍສະເພາະ "$cref->&*" ແມ່ນ ບໍ່ ເທົ່າກັບ "$cref->()", ແລະສາມາດໃຫ້ບໍລິການທີ່ແຕກຕ່າງກັນ
ຈຸດປະສົງ.
ອົງປະກອບ Glob ສາມາດສະກັດໄດ້ໂດຍຜ່ານຄຸນສົມບັດການອ້າງອິງ postfix:
$gref->*{SCALAR}; # ຄືກັນກັບ *{ $gref }{SCALAR}
Postfix array ແລະ scalar dereferencing ສາມາດເຮັດໄດ້ ຖືກນໍາໃຊ້ໃນ interpolating strings (ວົງຢືມຄູ່
ຫຼື "qq" operator), ແຕ່ພຽງແຕ່ຖ້າຄຸນສົມບັດ "postderef_qq" ເພີ່ມເຕີມຖືກເປີດໃຊ້.
postfix ກະສານອ້າງອີງ ຊິ້ນສ່ວນ
ສ່ວນມູນຄ່າຂອງ arrays ແລະ hashes ອາດຈະຖືກປະຕິບັດດ້ວຍການອ້າງອີງການອ້າງອີງ postfix,
ດ້ວຍການທຽບເທົ່າດັ່ງຕໍ່ໄປນີ້:
$aref->@[ ... ]; # ຄືກັນກັບ @$aref[ ... ]
$href->@{ ... }; # ຄືກັນກັບ @$href{ ... }
Postfix key/value slicing, ເພີ່ມໃນ 5.20.0 ແລະບັນທຶກໄວ້ໃນ Key/Value Hash
ສ່ວນ Slices ຂອງ perldata, ຍັງປະຕິບັດຕົວຕາມທີ່ຄາດໄວ້:
$aref->%[ ... ]; # ຄືກັນກັບ %$aref[ ... ]
$href->%{ ... }; # ຄືກັນກັບ %$href{ ... }
ເຊັ່ນດຽວກັນກັບ array postfix, postfix value slice dereferencing ສາມາດເຮັດໄດ້ ຖືກນໍາໃຊ້ໃນ interpolating
strings (double quotes ຫຼື "qq" operator), ແຕ່ວ່າພຽງແຕ່ຖ້າ "postderef_qq" ເພີ່ມເຕີມ
ຄຸນສົມບັດຖືກເປີດໃຊ້ງານ.
ການມອບ ໝາຍ to ເອກະສານ
ເລີ່ມຕົ້ນໃນ v5.22.0, ຜູ້ປະຕິບັດການອ້າງອີງສາມາດຖືກມອບຫມາຍໃຫ້. ມັນປະຕິບັດເປັນ
ການປະຕິບັດນາມແຝງ, ດັ່ງນັ້ນຊື່ຕົວແປທີ່ອ້າງອີງຢູ່ເບື້ອງຊ້າຍມືກາຍເປັນ
ນາມແຝງຂອງສິ່ງທີ່ອ້າງອີງຢູ່ເບື້ອງຂວາ:
\$a = \$b; # $a ແລະ $b ຕອນນີ້ຊີ້ໄປທີ່ສະເກັດເລກດຽວກັນ
\&foo = \&bar; # foo() ປະຈຸບັນຫມາຍຄວາມວ່າ bar()
syntax ນີ້ຕ້ອງຖືກເປີດໃຊ້ດ້ວຍ "ໃຊ້ຄຸນສົມບັດ 'refaliasing'". ມັນແມ່ນການທົດລອງ, ແລະ
ຈະເຕືອນໂດຍຄ່າເລີ່ມຕົ້ນເວັ້ນເສຍແຕ່ "ບໍ່ມີການເຕືອນໄພ 'ທົດລອງ:: refaliasing'" ມີຜົນບັງຄັບໃຊ້.
ແບບຟອມເຫຼົ່ານີ້ອາດຈະຖືກມອບຫມາຍໃຫ້, ແລະເຮັດໃຫ້ທາງດ້ານຂວາມືຖືກປະເມີນໃນສະເກັດເງິນ
ບໍລິບົດ:
\$scalar
\@array
\%hash
\&ຍ່ອຍ
\ my $scalar
\my @array
\ % hash ຂອງຂ້ອຍ
\state $scalar # ຫຼື @array, ແລະອື່ນໆ.
\ our $scalar # etc.
\ທ້ອງຖິ່ນ $scalar # ແລະອື່ນໆ.
\ ທ້ອງຖິ່ນຂອງພວກເຮົາ $scalar # ແລະອື່ນໆ.
\$some_array[$index]
\$some_hash{$key}
\ທ້ອງຖິ່ນ $some_array[$index]
\ທ້ອງຖິ່ນ $some_hash{$key}
ສະພາບ? \$this : \$tha[0] # ແລະອື່ນໆ.
ການດໍາເນີນງານ Slicing ແລະວົງເລັບເຮັດໃຫ້ທາງດ້ານຂວາມືຖືກປະເມີນຢູ່ໃນບັນຊີລາຍຊື່
ບໍລິບົດ:
\@array[5..7]
(\@array[5..7])
\(@array[5..7])
\@hash{'foo','bar'}
(\@hash{'foo','bar'})
\(@hash{'foo','bar'})
(\$scalar)
\($scalar)
\($scalar ຂອງຂ້ອຍ)
\my($scalar)
(\@array)
(\%hash)
(\&ຍ່ອຍ)
\(&ຍ່ອຍ)
\($foo, @bar, %baz)
(\$foo, \@bar, \%baz)
ແຕ່ລະອົງປະກອບຢູ່ເບື້ອງຂວາມືຕ້ອງເປັນການອ້າງອີງເຖິງ datum ຂອງປະເພດທີ່ຖືກຕ້ອງ.
ວົງເລັບທັນທີທີ່ອ້ອມຮອບ array (ແລະອາດຈະເປັນ
"my"/"state"/"our"/"local") ຈະເຮັດໃຫ້ແຕ່ລະອົງປະກອບຂອງ array ເປັນນາມແຝງ.
ຕາຕະລາງທີ່ສອດຄ້ອງກັນທີ່ອ້າງອີງຢູ່ເບື້ອງຂວາ:
\(@a) = \(@b); # @a ແລະ @b ໃນປັດຈຸບັນມີອົງປະກອບດຽວກັນ
\my(@a) = \(@b); # ຄືກັນ
\(my @a) = \(@b); # ຄືກັນ
push @a, 3; # ແຕ່ຕອນນີ້ @a ມີອົງປະກອບພິເສດທີ່ @b ຂາດ
\(@a) = (\$a, \$b, \$c); # @a ປະຈຸບັນມີ $a, $b, ແລະ $c
ການສົມທົບແບບຟອມນັ້ນກັບ "ທ້ອງຖິ່ນ" ແລະວາງວົງເລັບທັນທີປະມານ hash ແມ່ນ
ຫ້າມ (ເພາະວ່າມັນບໍ່ຊັດເຈນວ່າພວກເຂົາຄວນເຮັດແນວໃດ):
\local(@array) = foo(); # ຜິດ
\(%hash) = ແຖບ(); # ຜິດ
ການມອບຫມາຍໃຫ້ກັບການອ້າງອິງແລະບໍ່ອ້າງອີງອາດຈະຖືກລວມເຂົ້າກັນໃນລາຍການແລະເງື່ອນໄຂ
ການສະແດງອອກຂອງ ternary, ຕາບໃດທີ່ຄ່າຢູ່ເບື້ອງຂວາມືແມ່ນປະເພດທີ່ຖືກຕ້ອງ
ແຕ່ລະອົງປະກອບຢູ່ເບື້ອງຊ້າຍ, ເຖິງແມ່ນວ່ານີ້ອາດຈະເຮັດໃຫ້ສໍາລັບການລະຫັດ obfuscated:
($tom, \my $dick, \my @harry) = (\1, \2, [1..3]);
# $tom ແມ່ນຕອນນີ້ \1
# $dick ດຽວນີ້ແມ່ນ 2 (ອ່ານເທົ່ານັ້ນ)
# @harry ແມ່ນ (1,2,3)
my $type = ref $thingy;
($type ? $type == 'ARRAY' ? \@foo : \$bar : $baz) = $thingy;
loop "foreach" ຍັງສາມາດໃຊ້ຕົວສ້າງອ້າງອີງສໍາລັບຕົວແປ loop ຂອງມັນ, ເຖິງແມ່ນວ່າ
syntax ແມ່ນຈໍາກັດຫນຶ່ງຕໍ່ໄປນີ້, ໂດຍມີທາງເລືອກ "ຂອງຂ້ອຍ", "ລັດ", ຫຼື "ຂອງພວກເຮົາ" ຫຼັງຈາກ
backslash ໄດ້:
\$s
\@ກ
\%h
\&c
ບໍ່ອະນຸຍາດໃຫ້ມີວົງເລັບ. ຄຸນນະສົມບັດນີ້ແມ່ນເປັນປະໂຫຍດໂດຍສະເພາະສໍາລັບ array-of-arrays,
ຫຼື array-of-hashes:
foreach \my @a (@array_of_arrays) {
frobnicate($a[0], $a[-1]);
}
foreach \my %h (@array_of_hashes) {
$h{gelastic}++ ຖ້າ $h{type} == 'ຕະຫຼົກ';
}
ຄໍາເຕືອນ: aliasing ບໍ່ເຮັດວຽກຢ່າງຖືກຕ້ອງກັບການປິດ. ຖ້າທ່ານພະຍາຍາມ alias lexical
ຕົວແປຈາກບັນຊີຍ່ອຍພາຍໃນ ຫຼື "eval", ນາມແຝງຈະເຫັນໄດ້ພາຍໃນ.
subroutine ພາຍໃນນັ້ນ, ແລະຈະບໍ່ມີຜົນກະທົບ subroutine ພາຍນອກທີ່ຕົວແປໄດ້ຖືກປະກາດ.
ພຶດຕິກໍາທີ່ແປກປະຫຼາດນີ້ອາດຈະມີການປ່ຽນແປງ.
ໃຊ້ perlref ອອນໄລນ໌ໂດຍໃຊ້ບໍລິການ onworks.net