ພາສາອັງກິດພາສາຝຣັ່ງແອສປາໂຍນ

OnWorks favicon

PDL::PPp - ອອນລາຍໃນຄລາວ

ແລ່ນ PDL::PPp ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີຜ່ານ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator

ນີ້ແມ່ນຄໍາສັ່ງ PDL::PPp ທີ່ສາມາດດໍາເນີນການໄດ້ໃນ OnWorks ຜູ້ໃຫ້ບໍລິການໂຮດຕິ້ງຟຣີໂດຍໃຊ້ຫນຶ່ງໃນຫຼາຍບ່ອນເຮັດວຽກອອນໄລນ໌ຂອງພວກເຮົາເຊັ່ນ Ubuntu Online, Fedora Online, Windows online emulator ຫຼື MAC OS online emulator

ໂຄງການ:

NAME


PDL::PP - ສ້າງສິ່ງທີ່ເຮັດປະຈຳ PDL ຈາກຄຳອະທິບາຍຫຍໍ້

ສະຫຼຸບສັງລວມ


ຕົວຢ່າງ:

pp_def(
'sumover',
Pars => 'a(n); [o]b();',
ລະຫັດ => q{
tmp ສອງເທົ່າ = 0;
loop(n) %{
tmp += $a();
%}
$b() = tmp;
},
);

pp_done();

FUNCTIONS


ນີ້ແມ່ນບັນຊີລາຍຊື່ອ້າງອີງໄວຂອງຫນ້າທີ່ສະຫນອງໃຫ້ໂດຍ PDL::PP.

pp_add_boot
ເພີ່ມລະຫັດໃສ່ພາກສ່ວນ BOOT ຂອງໄຟລ໌ XS ທີ່ສ້າງຂຶ້ນ

pp_add_ສົ່ງອອກ
ເພີ່ມຟັງຊັນໃນບັນຊີລາຍຊື່ຂອງຫນ້າທີ່ສົ່ງອອກ

pp_add_isa
ເພີ່ມລາຍການໃສ່ລາຍຊື່ @ISA

pp_addbegin
ກໍານົດລະຫັດທີ່ຈະເພີ່ມຢູ່ເທິງສຸດຂອງໄຟລ໌ .pm ສ້າງ

pp_addhdr
ເພີ່ມລະຫັດ ແລະຮວມໃສ່ພາກສ່ວນ C ຂອງໄຟລ໌ XS ທີ່ສ້າງຂຶ້ນ

pp_addpm
ເພີ່ມລະຫັດໃສ່ໄຟລ໌ .pm ທີ່ສ້າງຂຶ້ນ

pp_addxs
ເພີ່ມລະຫັດ XS ເພີ່ມເຕີມໃສ່ໄຟລ໌ XS ທີ່ສ້າງຂຶ້ນ

pp_beginwrap
ເພີ່ມ BEGIN-block wrapping ໃສ່ລະຫັດສໍາລັບໄຟລ໌ .pm ທີ່ສ້າງຂຶ້ນ

pp_bless
ກໍານົດຊຸດທີ່ລະຫັດ XS ຖືກເພີ່ມ (ຄ່າເລີ່ມຕົ້ນແມ່ນ PDL)

pp_boundscheck
ຄວບຄຸມສະຖານະຂອງກິດຈະກໍາການກວດສອບຂອບເຂດ PDL

pp_core_importList
ລະບຸສິ່ງທີ່ນໍາເຂົ້າຈາກ PDL::Core

pp_def
ກໍານົດຟັງຊັນ PDL ໃຫມ່

pp_deprecate_module
ເພີ່ມເວລາແລ່ນ ແລະຄຳເຕືອນ POD ກ່ຽວກັບໂມດູນທີ່ກຳລັງຖືກຍົກເລີກ

pp_done
ໝາຍຈຸດສິ້ນສຸດຂອງ PDL::ຄຳນິຍາມ PP ໃນໄຟລ໌

pp_export_nothing
ລຶບລາຍການສົ່ງອອກສໍາລັບໂມດູນທີ່ສ້າງຂຶ້ນຂອງທ່ານ

pp_line_numbers
ເພີ່ມຂໍ້ມູນເລກແຖວເພື່ອເຮັດໃຫ້ການດີບັກຂອງ PDL::ລະຫັດ PP ງ່າຍຂຶ້ນ

pp_setversion
ກຳນົດເວີຊັນສຳລັບໄຟລ໌ .pm ແລະ .xs

ພາບລວມ


ເປັນຫຍັງພວກເຮົາຕ້ອງການ PP? ເຫດຜົນຫຼາຍຢ່າງ: ທໍາອິດ, ພວກເຮົາຕ້ອງການທີ່ຈະສາມາດສ້າງ subroutine
ລະຫັດສໍາລັບແຕ່ລະປະເພດຂໍ້ມູນ PDL (PDL_Byte, PDL_Short, ແລະອື່ນໆ). ອັດຕະໂນມັດ. ອັນທີສອງ,
ເມື່ອອ້າງອີງໃສ່ຊິ້ນສ່ວນຂອງ PDL arrays ໃນ Perl (ເຊັ່ນ "$a->slice('0:10:2,:')" ຫຼືອື່ນໆ.
ສິ່ງຕ່າງໆເຊັ່ນ transposes) ມັນເປັນການດີທີ່ຈະສາມາດເຮັດສິ່ງນີ້ໂປ່ງໃສແລະສາມາດ
ເພື່ອເຮັດສິ່ງນີ້ 'ໃນສະຖານທີ່' - ie, ບໍ່ຈໍາເປັນຕ້ອງເຮັດສໍາເນົາຄວາມຊົງຈໍາຂອງພາກ. PP handles
ອົງປະກອບທີ່ຈໍາເປັນທັງຫມົດແລະ offset ເລກຄະນິດສາດສໍາລັບທ່ານ. ຍັງມີແນວຄິດຂອງ
threading (ການເອີ້ນຊ້ໍາກັນຂອງປົກກະຕິດຽວກັນສໍາລັບຫຼາຍ slices, ເບິ່ງ PDL::Indexing)
ແລະ dataflow (ເບິ່ງ PDL::Dataflow) ເຊິ່ງການນໍາໃຊ້ PP ອະນຸຍາດໃຫ້.

ໃນຫຼາຍສິ່ງທີ່ຕໍ່ໄປນີ້ພວກເຮົາຈະສົມມຸດຄວາມຄຸ້ນເຄີຍຂອງຜູ້ອ່ານກັບແນວຄວາມຄິດຂອງ
ກະທູ້ແລະການຫມູນໃຊ້ດັດສະນີ implicit ແລະຈະແຈ້ງພາຍໃນ PDL. ຖ້າຫາກວ່າທ່ານຍັງບໍ່ທັນໄດ້
ໄດ້ຍິນແນວຄວາມຄິດເຫຼົ່ານີ້ຫຼືບໍ່ສະດວກສະບາຍຫຼາຍກັບພວກເຂົາມັນແມ່ນເວລາທີ່ຈະກວດສອບ
PDL::Indexing.

ດັ່ງທີ່ເຈົ້າອາດຈະຊື່ນຊົມຈາກຊື່ຂອງມັນ PDL::PP ແມ່ນ Pre-Processor, ie ມັນຂະຫຍາຍລະຫັດຜ່ານ
ການທົດແທນເພື່ອເຮັດໃຫ້ລະຫັດ C ທີ່ແທ້ຈິງ. ດ້ານວິຊາການ, ຜົນຜະລິດແມ່ນລະຫັດ XS (ເບິ່ງ perlxs) ແຕ່
ນັ້ນ​ແມ່ນ​ໃກ້​ຊິດ​ກັບ C.

ດັ່ງນັ້ນເຈົ້າໃຊ້ PP ແນວໃດ? ດີສໍາລັບສ່ວນໃຫຍ່ທ່ານພຽງແຕ່ຂຽນລະຫັດ C ທໍາມະດາຍົກເວັ້ນ
ການກໍ່ສ້າງພິເສດ PP ທີ່ມີຮູບແບບ:

$something(ອັນອື່ນ)

ຫລື:

PPfunction %{

%}

ການກໍ່ສ້າງ PP ທີ່ສໍາຄັນທີ່ສຸດແມ່ນຮູບແບບ "$array()". ພິຈາລະນາ PP ງ່າຍດາຍຫຼາຍ
ຟັງຊັນເພື່ອສະຫຼຸບອົງປະກອບຂອງ vector 1D (ໃນຄວາມເປັນຈິງນີ້ແມ່ນຄ້າຍຄືກັນກັບຕົວຈິງ
ລະຫັດທີ່ໃຊ້ໂດຍ 'sumover'):

pp_def('ລວມ',
Pars => 'a(n); [o]b();',
ລະຫັດ => q{
tmp ສອງເທົ່າ;
tmp = 0;
loop(n) %{
tmp += $a();
%}
$b() = tmp;
}
);

ເກີດ​ຫຍັງ​ຂື້ນ? ເສັ້ນ "Pars =>" ມີຄວາມສໍາຄັນຫຼາຍສໍາລັບ PP - ມັນກໍານົດທັງຫມົດ
ການໂຕ້ຖຽງແລະຂະຫນາດຂອງພວກເຂົາ. ພວກເຮົາເອີ້ນອັນນີ້ວ່າ ລາຍເຊັນ ຂອງຟັງຊັນ PP (ປຽບທຽບ
ຍັງຄໍາອະທິບາຍໃນ PDL::Indexing). ໃນ​ກໍ​ລະ​ນີ​ນີ້​ປະ​ຈໍາ​ການ​ໃຊ້​ເວ​ລາ​ການ​ທໍາ​ງານ 1-D ເປັນ​
input ແລະສົ່ງຄືນ 0-D scalar ເປັນຜົນຜະລິດ. ການກໍ່ສ້າງ "$a()" PP ຖືກນໍາໃຊ້ເພື່ອເຂົ້າເຖິງ
ອົງປະກອບຂອງອາເຣ a(n) ສໍາລັບທ່ານ - PP ຕື່ມຂໍ້ມູນໃສ່ໃນລະຫັດ C ທັງໝົດທີ່ຕ້ອງການ.

ທ່ານຈະສັງເກດເຫັນວ່າພວກເຮົາກໍາລັງໃຊ້ຕົວປະຕິບັດການ "q{}" ດຽວ. ນີ້ບໍ່ແມ່ນ
ອຸບັດເຫດ. ໂດຍທົ່ວໄປແລ້ວທ່ານຕ້ອງການໃຊ້ວົງຢືມດຽວເພື່ອຊີ້ໃຫ້ເຫັນພາກສ່ວນລະຫັດ PP ຂອງທ່ານ. PDL::PP
ໃຊ້ "$var()" ສໍາລັບການວິເຄາະຂອງມັນແລະຖ້າທ່ານບໍ່ໃຊ້ຄໍາເວົ້າດຽວ, Perl ຈະພະຍາຍາມ
interpolate "$var()". ນອກຈາກນັ້ນ, ການໃຊ້ຕົວປະຕິບັດການ "q" ດຽວທີ່ມີວົງເລັບ curly ເຮັດໃຫ້ມັນ
ເບິ່ງຄືວ່າທ່ານກໍາລັງສ້າງບລັອກລະຫັດ, ເຊິ່ງແມ່ນສິ່ງທີ່ທ່ານຫມາຍຄວາມວ່າ. (Perl ແມ່ນ smart ພຽງພໍທີ່ຈະ
ຊອກຫາເຊືອກຜູກ curly ຮັງແລະບໍ່ປິດວົງຢືມຈົນກ່ວາມັນຊອກຫາ curly ທີ່ກົງກັນ
ເຊືອກຜູກ, ສະນັ້ນມັນປອດໄພທີ່ຈະມີທ່ອນໄມ້ຮັງ.) ພາຍໃຕ້ສະຖານະການອື່ນໆ, ເຊັ່ນ: ໃນເວລາທີ່ທ່ານຢູ່.
ການ​ຕິດ​ຕົວ​ບລັອກ​ລະ​ຫັດ​ເຂົ້າ​ກັນ​ໂດຍ​ການ​ນໍາ​ໃຊ້​ການ​ເຊື່ອມ​ສະ​ຕ​ຣິ​ງ​, ມັນ​ມັກ​ຈະ​ງ່າຍ​ທີ່​ສຸດ​ທີ່​ຈະ​ນໍາ​ໃຊ້​
ວົງຢືມດຽວທີ່ແທ້ຈິງເປັນ

ລະຫັດ => 'ບາງສິ່ງບາງຢ່າງ'.$interpolatable.'somethingelse;'

ໃນກໍລະນີທີ່ງ່າຍດາຍທີ່ນີ້ບ່ອນທີ່ອົງປະກອບທັງຫມົດຖືກເຂົ້າເຖິງ PP construct "loop(n) %{ ...
%}" ຖືກນໍາໃຊ້ເພື່ອ loop over ອົງປະກອບທັງຫມົດໃນມິຕິ "n".
ມິຕິແມ່ນລະບຸໂດຍຊື່.

ນີ້ແມ່ນເຮັດໃຫ້ຊັດເຈນກວ່າຖ້າພວກເຮົາຫຼີກເວັ້ນ PP loop () ກໍ່ສ້າງແລະຂຽນ loop ຢ່າງຊັດເຈນ
ໃຊ້ C ທໍາມະດາ:

pp_def('ລວມ',
Pars => 'a(n); [o]b();',
ລະຫັດ => q{
int i,n_size;
tmp ສອງເທົ່າ;
n_size = $SIZE(n);
tmp = 0;
ສໍາລັບ(i=0; i
tmp += $a(n=>i);
}
$b() = tmp;
},
);

ຊຶ່ງ​ເຮັດ​ຄື​ກັນ​ກັບ​ເມື່ອ​ກ່ອນ, ​ແຕ່​ມີ​ລົມ​ແຮງ​ກວ່າ. ທ່ານສາມາດເບິ່ງເພື່ອໃຫ້ໄດ້ອົງປະກອບ "i" ຂອງ
a() ພວກເຮົາເວົ້າວ່າ "$a(n=>i)" - ພວກເຮົາກໍານົດຂະຫນາດໂດຍຊື່ "n". ໃນ 2D ພວກເຮົາອາດຈະເວົ້າວ່າ:

Pars=>'a(m,n);',
...
tmp += $a(m=>i,n=>j);
...

syntax "m=>i" ຢືມຈາກ Perl hashes, ເຊິ່ງໃນຕົວຈິງແມ່ນໃຊ້ໃນການຈັດຕັ້ງປະຕິບັດ.
ຂອງ PP. ຄົນເຮົາຍັງສາມາດເວົ້າວ່າ "$a(n=>j,m=>i)" ເນື່ອງຈາກຄໍາສັ່ງບໍ່ສໍາຄັນ.

ນອກນັ້ນທ່ານຍັງສາມາດເຫັນໃນຕົວຢ່າງຂ້າງເທິງນີ້ການນໍາໃຊ້ການກໍ່ສ້າງ PP ອື່ນ - $SIZE(n) ເພື່ອໃຫ້ໄດ້ຮັບ
ຄວາມຍາວຂອງຂະຫນາດ "n".

ຢ່າງໃດກໍຕາມ, ຄວນສັງເກດວ່າທ່ານບໍ່ຄວນຂຽນ C-loop ຢ່າງຊັດເຈນເມື່ອທ່ານສາມາດເຮັດໄດ້
ໄດ້ໃຊ້ PP "loop" ກໍ່ສ້າງນັບຕັ້ງແຕ່ PDL::PP ກວດສອບການກໍານົດຂອບເຂດຂອງ loop ໂດຍອັດຕະໂນມັດ
ທ່ານ, ການນໍາໃຊ້ "loop" ເຮັດໃຫ້ລະຫັດ concise ຫຼາຍ, ແລະອື່ນໆ. ແຕ່ແນ່ນອນວ່າມີສະຖານະການ
ບ່ອນ​ທີ່​ທ່ານ​ຕ້ອງ​ການ​ການ​ຄວບ​ຄຸມ​ຢ່າງ​ຊັດ​ເຈນ​ຂອງ loop ແລະ​ປັດ​ຈຸ​ບັນ​ທ່ານ​ຮູ້​ວິ​ທີ​ການ​ເຮັດ​ມັນ ;).

ເພື່ອທົບທວນຄືນ 'ເປັນຫຍັງ PP?' - ລະຫັດຂ້າງເທິງສໍາລັບ ປະຊຸມສຸດຍອດ() ຈະຖືກສ້າງຂື້ນສໍາລັບແຕ່ລະປະເພດຂໍ້ມູນ. ມັນ
ຈະດໍາເນີນການຢູ່ໃນສ່ວນຂອງ arrays 'in-place'. ມັນຈະ thread ອັດຕະໂນມັດ - e.g. ຖ້າຫາກວ່າເປັນ 2D
array ແມ່ນ​ໄດ້​ຮັບ​ໃຫ້​ມັນ​ຈະ​ໄດ້​ຮັບ​ການ​ເອີ້ນ​ຊ​້​ໍາ​ສໍາ​ລັບ​ແຕ່​ລະ​ແຖວ 1D (ອີກ​ເທື່ອ​ຫນຶ່ງ​ກວດ PDL::Indexing ສໍາ​ລັບ​ການ
ລາຍ​ລະ​ອຽດ​ຂອງ threading). ແລະຫຼັງຈາກນັ້ນ b() ຈະເປັນ array 1D ຂອງຜົນບວກຂອງແຕ່ລະແຖວ. ພວກ​ເຮົາ​ສາ​ມາດ
ໂທຫາມັນດ້ວຍ $a->xchg(0,1) ເພື່ອສະຫຼຸບຖັນແທນ. ແລະ Dataflow tracing ແລະອື່ນໆຈະເປັນ
ທີ່ມີຢູ່.

ທ່ານ​ສາ​ມາດ​ເບິ່ງ PP ຊ່ວຍ​ປະ​ຢັດ​ໂຄງ​ການ​ຈາກ​ການ​ຂຽນ​ຈໍາ​ນວນ​ຫຼາຍ​ຂອງ C-code ຊໍ້າ​ຊ້ອນ​ທີ່​ບໍ່​ຈໍາ​ເປັນ --
ໃນຄວາມຄິດເຫັນຂອງພວກເຮົານີ້ແມ່ນຫນຶ່ງໃນລັກສະນະທີ່ດີທີ່ສຸດຂອງ PDL ເຮັດໃຫ້ການຂຽນ C subroutines ໃຫມ່
ສໍາລັບ PDL ເປັນການອອກກໍາລັງກາຍທີ່ຊັດເຈນທີ່ຫນ້າປະຫລາດໃຈ. ເຫດຜົນທີສອງແມ່ນຄວາມສາມາດໃນການເຮັດໃຫ້ PP ຂະຫຍາຍ
ການກໍານົດລະຫັດຫຍໍ້ຂອງເຈົ້າເຂົ້າໄປໃນລະຫັດ C ທີ່ແຕກຕ່າງກັນໂດຍອີງໃສ່ຄວາມຕ້ອງການຂອງຄອມພິວເຕີ
ຖາປັດຕະຍະໃນຄໍາຖາມ. ຈິນຕະນາການຕົວຢ່າງວ່າທ່ານໂຊກດີທີ່ມີ supercomputer ຢູ່
ມືຂອງເຈົ້າ; ໃນກໍລະນີດັ່ງກ່າວທ່ານຕ້ອງການ PDL::PP ແນ່ນອນເພື່ອສ້າງລະຫັດທີ່ມີປະໂຫຍດ
ຄຸນ​ນະ​ສົມ​ບັດ vectorising/parallel ຄອມ​ພິວ​ເຕີ​ຂອງ​ເຄື່ອງ​ຂອງ​ທ່ານ (ນີ້​ແມ່ນ​ໂຄງ​ການ​ສໍາ​ລັບ​ການ​
ອະນາຄົດ). ໃນກໍລະນີໃດກໍ່ຕາມ, ເສັ້ນທາງລຸ່ມແມ່ນວ່າລະຫັດທີ່ບໍ່ປ່ຽນແປງຂອງທ່ານຄວນຈະຍັງຂະຫຍາຍອອກໄປ
ລະຫັດ XS ເຮັດວຽກເຖິງແມ່ນວ່າພາຍໃນຂອງ PDL ມີການປ່ຽນແປງ.

ນອກຈາກນັ້ນ, ເນື່ອງຈາກວ່າທ່ານກໍາລັງສ້າງລະຫັດໃນຕົວຫນັງສື Perl ຕົວຈິງ, ມີຄວາມມ່ວນຫຼາຍ
ສິ່ງ​ທີ່​ທ່ານ​ສາ​ມາດ​ເຮັດ​ໄດ້​. ໃຫ້ເວົ້າວ່າທ່ານຈໍາເປັນຕ້ອງຂຽນທັງສອງ sumit (ດັ່ງຂ້າງເທິງ) ແລະ multit.
ດ້ວຍຄວາມຄິດສ້າງສັນເລັກນ້ອຍ, ພວກເຮົາສາມາດເຮັດໄດ້

ສໍາລັບ({ຊື່ => 'sumit', Init => '0', Op => '+='},
{ຊື່ => 'ຫຼາຍ', Init => '1', Op => '*='}) {
pp_def($_->{ຊື່},
Pars => 'a(n); [o]b();',
ລະຫັດ => '
tmp ສອງເທົ່າ;
tmp = '.$_->{Init}.';
loop(n) %{
tmp '.$_->{Op}.' $a();
%}
$b() = tmp;
');
}

ເຊິ່ງກໍານົດຫນ້າທີ່ທັງສອງຢ່າງງ່າຍດາຍ. ໃນປັດຈຸບັນ, ຖ້າຫາກວ່າທ່ານຕໍ່ມາຈໍາເປັນຕ້ອງມີການປ່ຽນແປງລາຍເຊັນຫຼື
ຂະຫນາດຫຼືໃດກໍ່ຕາມ, ທ່ານພຽງແຕ່ຕ້ອງການປ່ຽນສະຖານທີ່ດຽວໃນລະຫັດຂອງທ່ານ. ແມ່ນແລ້ວ, ແນ່ນອນ,
ບັນນາທິການຂອງທ່ານມີ 'ຕັດແລະວາງ' ແລະ 'ຄົ້ນຫາແລະປ່ຽນແທນ' ແຕ່ມັນຍັງມີຫນ້ອຍ
bothersome ແລະແນ່ນອນມີຄວາມຫຍຸ້ງຍາກຫຼາຍທີ່ຈະລືມພຽງແຕ່ສະຖານທີ່ດຽວແລະມີແມງໄມ້ strange
creep in. ນອກຈາກນັ້ນ, ການເພີ່ມ 'orit' (bitwise ຫຼື) ຕໍ່ມາແມ່ນເສັ້ນດຽວ.

ແລະຈື່ໄວ້ວ່າ, ເຈົ້າມີຄວາມສາມາດອັນເຕັມທີ່ຂອງ Perl ກັບທ່ານແທ້ໆ - ເຈົ້າສາມາດອ່ານໄດ້ງ່າຍທີ່ສຸດ
ໄຟລ​໌​ໃດ​ຫນຶ່ງ​ເຂົ້າ​ແລະ​ເຮັດ​ໃຫ້​ກິດ​ຈະ​ກໍາ​ຈາກ​ຂໍ້​ມູນ​ໃນ​ໄຟລ​໌​ນັ້ນ​. ສໍາລັບກໍລະນີງ່າຍດາຍເຊັ່ນ
ຂ້າງເທິງ, ຜູ້ຂຽນ (Tjl) ປະຈຸບັນມັກ syntax hash ຄືຂ້າງເທິງ - ມັນບໍ່ແມ່ນເກີນໄປ.
ຕົວອັກສອນຫຼາຍກ່ວາ syntax array ທີ່ສອດຄ້ອງກັນແຕ່ເຂົ້າໃຈງ່າຍກວ່າແລະຫຼາຍ
ປ່ຽນແປງ.

ພວກເຮົາຄວນຈະກ່າວເຖິງໃນທີ່ນີ້ຍັງຄວາມສາມາດໃນການໄດ້ຮັບຕົວຊີ້ໄປຫາຈຸດເລີ່ມຕົ້ນຂອງຂໍ້ມູນໃນ
ຄວາມຊົງຈໍາ - ເງື່ອນໄຂເບື້ອງຕົ້ນສໍາລັບການຕິດຕໍ່ PDL ກັບບາງຫ້ອງສະຫມຸດ. ນີ້ແມ່ນຈັດການກັບ
"$P(var)" ຄໍາສັ່ງ, ເບິ່ງຂ້າງລຸ່ມນີ້.

ເມື່ອເລີ່ມຕົ້ນເຮັດວຽກກ່ຽວກັບຟັງຊັນ pp_def'ined ໃຫມ່, ຖ້າທ່ານເຮັດຜິດພາດ, ທ່ານມັກຈະ
ຊອກຫາຄວາມຜິດພາດ compiler ທີ່ຊີ້ບອກຕົວເລກແຖວໃນໄຟລ໌ XS ທີ່ສ້າງຂຶ້ນ. ຖ້າ​ເຈົ້າ
ຮູ້ວິທີການອ່ານໄຟລ໌ XS (ຫຼືຖ້າຫາກວ່າທ່ານຕ້ອງການທີ່ຈະຮຽນຮູ້ວິທີທີ່ຍາກ), ທ່ານສາມາດເປີດໄດ້
ສ້າງໄຟລ໌ XS ແລະຊອກຫາຕົວເລກແຖວດ້ວຍຄວາມຜິດພາດ. ຢ່າງໃດກໍຕາມ, ບໍ່ດົນມານີ້
ນອກ​ຈາກ PDL​::PP ຊ່ວຍ​ລາຍ​ງານ​ຈໍາ​ນວນ​ເສັ້ນ​ທີ່​ຖືກ​ຕ້ອງ​ຂອງ​ຄວາມ​ຜິດ​ພາດ​ຂອງ​ທ່ານ​:
"pp_line_numbers". ເຮັດວຽກກັບຕົວຢ່າງຂອງກອງປະຊຸມສຸດຍອດຕົ້ນສະບັບ, ຖ້າທ່ານມີການສະກົດຄໍາຜິດ
tmp ໃນລະຫັດຂອງທ່ານ, ທ່ານສາມາດປ່ຽນລະຫັດ (erroneos) ເປັນບາງສິ່ງບາງຢ່າງເຊັ່ນນີ້ແລະ
compiler ຈະໃຫ້ຂໍ້ມູນທີ່ເປັນປະໂຫຍດຫຼາຍແກ່ເຈົ້າ:

pp_def('ລວມ',
Pars => 'a(n); [o]b();',
ລະຫັດ => pp_line_numbers(__LINE__, q{
tmp ສອງເທົ່າ;
tmp = 0;
loop(n) %{
tmp += $a();
%}
$b() = rmp;
})
);

ສໍາລັບສະຖານະການຂ້າງເທິງນີ້, ຜູ້ລວບລວມຂໍ້ມູນຂອງຂ້ອຍບອກຂ້ອຍວ່າ:

...
test.pd:15: error: 'rmp' undeclared (ການ​ນໍາ​ໃຊ້​ທໍາ​ອິດ​ໃນ​ຫນ້າ​ທີ່​ນີ້​)
...

ໃນຕົວຢ່າງ script ຂອງຂ້ອຍ (ເອີ້ນວ່າ test.pd), ແຖວທີ 15 ແມ່ນກົງກັບເສັ້ນທີ່ຂ້ອຍເຮັດຂອງຂ້ອຍ
typo: "rmp" ແທນ "tmp".

ດັ່ງນັ້ນ, ຫຼັງຈາກພາບລວມໄວນີ້ຂອງລົດຊາດທົ່ວໄປຂອງການດໍາເນີນໂຄງການ PDL ປົກກະຕິການນໍາໃຊ້
PDL::PP ຂໍສະຫຼຸບໃນກໍລະນີທີ່ເຈົ້າຄວນໃຊ້ຕົວຈິງ
preprocessor/precompiler. ທ່ານຄວນໃຊ້ PDL::PP ຖ້າທ່ານຕ້ອງການ

·ການໂຕ້ຕອບ PDL ກັບບາງຫ້ອງສະຫມຸດພາຍນອກ

·ຂຽນ algorithm ບາງຢ່າງທີ່ຈະຊ້າຖ້າລະຫັດໃນ Perl (ນີ້ບໍ່ແມ່ນເລື້ອຍໆເທົ່າທີ່ທ່ານ
ຄິດ; ພິຈາລະນາເບິ່ງ threading ແລະ dataflow ທໍາອິດ).

·​ເປັນ​ຜູ້​ພັດ​ທະ​ນາ PDL (ແລະ​ເຖິງ​ແມ່ນ​ວ່າ​ຫຼັງ​ຈາກ​ນັ້ນ​ມັນ​ບໍ່​ຈໍາ​ເປັນ​)

ຄໍາເຕືອນ


ເນື່ອງຈາກວ່າສະຖາປັດຕະຍະກໍາຂອງມັນ, PDL::PP ສາມາດມີຄວາມຍືດຫຍຸ່ນແລະງ່າຍຕໍ່ການໃຊ້ໃນມືຫນຶ່ງ,
​ແຕ່​ມີ​ຄວາມ​ສັບສົນ​ຢ່າງ​ຟົດ​ຟື້ນ​ໃນ​ເວລາ​ດຽວ​ກັນ. ໃນປັດຈຸບັນ, ສ່ວນຫນຶ່ງຂອງບັນຫາແມ່ນຄວາມຜິດພາດນັ້ນ
ຂໍ້ຄວາມແມ່ນບໍ່ມີຂໍ້ມູນຫຼາຍແລະຖ້າມີບາງຢ່າງຜິດພາດ, ເຈົ້າຄວນຮູ້ວ່າເຈົ້າແມ່ນຫຍັງ
ກໍາລັງເຮັດແລະສາມາດ hack ວິທີການຂອງທ່ານໂດຍຜ່ານພາຍໃນ (ຫຼືສາມາດທີ່ຈະຄິດອອກໂດຍ
ການທົດລອງແລະຄວາມຜິດພາດສິ່ງທີ່ຜິດພາດກັບ args ຂອງທ່ານເປັນ "pp_def"). ເຖິງແມ່ນວ່າການເຮັດວຽກແມ່ນໄດ້ຖືກເຮັດ
ຜະລິດຄໍາເຕືອນທີ່ດີກວ່າ, ຢ່າຢ້ານທີ່ຈະສົ່ງຄໍາຖາມຂອງເຈົ້າໄປຫາລາຍຊື່ທາງໄປສະນີຖ້າ
ທ່ານແລ່ນເຂົ້າໄປໃນບັນຫາ.

ລາຍລະອຽດ


ຕອນນີ້ເຈົ້າມີຄວາມຄິດບາງຢ່າງທີ່ຈະໃຊ້ "pp_def" ເພື່ອກໍານົດຫນ້າທີ່ PDL ໃຫມ່ມັນເຖິງເວລາແລ້ວ
ອະທິບາຍ syntax ທົ່ວໄປຂອງ "pp_def". "pp_def" ໃຊ້ເວລາເປັນ arguments ທໍາອິດຊື່ຂອງ
ຟັງຊັນທີ່ທ່ານກໍາລັງກໍານົດແລະຫຼັງຈາກນັ້ນບັນຊີລາຍຊື່ hash ທີ່ສາມາດບັນຈຸປຸ່ມຕ່າງໆ.

ອີງຕາມກະແຈເຫຼົ່ານີ້ PP ສ້າງລະຫັດ XS ແລະໄຟລ໌ .pm. ຟັງຊັນ "pp_done" (ເບິ່ງ
ຕົວຢ່າງໃນ SYNOPSIS) ຖືກນໍາໃຊ້ເພື່ອບອກ PDL::PP ວ່າບໍ່ມີຄໍານິຍາມເພີ່ມເຕີມໃນ
ໄຟລ໌ນີ້ແລະມັນແມ່ນເວລາທີ່ຈະສ້າງ .xs ແລະ
ໄຟລ໌ .pm.

ດັ່ງນັ້ນ, ມັນອາດຈະມີຫຼາຍ pp_def() ໂທພາຍໃນໄຟລ໌ (ໂດຍໄຟລ໌ສົນທິສັນຍາ
ກັບລະຫັດ PP ມີນາມສະກຸນ .pd ຫຼື .pp) ແຕ່ໂດຍທົ່ວໄປແລ້ວມີພຽງອັນດຽວ pp_done().

ມີສອງປະເພດຕົ້ນຕໍທີ່ແຕກຕ່າງກັນຂອງການນໍາໃຊ້ pp_def(), 'ການດໍາເນີນງານຂໍ້ມູນ' ແລະ 'slice
ການດໍາເນີນງານ' prototypes.

'ການ​ດໍາ​ເນີນ​ງານ​ຂໍ້​ມູນ​' ໄດ້​ຖືກ​ນໍາ​ໃຊ້​ເພື່ອ​ເອົາ​ຂໍ້​ມູນ​ບາງ​ຢ່າງ​, mangle ມັນ​ແລະ​ອອກ​ຂໍ້​ມູນ​ອື່ນໆ​ຈໍາ​ນວນ​ຫນຶ່ງ​; ນີ້
ປະກອບມີຕົວຢ່າງການດໍາເນີນການ '+', matrix inverse, sumover ແລະອື່ນໆ ແລະຕົວຢ່າງທັງຫມົດ
ພວກເຮົາໄດ້ເວົ້າກ່ຽວກັບເອກະສານນີ້ມາເຖິງຕອນນັ້ນ. ກະທູ້ implicit ແລະ explicit ແລະ
ການສ້າງຜົນໄດ້ຮັບໄດ້ຖືກປະຕິບັດໂດຍອັດຕະໂນມັດໃນການດໍາເນີນງານເຫຼົ່ານັ້ນ. ເຈົ້າສາມາດແມ້ແຕ່
ເຮັດ dataflow ດ້ວຍ "sumit", "sumover", ແລະອື່ນໆ (ຢ່າຕົກໃຈຖ້າທ່ານບໍ່ເຂົ້າໃຈ.
ແນວຄວາມຄິດຂອງ dataflow ໃນ PDL ໄດ້ດີຫຼາຍ; ມັນຍັງມີການທົດລອງຫຼາຍ).

'ການ​ດໍາ​ເນີນ​ງານ​ການ​ຊອຍ​' ແມ່ນ​ປະ​ເພດ​ທີ່​ແຕກ​ຕ່າງ​ກັນ​ຂອງ​ການ​ດໍາ​ເນີນ​ງານ​: ໃນ​ການ​ດໍາ​ເນີນ​ງານ slice​, ທ່ານ​ບໍ່​ແມ່ນ​
ການປ່ຽນແປງຂໍ້ມູນໃດໆ, ທ່ານກໍາລັງກໍານົດການຕິດຕໍ່ລະຫວ່າງອົງປະກອບທີ່ແຕກຕ່າງກັນຂອງສອງ
piddles (ຕົວຢ່າງປະກອບມີການກໍານົດການຫມູນໃຊ້ດັດສະນີ / slicing function ຄໍານິຍາມໃນໄຟລ໌
slices.pd ນັ້ນແມ່ນສ່ວນຫນຶ່ງຂອງການແຈກຢາຍ PDL; ແຕ່ລະວັງ, ນີ້ບໍ່ແມ່ນລະດັບການແນະນໍາ
ສິ່ງຂອງ).

ຖ້າ PDL ຖືກລວບລວມໂດຍສະຫນັບສະຫນູນຄ່າທີ່ບໍ່ດີ (ເຊັ່ນ "WITH_BADVAL => 1"), ຫຼັງຈາກນັ້ນເພີ່ມເຕີມ
ລະຫັດແມ່ນຕ້ອງການສໍາລັບ "pp_def", ດັ່ງທີ່ອະທິບາຍຂ້າງລຸ່ມນີ້.

ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ພຽງ​ແຕ່​ມີ​ຄວາມ​ສົນ​ໃຈ​ໃນ​ການ​ຕິດ​ຕໍ່​ພົວ​ພັນ​ກັບ​ຫ້ອງ​ສະ​ຫມຸດ​ພາຍ​ນອກ​ບາງ (ຕົວ​ຢ່າງ​ບາງ​
linear algebra/matrix library), ເຈົ້າມັກຈະຕ້ອງການ 'ການດຳເນີນການຂໍ້ມູນ' ດັ່ງນັ້ນພວກເຮົາຈະໄປ.
ເພື່ອປຶກສາຫາລືຄັ້ງທໍາອິດ.

ຂໍ້ມູນ ປະຕິບັດງານ


A ງ່າຍດາຍ ຍົກຕົວຢ່າງ
ໃນການດໍາເນີນງານຂໍ້ມູນ, ທ່ານຕ້ອງຮູ້ວ່າຂະຫນາດຂອງຂໍ້ມູນທີ່ທ່ານຕ້ອງການ. ຫນ້າທໍາອິດ, ຕົວຢ່າງ
ດ້ວຍເກັດ:

pp_def('ຕື່ມ',
Pars => 'a(); b(); [o]c();',
ລະຫັດ => '$c() = $a() + $b();'
);

ມັນເບິ່ງຄືວ່າແປກເລັກນ້ອຍແຕ່ໃຫ້ກວດເບິ່ງມັນ. ເສັ້ນທໍາອິດແມ່ນງ່າຍ: ພວກເຮົາກໍາລັງກໍານົດ a
ປົກກະຕິທີ່ມີຊື່ 'ຕື່ມ'. ແຖວທີສອງພຽງແຕ່ປະກາດຕົວກໍານົດການຂອງພວກເຮົາແລະ
ວົງເລັບຫມາຍຄວາມວ່າພວກມັນເປັນເກັດ. ພວກເຮົາໂທຫາສາຍທີ່ກໍານົດພາລາມິເຕີຂອງພວກເຮົາແລະ
ຂະຫນາດຂອງເຂົາເຈົ້າ ລາຍເຊັນ ຂອງ​ຫນ້າ​ທີ່​ນັ້ນ​. ສໍາລັບຄວາມກ່ຽວຂ້ອງຂອງຕົນກ່ຽວກັບ
threading and index manipulations ກວດເບິ່ງ PDL::Indexing man page.

ສາຍທີສາມແມ່ນການປະຕິບັດຕົວຈິງ. ທ່ານຈໍາເປັນຕ້ອງໃຊ້ເຄື່ອງຫມາຍເງິນໂດລາແລະວົງເລັບ
ເພື່ອອ້າງອີງເຖິງຕົວກໍານົດການຂອງທ່ານ (ອັນນີ້ອາດຈະມີການປ່ຽນແປງໃນບາງຈຸດໃນອະນາຄົດ, ເມື່ອ a
syntax ທີ່ດີແມ່ນພົບເຫັນ).

ເສັ້ນເຫຼົ່ານີ້ແມ່ນທັງຫມົດທີ່ຈໍາເປັນເພື່ອກໍານົດຫນ້າທີ່ຕົວຈິງສໍາລັບ PDL (ດີ,
ຕົວຈິງແລ້ວມັນບໍ່ແມ່ນ; ນອກຈາກນັ້ນ, ທ່ານຈໍາເປັນຕ້ອງຂຽນ Makefile.PL (ເບິ່ງຂ້າງລຸ່ມນີ້) ແລະສ້າງ
module (ບາງສິ່ງບາງຢ່າງເຊັ່ນ: 'perl Makefile.PL; make'); ແຕ່​ໃຫ້​ເຮົາ​ລະ​ເລີຍ​ໃນ​ປັດ​ຈຸ​ບັນ).
ສະນັ້ນຕອນນີ້ເຈົ້າສາມາດເຮັດໄດ້

ໃຊ້ MyModule;
$a = pdl 2,3,4;
$b = pdl 5;

$c = ເພີ່ມ($a,$b);
# ຫລື
add($a,$b,($c=null)); # ຮູບແບບທາງເລືອກ, ເປັນປະໂຫຍດຖ້າ $c ໄດ້
# ຕັ້ງໄວ້ເປັນອັນໃຫຍ່, ບໍ່ມີປະໂຫຍດຢູ່ທີ່ນີ້.

ແລະມີ threading ເຮັດວຽກຢ່າງຖືກຕ້ອງ (ຜົນໄດ້ຮັບແມ່ນ $c == [7 8 9]).

ໄດ້ Pars ສ່ວນ: ໄດ້ ລາຍເຊັນ of a PP ຫນ້າທີ່
ເບິ່ງລະຫັດຕົວຢ່າງຂ້າງເທິງນີ້, ເຈົ້າອາດຈະຖາມວ່າ: "$c=null" ແມ່ນຫຍັງແປກ.
syntax ໃນການໂທທີສອງກັບຟັງຊັນ "ເພີ່ມ" ໃຫມ່ຂອງພວກເຮົາບໍ? ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ເບິ່ງ​ອື່ນ​ຢູ່​ໃນ​
ຄໍານິຍາມຂອງ "ຕື່ມ" ທ່ານຈະສັງເກດເຫັນວ່າການໂຕ້ຖຽງທີສາມ "c" ຖືກທຸງກັບ
qualifier "[o]" ທີ່ບອກ PDL::PP ວ່ານີ້ແມ່ນການໂຕ້ຖຽງຜົນຜະລິດ. ດັ່ງນັ້ນຂ້າງເທິງໂທຫາ
add ຫມາຍຄວາມວ່າ 'ສ້າງ $c ໃຫມ່ຈາກ scratch ມີຂະຫນາດທີ່ຖືກຕ້ອງ' - "null" ແມ່ນພິເສດ
token ສໍາລັບ 'piddle ຫວ່າງເປົ່າ' (ທ່ານອາດຈະຖາມວ່າເປັນຫຍັງພວກເຮົາບໍ່ໄດ້ໃຊ້ຄ່າ "undef" ເພື່ອທຸງນີ້.
ແທນທີ່ PDL ສະເພາະ "null"; ພວກເຮົາກໍາລັງຄິດກ່ຽວກັບມັນ ;).

[ນີ້​ຄວນ​ຈະ​ໄດ້​ຮັບ​ການ​ອະ​ທິ​ບາຍ​ໃນ​ບາງ​ພາກ​ສ່ວນ​ອື່ນໆ​ຂອງ​ຄູ່​ມື​ເຊັ່ນ​ດຽວ​ກັນ !!] ເຫດ​ຜົນ​ສໍາ​ລັບ​ການ​
ມີ syntax ນີ້ເປັນທາງເລືອກແມ່ນວ່າຖ້າທ່ານມີ piddles ໃຫຍ່ແທ້ໆ, ທ່ານສາມາດເຮັດໄດ້

$c = PDL->null;
ສໍາລັບ(ບາງວົງຍາວ) {
# munge a,b
add($a,$b,$c);
# munge c, ເອົາບາງສິ່ງບາງຢ່າງກັບຄືນໄປບ່ອນ a,b
}

ແລະຫຼີກເວັ້ນການຈັດສັນ ແລະແຈກຢາຍ $c ໃນແຕ່ລະຄັ້ງ. ມັນໄດ້ຖືກຈັດສັນຫນຶ່ງຄັ້ງໃນຄັ້ງທໍາອິດ
ເພີ່ມ () ແລະຫຼັງຈາກນັ້ນຄວາມຊົງຈໍາຈະຢູ່ຈົນກ່ວາ $c ຖືກທໍາລາຍ.

ຖ້າທ່ານພຽງແຕ່ເວົ້າ

$c = ເພີ່ມ($a,$b);

ລະຫັດທີ່ສ້າງຂຶ້ນໂດຍ PP ຈະຕື່ມໃສ່ໃນ "$c=null" ໂດຍອັດຕະໂນມັດ ແລະສົ່ງຜົນໄດ້ຮັບ. ຖ້າ
ທ່ານຕ້ອງການຮຽນຮູ້ເພີ່ມເຕີມກ່ຽວກັບເຫດຜົນວ່າເປັນຫຍັງ PDL::PP ສະຫນັບສະຫນູນຮູບແບບນີ້ບ່ອນທີ່ຜົນຜະລິດ
arguments ແມ່ນໃຫ້ເປັນ arguments ສຸດທ້າຍກວດເບິ່ງ PDL::Indexing man page.

"[o]" ບໍ່ແມ່ນເງື່ອນໄຂດຽວທີ່ argument pdl ສາມາດມີຢູ່ໃນລາຍເຊັນ. ອື່ນ
ເງື່ອນໄຂທີ່ສໍາຄັນແມ່ນທາງເລືອກ "[t]" ທີ່ທຸງ pdl ເປັນຊົ່ວຄາວ. ມັນເຮັດຫຍັງ
ຫມາຍຄວາມວ່າ? ທ່ານບອກ PDL::PP ວ່າ pdl ນີ້ໃຊ້ສໍາລັບຜົນໄດ້ຮັບຊົ່ວຄາວເທົ່ານັ້ນ
ການ​ຄິດ​ໄລ່​ແລະ​ທ່ານ​ບໍ່​ໄດ້​ສົນ​ໃຈ​ໃນ​ມູນ​ຄ່າ​ຂອງ​ຕົນ​ຫຼັງ​ຈາກ​ການ​ຄິດ​ໄລ່​ໄດ້​
ສໍາເລັດ. ແຕ່ເປັນຫຍັງ PDL::PP ຕ້ອງການຮູ້ກ່ຽວກັບເລື່ອງນີ້ໃນຕອນທໍາອິດ? ເຫດ​ຜົນ
ມີຄວາມກ່ຽວຂ້ອງຢ່າງໃກ້ຊິດກັບແນວຄວາມຄິດຂອງການສ້າງ pdl auto (ທ່ານໄດ້ຍິນກ່ຽວກັບວ່າຂ້າງເທິງ) ແລະ
ກະທູ້ implicit. ຖ້າທ່ານໃຊ້ກະທູ້ implicit ຂະຫນາດຂອງອັດຕະໂນມັດ
ຕົວຈິງແລ້ວ pdls ທີ່ສ້າງຂຶ້ນແມ່ນໃຫຍ່ກວ່າທີ່ລະບຸໄວ້ໃນລາຍເຊັນ. ດ້ວຍ "[o]" ທຸງ
pdls ຈະຖືກສ້າງຂື້ນເພື່ອໃຫ້ພວກເຂົາມີຂະຫນາດເພີ່ມເຕີມຕາມຄວາມຕ້ອງການຂອງຈໍານວນ
ຂອງຂະຫນາດກະທູ້ implicit. ເມື່ອສ້າງ pdl ຊົ່ວຄາວ, ຢ່າງໃດກໍຕາມ, ມັນຈະສະເຫມີເທົ່ານັ້ນ
ໄດ້ຮັບການເຮັດໃຫ້ໃຫຍ່ພໍເພື່ອໃຫ້ມັນສາມາດຖືຜົນໄດ້ຮັບສໍາລັບການ iteration ຫນຶ່ງໃນ loop thread, ie
ຂະຫນາດໃຫຍ່ຕາມຄວາມຕ້ອງການຂອງລາຍເຊັນ. ດັ່ງນັ້ນຄວາມຊົງຈໍາຫນ້ອຍຈະເສຍເວລາໃນເວລາທີ່ທ່ານຫມາຍ pdl ເປັນ
ຊົ່ວຄາວ. ອັນທີສອງ, ທ່ານສາມາດນໍາໃຊ້ຜົນຜະລິດອັດຕະໂນມັດທີ່ມີ pdls ຊົ່ວຄາວເຖິງແມ່ນວ່າໃນເວລາທີ່ທ່ານ
ກໍາລັງໃຊ້ threading explicit ທີ່ຖືກຫ້າມສໍາລັບ pdls ຜົນຜະລິດປົກກະຕິທີ່ຖືກທຸງດ້ວຍ "[o]"
(ເບິ່ງ PDL::Indexing).

ນີ້ແມ່ນຕົວຢ່າງທີ່ພວກເຮົາໃຊ້ [t] qualifier. ພວກເຮົາກໍານົດຫນ້າທີ່ "callf" ວ່າ
ເອີ້ນ C routine "f" ເຊິ່ງຕ້ອງການ array ຊົ່ວຄາວທີ່ມີຂະຫນາດແລະປະເພດດຽວກັນກັບ array.
"a" (ຂໍ​ອະ​ໄພ​ກ່ຽວ​ກັບ​ການ​ກະ​ສານ​ອ້າງ​ອີງ​ຕໍ່​ຫນ້າ $P; ມັນ​ເປັນ​ການ​ເຂົ້າ​ເຖິງ pointer​, ເບິ່ງ​ຂ້າງ​ລຸ່ມ​ນີ້​) :

pp_def('callf',
Pars => 'a(n); [t] tmp(n); [o] b()',
ລະຫັດ => 'int ns = $SIZE(n);
f($P(a),$P(b),$P(tmp),ns);
'
);

ການໂຕ້ຖຽງ ຂະຫນາດ ແລະ ໄດ້ ລາຍເຊັນ
ໃນປັດຈຸບັນພວກເຮົາໄດ້ເວົ້າກ່ຽວກັບຂະຫນາດຂອງ pdls ແລະລາຍເຊັນ. ເຂົາເຈົ້າກ່ຽວຂ້ອງກັນແນວໃດ?
ສົມມຸດວ່າພວກເຮົາຕ້ອງການເພີ່ມ scalar + ຕົວເລກດັດຊະນີໃສ່ vector:

pp_def('ຕື່ມ2',
Pars => 'a(n); b(); [o]c(n);',
ລະຫັດ => 'loop(n) %{
$c() = $a() + $b() + n;
%}'
);

ມີຫຼາຍຈຸດທີ່ຈະສັງເກດເຫັນຢູ່ທີ່ນີ້: ທໍາອິດ, ການໂຕ້ຖຽງ "Pars" ໃນປັດຈຸບັນປະກອບດ້ວຍ n
ການໂຕ້ຖຽງເພື່ອສະແດງໃຫ້ເຫັນວ່າພວກເຮົາມີຂະຫນາດດຽວໃນ a ແລະ c. ມັນເປັນສິ່ງສໍາຄັນທີ່ຈະສັງເກດ
ຂະຫນາດນັ້ນແມ່ນຫນ່ວຍງານຕົວຈິງທີ່ເຂົ້າເຖິງໂດຍຊື່ດັ່ງນັ້ນການປະກາດນີ້ a ແລະ c to
ມີ ດຽວກັນ ຂະ​ຫນາດ​ທໍາ​ອິດ​. ໃນຄໍານິຍາມ PP ສ່ວນໃຫຍ່ຂະຫນາດຂອງຂະຫນາດທີ່ມີຊື່ຈະ
ຖືກກໍານົດຈາກຂະຫນາດທີ່ກ່ຽວຂ້ອງຂອງ pdls ທີ່ບໍ່ແມ່ນຜົນຜະລິດ (ຜູ້ທີ່ບໍ່ມີທຸງ "[o]") ແຕ່.
ບາງຄັ້ງທ່ານອາດຈະຕ້ອງການກໍານົດຂະຫນາດຂອງຂະຫນາດທີ່ມີຊື່ຢ່າງຊັດເຈນໂດຍຜ່ານ an
ຕົວກໍານົດການຈໍານວນເຕັມ. ເບິ່ງຂ້າງລຸ່ມນີ້ໃນຄໍາອະທິບາຍຂອງພາກ "OtherPars" ວິທີການເຮັດວຽກ.

ຄົງ ການໂຕ້ຖຽງ ຂະຫນາດ in ໄດ້ ລາຍເຊັນ
ສົມມຸດວ່າທ່ານຕ້ອງການ piddle ຜົນຜະລິດທີ່ຈະຖືກສ້າງຂື້ນໂດຍອັດຕະໂນມັດແລະທ່ານຮູ້ວ່າໃນທຸກໆ
ໂທຫາຂະຫນາດຂອງມັນຈະມີຂະຫນາດດຽວກັນ (ເວົ້າວ່າ 9) ໂດຍບໍ່ຄໍານຶງເຖິງຂະຫນາດຂອງ
piddles ປ້ອນຂໍ້ມູນ. ໃນກໍລະນີນີ້ທ່ານໃຊ້ syntax ຕໍ່ໄປນີ້ໃນພາກ Pars ເພື່ອກໍານົດ
ຂະຫນາດຂອງຂະຫນາດ:

' [o] y(n=9); '

ຕາມທີ່ຄາດໄວ້, ຂະໜາດພິເສດທີ່ຕ້ອງການໂດຍການໃສ່ກະທູ້ຈະຖືກສ້າງຖ້າຈໍາເປັນ. ຖ້າ​ເຈົ້າ
ຈໍາ​ເປັນ​ຕ້ອງ​ກໍາ​ນົດ​ຂະ​ຫນາດ​ທີ່​ມີ​ຊື່​ຕາມ​ສູດ​ທີ່​ຊັບ​ຊ້ອນ​ຫຼາຍ (ກ​່​ວາ​ຄົງ​ທີ່​)
ທ່ານຕ້ອງໃຊ້ລະຫັດ "RedoDimsCode" ທີ່ອະທິບາຍຂ້າງລຸ່ມນີ້.

ປະເພດ ການປ່ຽນແປງ ແລະ ໄດ້ ລາຍເຊັນ
ລາຍເຊັນຍັງກໍານົດການແປງປະເພດທີ່ຈະດໍາເນີນການໃນເວລາທີ່ PP
ຟັງຊັນຖືກເອີ້ນ. ດັ່ງນັ້ນຈະເກີດຫຍັງຂຶ້ນເມື່ອພວກເຮົາຮຽກຮ້ອງອັນໜຶ່ງຂອງພວກເຮົາທີ່ໄດ້ກຳນົດໄວ້ກ່ອນໜ້ານີ້
ຟັງຊັນທີ່ມີ pdls ຂອງປະເພດທີ່ແຕກຕ່າງກັນ, eg

add2($a,$b,($ret=null));

ບ່ອນທີ່ $a ເປັນປະເພດ "PDL_Float" ແລະ $b ຂອງປະເພດ "PDL_Short"? ມີລາຍເຊັນດັ່ງທີ່ສະແດງຢູ່ໃນ
ຄໍານິຍາມຂອງ "add2" ຂ້າງເທິງປະເພດຂອງການດໍາເນີນການ (ຕາມທີ່ກໍານົດໃນເວລາແລ່ນ) ແມ່ນ
ຂອງ pdl ທີ່ມີປະເພດ 'ສູງສຸດ' (ລໍາດັບແມ່ນ byte < short < ushort < long < float
< ສອງເທົ່າ). ໃນຕົວຢ່າງ add2 ປະເພດຂອງການດໍາເນີນການແມ່ນ float ($a ມີນັ້ນ
ປະເພດຂໍ້ມູນ). argument pdl ທັງຫມົດແມ່ນຫຼັງຈາກນັ້ນປະເພດປ່ຽນເປັນ datatype (ພວກມັນບໍ່ແມ່ນ
converted inplace ແຕ່ສໍາເນົາທີ່ມີປະເພດທີ່ເຫມາະສົມແມ່ນຖືກສ້າງຂຶ້ນຖ້າ argument pdl ບໍ່ມີ
ປະ​ເພດ​ຂອງ​ການ​ດໍາ​ເນີນ​ງານ​)​. Null pdls ບໍ່ໄດ້ປະກອບສ່ວນປະເພດຂອງການກໍານົດ
ປະ​ເພດ​ຂອງ​ການ​ດໍາ​ເນີນ​ງານ​. ຢ່າງໃດກໍ່ຕາມ, ພວກເຂົາຈະຖືກສ້າງຂື້ນດ້ວຍປະເພດຂອງການດໍາເນີນການ;
ທີ່ນີ້, ສໍາລັບການຍົກຕົວຢ່າງ, $ret ຈະເປັນປະເພດ float. ທ່ານຄວນຮູ້ກົດລະບຽບເຫຼົ່ານີ້ໃນເວລາທີ່
ໂທຫາຫນ້າທີ່ PP ກັບ pdls ຂອງປະເພດທີ່ແຕກຕ່າງກັນເພື່ອເອົາການເກັບຮັກສາເພີ່ມເຕີມແລະ
ຄວາມຕ້ອງການ runtime ເຂົ້າໄປໃນບັນຊີ.

ການແປງປະເພດເຫຼົ່ານີ້ແມ່ນຖືກຕ້ອງສໍາລັບຫນ້າທີ່ສ່ວນໃຫຍ່ທີ່ທ່ານປົກກະຕິກໍານົດດ້ວຍ "pp_def".
ຢ່າງໃດກໍ່ຕາມ, ມີບາງກໍລະນີທີ່ມີພຶດຕິກໍາການປ່ຽນປະເພດທີ່ຖືກດັດແປງເລັກນ້ອຍ
ຕ້ອງການ. ສໍາ​ລັບ​ກໍ​ລະ​ນີ​ເຫຼົ່າ​ນີ້​ຄຸນ​ສົມ​ບັດ​ເພີ່ມ​ເຕີມ​ໃນ​ລາຍ​ເຊັນ​ສາ​ມາດ​ຖືກ​ນໍາ​ໃຊ້​ເພື່ອ​ລະ​ບຸ​
ຄຸນສົມບັດທີ່ຕ້ອງການກ່ຽວກັບການແປງປະເພດ. ຄຸນສົມບັດເຫຼົ່ານີ້ສາມາດຖືກລວມເຂົ້າກັບ
ທີ່​ພວກ​ເຮົາ​ໄດ້​ພົບ​ແລ້ວ (the ການສ້າງ ຮອບຄັດເລືອກ "[o]" ແລະ "[t]"). ໄປ​ກັນ​ເລີຍ
ໂດຍຜ່ານບັນຊີລາຍຊື່ຂອງຄຸນສົມບັດທີ່ມີການປ່ຽນແປງພຶດຕິກໍາການແປງປະເພດ.

ສິ່ງທີ່ສໍາຄັນທີ່ສຸດແມ່ນຄຸນສົມບັດ "int" ທີ່ມີປະໂຫຍດໃນເວລາທີ່ການໂຕ້ຖຽງ pdl
ເປັນຕົວແທນຂອງດັດຊະນີເຂົ້າໄປໃນ pdl ອື່ນ. ໃຫ້ເບິ່ງຕົວຢ່າງຈາກ "PDL::Ufunc":

pp_def('maximum_ind',
Pars => 'a(n); int [o] b()',
ລະຫັດ => '$GENERIC() cur;
int curind;
loop(n) %{
ຖ້າ (!n || $a() > cur) {cur = $a(); curind = n;}
%}
$b() = curind;',
);

ຟັງຊັນ "maximum_ind" ຊອກຫາດັດຊະນີຂອງອົງປະກອບທີ່ໃຫຍ່ທີ່ສຸດຂອງ vector. ຖ້າເຈົ້າເບິ່ງ
ຢູ່ໃນລາຍເຊັນທີ່ທ່ານສັງເກດເຫັນວ່າການໂຕ້ຖຽງຜົນຜະລິດ "b" ໄດ້ຖືກປະກາດດ້ວຍ
ເພີ່ມເຕີມ "int" qualifier. ນີ້ມີຜົນສະທ້ອນຕໍ່ໄປນີ້ສໍາລັບການແປງປະເພດ:
ໂດຍບໍ່ຄໍານຶງເຖິງປະເພດຂອງ input pdl "a" ຜົນຜະລິດ pdl "b" ຈະເປັນປະເພດ "PDL_Long"
ເຊິ່ງເຮັດໃຫ້ຄວາມຮູ້ສຶກນັບຕັ້ງແຕ່ "b" ຈະເປັນຕົວແທນຂອງດັດຊະນີເຂົ້າໄປໃນ "a". ນອກຈາກນັ້ນ, ຖ້າທ່ານໂທຫາ
ຟັງຊັນທີ່ມີຜົນຜະລິດທີ່ມີຢູ່ pdl "b" ປະເພດຂອງມັນຈະບໍ່ມີອິດທິພົນຕໍ່ປະເພດຂອງຂໍ້ມູນ
ການດໍາເນີນງານ (ເບິ່ງຂ້າງເທິງ). ດັ່ງນັ້ນ, ເຖິງແມ່ນວ່າ "a" ແມ່ນປະເພດຂະຫນາດນ້ອຍກວ່າ "b" ມັນຈະບໍ່ເປັນ
ແປງໃຫ້ກົງກັບປະເພດຂອງ "b" ແຕ່ບໍ່ຖືກແຕະຕ້ອງ, ເຊິ່ງຊ່ວຍປະຢັດຫນ່ວຍຄວາມຈໍາແລະວົງຈອນ CPU
ແລະເປັນສິ່ງທີ່ຖືກຕ້ອງທີ່ຈະເຮັດເມື່ອ "b" ເປັນຕົວແທນຂອງດັດຊະນີ. ຍັງສັງເກດວ່າທ່ານສາມາດນໍາໃຊ້ໄດ້
'int' qualifiers ຮ່ວມ​ກັບ​ຄຸນ​ສົມ​ບັດ​ອື່ນໆ (ໄດ້ "[o]" ແລະ "[t]" qualifiers). ຄໍາສັ່ງແມ່ນ
ທີ່​ສໍາ​ຄັນ -- type qualifiers precede creation qualifiers ("[o]" ແລະ "[t]").

ຕົວຢ່າງຂ້າງເທິງຍັງສະແດງໃຫ້ເຫັນເຖິງການນໍາໃຊ້ປົກກະຕິຂອງ "$GENERIC()" macro. ມັນຂະຫຍາຍ
ກັບປະເພດປະຈຸບັນໃນ loop ທົ່ວໄປທີ່ເອີ້ນວ່າ. ວົງວຽນທົ່ວໄປແມ່ນຫຍັງ? ດັ່ງທີ່ເຈົ້າແລ້ວ
ໄດ້ຍິນຟັງຊັນ PP ມີປະເພດຂໍ້ມູນເວລາແລ່ນຕາມທີ່ກໍານົດໂດຍປະເພດຂອງການໂຕ້ຖຽງ pdl
ມັນໄດ້ຖືກຮຽກຮ້ອງດ້ວຍ. PP ສ້າງລະຫັດ XS ສໍາລັບຟັງຊັນນີ້ປະກອບດ້ວຍ a
switch ເຊັ່ນ "switch (type) {case PDL_Byte: ... case PDL_Double: ... }" ທີ່ເລືອກກໍລະນີ
ອີງໃສ່ປະເພດຂໍ້ມູນເວລາແລ່ນຂອງຟັງຊັນ (ມັນເອີ້ນວ່າປະເພດ ``ວົງ´ ເພາະວ່າຢູ່ທີ່ນັ້ນ
ແມ່ນ loop ໃນລະຫັດ PP ທີ່ສ້າງກໍລະນີ). ໃນກໍລະນີໃດກໍ່ຕາມ, ລະຫັດຂອງທ່ານຖືກໃສ່ຫນຶ່ງຄັ້ງ
ສໍາລັບແຕ່ລະປະເພດ PDL ເຂົ້າໄປໃນຄໍາຖະແຫຼງການສະຫຼັບນີ້. ມະຫາພາກ "$GENERIC()" ພຽງແຕ່ຂະຫຍາຍໄປຫາ
ປະເພດທີ່ກ່ຽວຂ້ອງໃນແຕ່ລະສໍາເນົາຂອງລະຫັດ parsed ຂອງທ່ານໃນຄໍາສັ່ງ "ສະຫຼັບ" ນີ້, ຕົວຢ່າງ, ໃນ
"ກໍລະນີ PDL_Byte" ສ່ວນ "cur" ຈະຂະຫຍາຍໄປເປັນ "PDL_Byte" ແລະອື່ນໆສໍາລັບກໍລະນີອື່ນໆ.
ຖະແຫຼງການ. ຂ້ອຍເດົາເຈົ້າຮູ້ວ່ານີ້ແມ່ນມະຫາພາກທີ່ເປັນປະໂຫຍດທີ່ຈະຖືຄຸນຄ່າຂອງ pdls ໃນບາງອັນ
ລະຫັດ.

ມີຄູ່ຂອງຄຸນສົມບັດອື່ນໆທີ່ມີຜົນກະທົບທີ່ຄ້າຍຄືກັນເປັນ "int". ສໍາລັບຂອງທ່ານ
ຄວາມສະດວກສະບາຍມີຄຸນສົມບັດ "ເລື່ອນ" ແລະ "ຄູ່" ທີ່ມີຜົນສະທ້ອນທີ່ຄ້າຍຄືກັນ.
ພິມການແປງເປັນ "int". ໃຫ້ສົມມຸດວ່າທ່ານມີ a ຫຼາຍ array ຂະຫນາດໃຫຍ່ທີ່ທ່ານຕ້ອງການ
ຄິດໄລ່ຜົນລວມແຖວ ແລະຖັນທີ່ທຽບເທົ່າກັບຟັງຊັນ "sumover". ຢ່າງໃດກໍຕາມ, ກັບ
ຄໍານິຍາມປົກກະຕິຂອງ "sumover" ທ່ານອາດຈະມີບັນຫາໃນເວລາທີ່ຂໍ້ມູນຂອງທ່ານແມ່ນ, ເຊັ່ນ:
ພິມສັ້ນ. ໂທເຊັ່ນ

sumover($large_pdl,($sums = null));

ຈະສົ່ງຜົນໃຫ້ $sums ເປັນປະເພດສັ້ນ ແລະເພາະສະນັ້ນຈຶ່ງມັກຈະເກີດຄວາມຜິດພາດເກີນຖ້າ
$large_pdl ເປັນ array ໃຫຍ່ຫຼາຍ. ໃນອີກດ້ານຫນຶ່ງໂທຫາ

@dims = $large_pdl-> dims; shift @ dims;
sumover($large_pdl,($sums = zeroes(double,@dims)));

ບໍ່ແມ່ນທາງເລືອກທີ່ດີ. ຕອນນີ້ພວກເຮົາບໍ່ມີບັນຫາ overflow ກັບ $sums ແຕ່ຢູ່ທີ່
ຄ່າໃຊ້ຈ່າຍຂອງການແປງປະເພດຂອງ $large_pdl ເປັນສອງເທົ່າ, ບາງສິ່ງບາງຢ່າງທີ່ບໍ່ດີຖ້ານີ້ແມ່ນແທ້ໆ
pdl ຂະຫນາດໃຫຍ່. ນັ້ນແມ່ນບ່ອນທີ່ "ສອງ" ມີປະໂຫຍດ:

pp_def('sumoverd',
Pars => 'a(n); double [o] b()',
ລະຫັດ => 'double tmp=0;
loop(n) %{ tmp += a(); %}
$b() = tmp;',
);

ນີ້ເຮັດໃຫ້ພວກເຮົາປະມານການແປງປະເພດແລະບັນຫາ overflow. ອີກເທື່ອຫນຶ່ງ, ຄ້າຍຄືກັນກັບ
"int" qualifier "double" ສົ່ງຜົນໃຫ້ "b" ສະເຫມີເປັນປະເພດ double ບໍ່ວ່າຈະເປັນປະເພດໃດ
ຂອງ "a" ໂດຍບໍ່ມີການນໍາໄປສູ່ການແປງປະເພດຂອງ "a" ເປັນຜົນຂ້າງຄຽງ.

ສຸດທ້າຍ, ມີຄຸນສົມບັດ "type+" ທີ່ປະເພດແມ່ນຫນຶ່ງໃນ "int" ຫຼື "float". ແມ່ນ​ຫຍັງ
ນັ້ນຫມາຍຄວາມວ່າ. ໃຫ້ພວກເຮົາສະແດງຄຸນສົມບັດ "int+" ກັບຄໍານິຍາມທີ່ແທ້ຈິງຂອງ
ສຸດຍອດ:

pp_def('sumover',
Pars => 'a(n); int+ [o] b()',
ລະຫັດ => '$GENERIC(b) tmp=0;
loop(n) %{ tmp += a(); %}
$b() = tmp;',
);

ດັ່ງທີ່ພວກເຮົາໄດ້ເຫັນແລ້ວສໍາລັບ "int", "float" ແລະ "double" qualifiers, pdl ທີ່ຫມາຍດ້ວຍ
"type+" qualifier ບໍ່ມີອິດທິພົນຕໍ່ປະເພດຂອງການດໍາເນີນການ pdl. ຄວາມຫມາຍຂອງມັນແມ່ນ
"ເຮັດໃຫ້ pdl ນີ້ຢ່າງຫນ້ອຍປະເພດ "ປະເພດ" ຫຼືສູງກວ່າ, ຕາມຄວາມຕ້ອງການຂອງປະເພດຂອງ
ໃນຕົວຢ່າງ sumover ນີ້ຫມາຍຄວາມວ່າເມື່ອທ່ານເອີ້ນຟັງຊັນດ້ວຍ "a"
ປະເພດ PDL_Short ຜົນຜະລິດ pdl ຈະເປັນປະເພດ PDL_Long (ຄືກັນກັບທີ່ເຄີຍເປັນ.
ກໍລະນີທີ່ມີຄຸນສົມບັດ "int"). ນີ້ອີກເທື່ອຫນຶ່ງພະຍາຍາມທີ່ຈະຫຼີກເວັ້ນບັນຫາ overflow ໃນເວລາທີ່ການນໍາໃຊ້
ປະເພດຂໍ້ມູນຂະຫນາດນ້ອຍ (ເຊັ່ນ: ຮູບພາບ byte). ຢ່າງໃດກໍຕາມ, ໃນເວລາທີ່ປະເພດຂອງການດໍາເນີນການແມ່ນສູງຂຶ້ນ
ກ່ວາປະເພດທີ່ລະບຸໄວ້ໃນ "type+" ຄຸນວຸດທິ "b" ຈະຖືກສ້າງຂື້ນດ້ວຍປະເພດຂອງຂໍ້ມູນ
ການດໍາເນີນງານ, ເຊັ່ນ: ເມື່ອ "a" ເປັນປະເພດ double ຫຼັງຈາກນັ້ນ "b" ຈະເປັນສອງເທົ່າ. ພວກ​ເຮົາ​ຫວັງ​ວ່າ
ທ່ານຕົກລົງເຫັນດີວ່ານີ້ແມ່ນພຶດຕິກໍາທີ່ສົມເຫດສົມຜົນສໍາລັບ "sumover". ມັນຄວນຈະເປັນທີ່ຈະແຈ້ງວິທີການ
"float+" qualifier ເຮັດວຽກໂດຍການປຽບທຽບ. ມັນອາດຈະກາຍເປັນຄວາມຈໍາເປັນເພື່ອໃຫ້ສາມາດກໍານົດຊຸດ
ປະເພດທາງເລືອກສໍາລັບພາລາມິເຕີ. ຢ່າງໃດກໍຕາມ, ນີ້ອາດຈະບໍ່ໄດ້ຮັບການປະຕິບັດ
ຈົນ​ກວ່າ​ຜູ້​ໃດ​ຜູ້​ຫນຶ່ງ​ມາ​ມີ​ການ​ນໍາ​ໃຊ້​ທີ່​ສົມ​ເຫດ​ສົມ​ຜົນ​ສໍາ​ລັບ​ມັນ​.

ໃຫ້ສັງເກດວ່າຕອນນີ້ພວກເຮົາຕ້ອງລະບຸ Macro $GENERIC ດ້ວຍຊື່ຂອງ pdl ເພື່ອເອົາມາໃຫ້
ພິມຈາກການໂຕ້ຖຽງນັ້ນ. ເປັນຫຍັງຄື? ຖ້າເຈົ້າປະຕິບັດຕາມຄໍາອະທິບາຍຂອງພວກເຮົາຢ່າງລະມັດລະວັງເຈົ້າຈະ
ໄດ້ຮັບຮູ້ວ່າໃນບາງກໍລະນີ "b" ຈະມີປະເພດທີ່ແຕກຕ່າງກັນກ່ວາປະເພດຂອງ
ການດໍາເນີນງານ. ການໂທຫາມະຫາພາກ '$GENERIC' ດ້ວຍ "b" ເປັນການໂຕ້ຖຽງເຮັດໃຫ້ແນ່ໃຈວ່າປະເພດນັ້ນ
ຈະຄືກັນກັບຂອງ "b" ໃນສ່ວນຂອງ loop ທົ່ວໄປ.

ນີ້ແມ່ນກ່ຽວກັບສິ່ງທີ່ເວົ້າກ່ຽວກັບພາກສ່ວນ "Pars" ໃນການໂທ "pp_def". ເຈົ້າ​ຄວນ
ຈື່ໄວ້ວ່າພາກນີ້ກໍານົດ ລາຍເຊັນ ຂອງຫນ້າທີ່ກໍານົດ PP, ທ່ານສາມາດນໍາໃຊ້
ທາງ​ເລືອກ​ຫຼາຍ​ຢ່າງ​ທີ່​ຈະ​ມີ​ຄຸນ​ສົມ​ບັດ​ການ​ໂຕ້​ຖຽງ​ສະ​ເພາະ​ໃດ​ຫນຶ່ງ​ເປັນ​ຜົນ​ຜະ​ລິດ​ແລະ args ຊົ່ວ​ຄາວ​ແລະ​ທັງ​ຫມົດ​
ຂະໜາດທີ່ເຈົ້າສາມາດອ້າງອີງໃນພາຍຫຼັງໃນສ່ວນ "ລະຫັດ" ແມ່ນກຳນົດຕາມຊື່.

ມັນເປັນສິ່ງສໍາຄັນທີ່ທ່ານເຂົ້າໃຈຄວາມຫມາຍຂອງລາຍເຊັນນັບຕັ້ງແຕ່ໃນ PDL ຫຼ້າສຸດ
ຮຸ່ນທີ່ທ່ານສາມາດນໍາໃຊ້ມັນເພື່ອກໍານົດຫນ້າທີ່ threaded ຈາກພາຍໃນ Perl, ເຊັ່ນສິ່ງທີ່ພວກເຮົາໂທຫາ
Perl ລະດັບ ກະທູ້. ກະລຸນາກວດເບິ່ງ PDL::Indexing ສໍາລັບລາຍລະອຽດ.

ໄດ້ ລະຫັດ ສ່ວນ
ພາກສ່ວນ "ລະຫັດ" ປະກອບມີລະຫັດ XS ຕົວຈິງທີ່ຈະຢູ່ໃນສ່ວນໃນທີ່ສຸດຂອງ a
thread loop (ຖ້າທ່ານບໍ່ຮູ້ວ່າ thread loop ແມ່ນຫຍັງ, ຫຼັງຈາກນັ້ນທ່ານຍັງບໍ່ໄດ້ອ່ານ
PDL::Indexing; ເຮັດມັນດຽວນີ້ ;) ຫຼັງຈາກ PP macros (ເຊັ່ນ $ GENERIC) ແລະຟັງຊັນ PP ໄດ້
ຂະຫຍາຍ (ຄືກັບຟັງຊັນ "loop" ທີ່ພວກເຮົາຈະອະທິບາຍຕໍ່ໄປ).

ໃຫ້ເວົ້າຄືນຕົວຢ່າງ "sumover" ຢ່າງໄວວາ:

pp_def('sumover',
Pars => 'a(n); int+ [o] b()',
ລະຫັດ => '$GENERIC(b) tmp=0;
loop(n) %{ tmp += a(); %}
$b() = tmp;',
);

ການກໍ່ສ້າງ "loop" ໃນສ່ວນ "ລະຫັດ" ຍັງຫມາຍເຖິງຊື່ມິຕິດັ່ງນັ້ນທ່ານບໍ່ໄດ້
ຈໍາ​ເປັນ​ຕ້ອງ​ລະ​ບຸ​ຂໍ້​ຈໍາ​ກັດ​ໃດ​ຫນຶ່ງ​: loop ແມ່ນ​ຂະ​ຫນາດ​ທີ່​ຖືກ​ຕ້ອງ​ແລະ​ທຸກ​ສິ່ງ​ທຸກ​ຢ່າງ​ແມ່ນ​ສໍາ​ລັບ​ທ່ານ​,
ອີກເທື່ອຫນຶ່ງ.

ຕໍ່ໄປ, ມີຄວາມຈິງທີ່ຫນ້າປະຫລາດໃຈທີ່ "$a()" ແລະ "$b()" ເຮັດ ບໍ່ ມີດັດຊະນີ. ນີ້
ແມ່ນບໍ່ຈໍາເປັນເພາະວ່າພວກເຮົາກໍາລັງ looping n ແລະຕົວແປທັງສອງຮູ້ວ່າຂະຫນາດໃດ
ພວກເຂົາເຈົ້າມີດັ່ງນັ້ນເຂົາເຈົ້າອັດຕະໂນມັດຮູ້ວ່າພວກເຂົາເຈົ້າກໍາລັງຖືກ looped ໃນໄລຍະ.

ຄຸນສົມບັດນີ້ມາສະດວກຫຼາຍໃນຫຼາຍບ່ອນ ແລະເຮັດໃຫ້ລະຫັດສັ້ນກວ່າຫຼາຍ. ຂອງ
ແນ່ນອນ, ມີເວລາທີ່ທ່ານຕ້ອງການຫຼີກເວັ້ນ; ນີ້ແມ່ນຫນ້າທີ່ທີ່ເຮັດໃຫ້ a
matrix symmetric ແລະເຮັດຫນ້າທີ່ເປັນຕົວຢ່າງຂອງວິທີການລະຫັດ looping explicit:

pp_def('symm',
Pars => 'a(n,n); [o]c(n,n);',
ລະຫັດ => 'loop(n) %{
int n2;
ສໍາລັບ(n2=n; n2<$SIZE(n); n2++) {
$c(n0 => n, n1 => n2) =
$c(n0 => n2, n1 => n) =
$a(n0 => n, n1 => n2);
}
%}
'
);

ໃຫ້ dissect ສິ່ງທີ່ເກີດຂຶ້ນ. ກ່ອນອື່ນ ໝົດ, ຫນ້າທີ່ນີ້ຄວນຈະເຮັດຫຍັງ? ຈາກຂອງມັນ
ລາຍ​ເຊັນ​ທ່ານ​ເຫັນ​ວ່າ​ມັນ​ໃຊ້​ເວ​ລາ​ມາ​ຕຣິກ​ເບື້ອງ 2D ທີ່​ມີ​ຈໍາ​ນວນ​ເທົ່າ​ທຽມ​ກັນ​ຂອງ​ຖັນ​ແລະ​ແຖວ​ແລະ​
ຜົນໄດ້ຮັບ matrix ຂອງຂະຫນາດດຽວກັນ. ຈາກ​ເມ​ຕຣິກ​ການ​ປ້ອນ​ຂໍ້​ມູນ​ທີ່​ໃຫ້ $a ມັນ​ຄຳ​ນວນ​ສະ​ສົມ​ເມ​ຕຣິກ
output matrix $c (symmetric ໃນຄວາມໝາຍ matrix ວ່າ A^T = A ທີ່ ^T ຫມາຍຄວາມວ່າ matrix
transpose, ຫຼືໃນ PDL parlance $c == $c->xchg(0,1)). ມັນເຮັດສິ່ງນີ້ໂດຍໃຊ້ພຽງແຕ່ຄ່າ
ຢູ່ເທິງ ແລະລຸ່ມເສັ້ນຂວາງຂອງ $a. ໃນ matrix ຜົນ​ຜະ​ລິດ $c ຄ່າ​ທັງ​ຫມົດ​ຢູ່​ໃນ​ແລະ​ຂ້າງ​ລຸ່ມ​ນີ້​
ເສັ້ນຂວາງແມ່ນຄືກັນກັບທີ່ຢູ່ໃນ $a ໃນຂະນະທີ່ຢູ່ຂ້າງເທິງເສັ້ນຂວາງແມ່ນຮູບກະຈົກຂອງ
ທີ່ຢູ່ຂ້າງລຸ່ມຂອງເສັ້ນຂວາງ (ຂ້າງເທິງແລະຂ້າງລຸ່ມນີ້ແມ່ນໄດ້ຮັບການຕີຄວາມຫມາຍໃນແບບທີ່ PDL ພິມ
2D pdls). ຖ້າຄໍາອະທິບາຍນີ້ຍັງຟັງແປກເລັກນ້ອຍ, ພຽງແຕ່ສືບຕໍ່ເດີນຫນ້າ, ສ້າງໄຟລ໌ເລັກນ້ອຍ
ທີ່ທ່ານຂຽນຄໍານິຍາມນີ້, ສ້າງສ່ວນຂະຫຍາຍ PDL ໃຫມ່ (ເບິ່ງພາກ
Makefiles ສໍາລັບລະຫັດ PP) ແລະລອງມັນອອກດ້ວຍສອງສາມຕົວຢ່າງ.

ມີການອະທິບາຍສິ່ງທີ່ຫນ້າທີ່ຄວນຈະເຮັດມີສອງສາມຈຸດທີ່ມີມູນຄ່າ
ສັງເກດເຫັນຈາກຈຸດ syntactic ຂອງທັດສະນະ. ທໍາອິດ, ພວກເຮົາໄດ້ຮັບຂະຫນາດຂອງຂະຫນາດທີ່ມີຊື່
"n" ອີກຄັ້ງໂດຍໃຊ້ມະຫາພາກ $SIZE. ອັນທີສອງ, ທັນທີທັນໃດມີ "n0" ແລະ "n1" ຕະຫລົກເຫຼົ່ານີ້.
ຊື່ດັດສະນີໃນລະຫັດເຖິງແມ່ນວ່າລາຍເຊັນກໍານົດພຽງແຕ່ມິຕິ "n". ເປັນຫຍັງນີ້? ໄດ້
ເຫດຜົນຈະກາຍເປັນທີ່ຊັດເຈນເມື່ອທ່ານສັງເກດວ່າທັງສອງມິຕິທໍາອິດແລະທີສອງຂອງ $a ແລະ $b
ມີຊື່ "n" ໃນລາຍເຊັນຂອງ "symm". ນີ້ບອກ PDL::PP ວ່າຄັ້ງທໍາອິດແລະທີສອງ
ຂະຫນາດຂອງການໂຕ້ຖຽງເຫຼົ່ານີ້ຄວນຈະມີຂະຫນາດດຽວກັນ. ຖ້າບໍ່ດັ່ງນັ້ນຟັງຊັນທີ່ສ້າງຂຶ້ນ
ຈະ​ເພີ່ມ​ຄວາມ​ຜິດ​ພາດ runtime​. ຢ່າງໃດກໍຕາມ, ໃນປັດຈຸບັນຢູ່ໃນການເຂົ້າເຖິງ $a ແລະ $c PDL::PP ບໍ່ສາມາດຄິດໄລ່ໄດ້
ດັດຊະນີ "n" ຫມາຍເຖິງຫຍັງເພີ່ມເຕີມພຽງແຕ່ຈາກຊື່ຂອງດັດຊະນີ. ເພາະສະນັ້ນ, ໄດ້
ຕົວຊີ້ວັດທີ່ມີຊື່ມິຕິເທົ່າທຽມກັນໄດ້ຮັບຕົວເລກຈາກຊ້າຍຫາຂວາເລີ່ມຕົ້ນທີ່ 0, ຕົວຢ່າງ: ໃນ
ຕົວຢ່າງຂ້າງເທິງ "n0" ຫມາຍເຖິງຂະຫນາດທໍາອິດຂອງ $a ແລະ $c, "n1" ກັບທີສອງແລະ
ອື່ນໆ.

ໃນຕົວຢ່າງທັງຫມົດມາເຖິງຕອນນັ້ນ, ພວກເຮົາໃຊ້ພຽງແຕ່ "Pars" ແລະ "Code" ສະມາຊິກຂອງ hash ທີ່
ຖືກສົ່ງໄປຫາ "pp_def". ແນ່ນອນວ່າມີກະແຈອື່ນໆທີ່ຖືກຮັບຮູ້ໂດຍ PDL::PP ແລະ
ພວກເຮົາຈະໄດ້ຍິນກ່ຽວກັບບາງສ່ວນຂອງເຂົາເຈົ້າໃນໄລຍະຂອງເອກະສານນີ້. ຊອກຫາ (ບໍ່ໝົດ)
ບັນຊີລາຍຊື່ຂອງກະແຈໃນເອກະສານຊ້ອນທ້າຍ A. ບັນຊີລາຍຊື່ຂອງ macros ແລະ PPfunctions (ພວກເຮົາໄດ້ພົບພຽງແຕ່
ບາງສ່ວນຂອງຕົວຢ່າງຂ້າງເທິງນີ້) ທີ່ຖືກຂະຫຍາຍຢູ່ໃນມູນຄ່າຂອງການໂຕ້ຖຽງ hash
ກັບ "pp_def" ແມ່ນສະຫຼຸບໃນເອກະສານຊ້ອນທ້າຍ B.

ໃນຈຸດນີ້, ມັນອາດຈະເຫມາະສົມທີ່ຈະກ່າວເຖິງວ່າ PDL:: PP ບໍ່ແມ່ນສະຖິດຢ່າງສົມບູນ,
ຊຸດກິດຈະ ກຳ ທີ່ອອກແບບໄດ້ດີ (ດັ່ງທີ່ Tuomas ວາງໄວ້: "ຢຸດຄິດເຖິງ PP ເປັນຊຸດຂອງ
ປົກກະຕິແກະສະຫຼັກຢູ່ໃນຫີນ") ແຕ່ແທນທີ່ຈະເປັນການເກັບກໍາຂອງສິ່ງທີ່ PDL:: PP ຜູ້ຂຽນ
(Tuomas J. Lukka) ພິຈາລະນາວ່າລາວຈະຕ້ອງຂຽນເລື້ອຍໆເຂົ້າໃນການຂະຫຍາຍ PDL ຂອງລາວເລື້ອຍໆ.
PP ພະຍາຍາມທີ່ຈະຂະຫຍາຍໄດ້ເພື່ອວ່າໃນອະນາຄົດ, ເມື່ອຄວາມຕ້ອງການໃຫມ່ເກີດຂື້ນ, ລະຫັດທົ່ວໄປໃຫມ່ສາມາດ
ໄດ້ຮັບການ abstracted ກັບຄືນໄປບ່ອນເຂົ້າໄປໃນມັນ. ຖ້າທ່ານຕ້ອງການຮຽນຮູ້ເພີ່ມເຕີມກ່ຽວກັບວ່າເປັນຫຍັງທ່ານອາດຈະຕ້ອງການປ່ຽນແປງ
PDL::PP ແລະວິທີການເຮັດມັນກວດເບິ່ງພາກສ່ວນກ່ຽວກັບ PDL::PP ພາຍໃນ.

ການຈັດການ ບໍ່ດີ ຄ່າ
ຖ້າທ່ານບໍ່ມີການສະຫນັບສະຫນູນມູນຄ່າທີ່ບໍ່ດີທີ່ລວບລວມເຂົ້າໄປໃນ PDL ທ່ານສາມາດລະເລີຍພາກນີ້ແລະ
ກະແຈທີ່ກ່ຽວຂ້ອງ: "BadCode", "HandleBad", ... (ລອງພິມອອກຄ່າຂອງ
$PDL::Bad::ສະຖານະ - ຖ້າມັນເທົ່າກັບ 0 ແລ້ວຍ້າຍໄປຊື່).

ມີຫຼາຍກະແຈ ແລະ macros ທີ່ໃຊ້ໃນເວລາຂຽນລະຫັດເພື່ອຈັດການກັບຄ່າທີ່ບໍ່ດີ. ທໍາອິດ
ອັນນຶ່ງແມ່ນປຸ່ມ "HandleBad":

HandleBad => 0
ອັນນີ້ໝາຍເຖິງ pp-routine ເປັນ ບໍ່ ການຈັດການຄ່າທີ່ບໍ່ດີ. ຖ້າປົກກະຕິນີ້ຖືກສົ່ງ piddles
ດ້ວຍຊຸດ "badflag" ຂອງພວກເຂົາ, ຫຼັງຈາກນັ້ນຂໍ້ຄວາມເຕືອນຈະຖືກພິມອອກເປັນ STDOUT ແລະ piddles.
ຖືກປະມວນຜົນຄືກັບວ່າຄ່າທີ່ໃຊ້ເພື່ອສະແດງຄ່າທີ່ບໍ່ດີແມ່ນຕົວເລກທີ່ຖືກຕ້ອງ. ໄດ້
ຄ່າ "badflag" ບໍ່ໄດ້ຖືກຂະຫຍາຍໄປຫາ piddles ຜົນຜະລິດ.

ຕົວຢ່າງຂອງເວລາທີ່ນີ້ແມ່ນໃຊ້ສໍາລັບ FFT routines, ເຊິ່ງໂດຍທົ່ວໄປແລ້ວບໍ່ມີທາງ
ການບໍ່ສົນໃຈບາງສ່ວນຂອງຂໍ້ມູນ.

HandleBad => 1
ນີ້ເຮັດໃຫ້ PDL::PP ຂຽນລະຫັດພິເສດທີ່ຮັບປະກັນວ່າພາກ BadCode ຖືກໃຊ້, ແລະ
ວ່າມະຫາພາກ "$ISBAD()" (ແລະພີ່ນ້ອງຂອງມັນ) ເຮັດວຽກ.

HandleBad ບໍ່ໄດ້ຖືກມອບໃຫ້
ຖ້າ input piddles ໃດມີຊຸດ "badflag", ຫຼັງຈາກນັ້ນ, piddles ຜົນຜະລິດຈະ.
ມີຊຸດ "badflag" ຂອງພວກເຂົາ, ແຕ່ BadCode ໃດໆທີ່ສະຫນອງແມ່ນຖືກລະເລີຍ.

ຄ່າຂອງ "HandleBad" ແມ່ນໃຊ້ເພື່ອກໍານົດເນື້ອໃນຂອງປຸ່ມ "BadDoc", ຖ້າມັນບໍ່ແມ່ນ.
ໃຫ້.

ເພື່ອຈັດການກັບຄ່າທີ່ບໍ່ດີ, ລະຫັດຕ້ອງຖືກຂຽນແຕກຕ່າງກັນ; ຕົວ​ຢ່າງ,

$c() = $a() + $b();

ກາຍເປັນບາງສິ່ງບາງຢ່າງເຊັ່ນ:

ຖ້າ ($a() != BADVAL && $b() != BADVAL ) {
$c() = $a() + $b();
} else {
$c() = BADVAL;
}

ຢ່າງໃດກໍຕາມ, ພວກເຮົາພຽງແຕ່ຕ້ອງການສະບັບທີສອງຖ້າມີຄ່າທີ່ບໍ່ດີຢູ່ໃນ piddles ການປ້ອນຂໍ້ມູນ
(ແລະການສະຫນັບສະຫນູນທີ່ບໍ່ດີແມ່ນຕ້ອງການ!) - ຖ້າບໍ່ດັ່ງນັ້ນພວກເຮົາຕ້ອງການລະຫັດຕົ້ນສະບັບ.
ນີ້ແມ່ນບ່ອນທີ່ລະຫັດ "BadCode" ເຂົ້າມາ; ທ່ານໃຊ້ມັນເພື່ອລະບຸລະຫັດເພື່ອປະຕິບັດຖ້າຫາກວ່າບໍ່ດີ
ມູນຄ່າອາດຈະມີຢູ່, ແລະ PP ໃຊ້ທັງມັນແລະສ່ວນ "ລະຫັດ" ເພື່ອສ້າງບາງສິ່ງບາງຢ່າງ
ຄື:

ຖ້າ ( bad_values_are_present ) {
fancy_threadloop_stuff {
ລະຫັດບໍ່ດີ
}
} else {
fancy_threadloop_stuff {
ລະຫັດ
}
}

ວິທີການນີ້ຫມາຍຄວາມວ່າເກືອບບໍ່ມີສ່ວນເກີນໃນເວລາທີ່ຄຸນຄ່າທີ່ບໍ່ດີບໍ່ມີຢູ່
(ເຊັ່ນ: ປົກກະຕິ badflag ກັບຄືນມາ 0).

ພາກສ່ວນ BadCode ສາມາດໃຊ້ macro ດຽວກັນແລະການສ້າງ looping ເປັນພາກສ່ວນລະຫັດ.
ແນວໃດກໍ່ຕາມ, ມັນຈະບໍ່ມີປະໂຫຍດຫຼາຍຖ້າບໍ່ມີມະຫາພາກເພີ່ມເຕີມຕໍ່ໄປນີ້:

$ISBAD(var)
ເພື່ອກວດເບິ່ງວ່າຄ່າຂອງ piddle ບໍ່ດີ, ໃຊ້ Macro $ISBAD:

ຖ້າ ( $ISBAD(a()) ) { printf("a() ບໍ່ດີ\n"); }

ນອກນັ້ນທ່ານຍັງສາມາດເຂົ້າເຖິງອົງປະກອບຂອງ piddle ໄດ້:

ຖ້າ ( $ISBAD(a(n=>l))) ) { printf("ອົງປະກອບ %d ຂອງ a() ບໍ່ດີ\n", l); }

$ISGOOD(var)
ນີ້ແມ່ນກົງກັນຂ້າມກັບມະຫາພາກ $ISBAD.

$SETBAD(var)
ສໍາລັບເວລາທີ່ທ່ານຕ້ອງການທີ່ຈະກໍານົດອົງປະກອບຂອງ piddle ບໍ່ດີ.

$ISBADVAR(c_var,pdl)
ຖ້າທ່ານໄດ້ເກັບຄ່າຂອງ piddle "$a()" ເຂົ້າໄປໃນຕົວແປ c ("foo" ເວົ້າວ່າ), ຫຼັງຈາກນັ້ນ
ກວດເບິ່ງວ່າມັນບໍ່ດີຫຼືບໍ່, ໃຊ້ "$ISBADVAR(foo,a)".

$ISGOODVAR(c_var,pdl)
ດັ່ງຂ້າງເທິງ, ແຕ່ເວລານີ້ກວດເບິ່ງວ່າຄ່າ cache ແມ່ນບໍ່ບໍ່ດີ.

$SETBADVAR(c_var,pdl)
ເພື່ອຄັດລອກຄ່າທີ່ບໍ່ດີຂອງ piddle ເຂົ້າໄປໃນຕົວແປ ac, ໃຊ້ "$SETBADVAR(foo,a)".

ສິ່ງທີ່ຕ້ອງເຮັດ: ກ່າວເຖິງ "$PPISBAD()" ແລະອື່ນໆ macro.

ການນໍາໃຊ້ macro ເຫຼົ່ານີ້, ລະຫັດຂ້າງເທິງສາມາດຖືກກໍານົດເປັນ:

ລະຫັດ => '$c() = $a() + $b();',
ລະຫັດບໍ່ດີ => '
ຖ້າ ( $ISBAD(a()) || $ISBAD(b()) ) {
$SETBAD(c());
} else {
$c() = $a() + $b();
}',

ເນື່ອງຈາກວ່ານີ້ແມ່ນ Perl, TMTOWTDI, ດັ່ງນັ້ນທ່ານຍັງສາມາດຂຽນ:

ລະຫັດບໍ່ດີ => '
ຖ້າ ( $ISGOOD(a()) && $ISGOOD(b()) ) {
$c() = $a() + $b();
} else {
$SETBAD(c());
}',

ຖ້າທ່ານຕ້ອງການເຂົ້າເຖິງມູນຄ່າຂອງ badflag ສໍາລັບ piddle ທີ່ໃຫ້, ທ່ານສາມາດນໍາໃຊ້
"$PDLSTATExxxx()" ມາໂຄຣ:

$PDLSTATEISBAD(pdl)
$PDLSTATEISGOOD(pdl)
$PDLSTATESETBAD(pdl)
$PDLSTATESETGOOD(pdl)

ສິ່ງທີ່ຕ້ອງເຮັດ: ກ່າວເຖິງຕົວເລືອກ "FindBadStatusCode" ແລະ "CopyBadStatusCode" ກັບ "pp_def", ເຊັ່ນກັນ.
ເປັນປຸ່ມ "BadDoc".

ການແຊກແຊງ ຂອງ​ທ່ານ ຂອງຕົນເອງ / ຫ້ອງສະຫມຸດ ຫນ້າທີ່ ການນໍາໃຊ້ PP
ໃນປັດຈຸບັນ, ພິຈາລະນາດັ່ງຕໍ່ໄປນີ້: ທ່ານມີຫນ້າທີ່ C ຂອງທ່ານເອງ (ໃນຄວາມເປັນຈິງອາດຈະເປັນສ່ວນຫນຶ່ງຂອງ
ບາງຫ້ອງສະຫມຸດທີ່ທ່ານຕ້ອງການໂຕ້ຕອບກັບ PDL) ເຊິ່ງໃຊ້ເວລາເປັນການໂຕ້ຖຽງສອງຕົວຊີ້ໄປຫາ
vectors ຂອງ double:

void myfunc(int n,double *v1,double *v2);

ວິທີທີ່ຖືກຕ້ອງຂອງການກໍານົດຫນ້າທີ່ PDL ແມ່ນ

pp_def('myfunc',
Pars => 'a(n); [o]b(n);',
ປະເພດທົ່ວໄປ => ['D'],
ລະຫັດ => 'myfunc($SIZE(n),$P(a),$P(b));'
);

"$P("ໂດຍ")" syntax ສົ່ງຄືນຕົວຊີ້ໄປຫາອົງປະກອບທໍາອິດແລະອົງປະກອບອື່ນໆແມ່ນ
ຮັບປະກັນການຕົວະຫຼັງຈາກນັ້ນ.

ສັງເກດເຫັນວ່າໃນທີ່ນີ້ມັນເປັນໄປໄດ້ທີ່ຈະເຮັດຜິດພາດຫຼາຍ. ທຳອິດ, ຈະຕ້ອງໃຊ້ $SIZE(n)
ແທນ "n". ອັນທີສອງ, ທ່ານບໍ່ຄວນໃສ່ loops ໃນລະຫັດນີ້. ອັນທີສາມ, ຢູ່ທີ່ນີ້ພວກເຮົາພົບ
ລະຫັດ hash ໃໝ່ທີ່ຮັບຮູ້ໂດຍ PDL::PP : ການປະກາດ "GenericTypes" ບອກ PDL::PP ກັບ
ພຽງແຕ່ສ້າງ TYPELOOP ສະເພາະລາຍການປະເພດທີ່ລະບຸ. ໃນກໍລະນີນີ້ "ສອງ". ນີ້
ມີສອງຂໍ້ໄດ້ປຽບ. ກ່ອນອື່ນ ໝົດ, ຂະຫນາດຂອງລະຫັດທີ່ລວບລວມໄດ້ຖືກຫຼຸດລົງຢ່າງຫຼວງຫຼາຍ, ອັນທີສອງ, ຖ້າ
arguments ທີ່ບໍ່ແມ່ນສອງເທົ່າຈະຖືກສົ່ງກັບ "myfunc()" PDL ຈະປ່ຽນພວກມັນເປັນອັດຕະໂນມັດ
double ກ່ອນທີ່ຈະຜ່ານໄປປົກກະຕິ C ພາຍນອກແລະປ່ຽນໃຫ້ເຂົາເຈົ້າກັບຄືນໄປບ່ອນຫຼັງຈາກນັ້ນ.

ຫນຶ່ງຍັງສາມາດໃຊ້ "Pars" ເພື່ອກໍານົດປະເພດຂອງການໂຕ້ຖຽງສ່ວນບຸກຄົນ. ດັ່ງນັ້ນ, ຫນຶ່ງຍັງສາມາດ
ຂຽນນີ້ເປັນ:

pp_def('myfunc',
Pars => 'double a(n); double [o]b(n);',
ລະຫັດ => 'myfunc($SIZE(n),$P(a),$P(b));'
);

ປະເພດສະເພາະໃນ "Pars" ຍົກເວັ້ນການໂຕ້ຖຽງຈາກການປ່ຽນແປງໃນ typeloop -
ແທນທີ່ຈະມັນຖືກປ່ຽນອັດຕະໂນມັດເກີນໄປແລະຈາກປະເພດທີ່ລະບຸໄວ້. ນີ້ແມ່ນແນ່ນອນ
ເປັນປະໂຫຍດໃນຕົວຢ່າງທົ່ວໄປກວ່າ, ຕົວຢ່າງ:

void myfunc(int n,float *v1,long *v2);

pp_def('myfunc',
Pars => 'ລອຍ a(n); ຍາວ [o]b(n);',
ປະເພດທົ່ວໄປ => ['F'],
ລະຫັດ => 'myfunc($SIZE(n),$P(a),$P(b));'
);

ໃຫ້ສັງເກດວ່າພວກເຮົາຍັງໃຊ້ "GenericTypes" ເພື່ອຫຼຸດຜ່ອນຂະຫນາດຂອງ loop ປະເພດ, ແນ່ນອນ PP ສາມາດ
ໃນຫຼັກການຈຸດນີ້ແລະເຮັດມັນອັດຕະໂນມັດເຖິງແມ່ນວ່າລະຫັດຍັງບໍ່ທັນບັນລຸໄດ້
ລະດັບຄວາມຊັບຊ້ອນ!

ສຸດ​ທ້າຍ​ຄວນ​ສັງ​ເກດ​ເມື່ອ​ປະ​ເພດ​ທີ່​ຖືກ​ແປງ​ອັດ​ຕະ​ໂນ​ມັດ​ຫນຶ່ງ​ຈະ​ຕ້ອງ​ໄດ້​ໃຊ້​ຄຸນ​ນະ​ສົມ​ບັດ "[o]​" ສໍາ​ລັບ​ການ​
ຕົວແປຜົນຜະລິດຫຼືທ່ານຍາກຫນຶ່ງການປ່ຽນແປງຈະໄດ້ຮັບການ optimized ທັນທີໂດຍ PP!

ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ໂຕ້​ຕອບ​ຫ້ອງ​ສະ​ຫມຸດ​ຂະ​ຫນາດ​ໃຫຍ່​ທີ່​ທ່ານ​ສາ​ມາດ​ອັດ​ຕະ​ໂນ​ມັດ interfacing ເຖິງ​ແມ່ນ​ວ່າ​. Perl ສາມາດ
ຊ່ວຍທ່ານອີກເທື່ອຫນຶ່ງ (!) ໃນການເຮັດສິ່ງນີ້. ໃນຫ້ອງສະຫມຸດຈໍານວນຫຼາຍທ່ານມີສົນທິສັນຍາການໂທຫາທີ່ແນ່ນອນ.
ນີ້ສາມາດຖືກຂູດຮີດ. ໃນສັ້ນ, ທ່ານສາມາດຂຽນຕົວແຍກເລັກນ້ອຍ (ເຊິ່ງບໍ່ແມ່ນແທ້ໆ
ຍາກໃນ Perl) ຈາກນັ້ນສ້າງການໂທຫາ "pp_def" ຈາກຄໍາອະທິບາຍທີ່ແຍກອອກ
ຫນ້າທີ່ຢູ່ໃນຫ້ອງສະຫມຸດນັ້ນ. ສໍາລັບຕົວຢ່າງ, ກະລຸນາກວດເບິ່ງ Slatec ການໂຕ້ຕອບໃນ
ຕົ້ນໄມ້ "Lib" ຂອງການແຈກຢາຍ PDL. ຖ້າທ່ານຕ້ອງການກວດສອບ (ໃນລະຫວ່າງການ debugging) ທີ່ໂທຫາ
PP ປະຕິບັດຫນ້າທີ່ລະຫັດ Perl ຂອງທ່ານທີ່ສ້າງຊຸດຜູ້ຊ່ວຍພຽງເລັກນ້ອຍມາໃນທີ່ເປັນປະໂຫຍດ
ແທນທີ່ຟັງຊັນ PP ໂດຍຕົວຕົນທີ່ມີຊື່ທີ່ dump ການໂຕ້ຖຽງຂອງພວກເຂົາໄປ stdout.

ພຽງ​ແຕ່​ເວົ້າ​ວ່າ

perl -MPDL::PP::Dump myfile.pd

ເພື່ອເບິ່ງການໂທຫາ "pp_def" ແລະຫມູ່ເພື່ອນ. ລອງມັນກັບ ops.pd ແລະ slatec.pd. ຖ້າເຈົ້າ
ສົນໃຈ (ຫຼືຕ້ອງການເສີມຂະຫຍາຍມັນ), ແຫຼ່ງແມ່ນຢູ່ໃນ Basic/Gen/PP/Dump.pm

ອື່ນ ໆ ມະຫາພາກ ແລະ ຫນ້າທີ່ in ໄດ້ ລະຫັດ ສ່ວນ
Macros: ມາຮອດປັດຈຸບັນພວກເຮົາໄດ້ພົບກັບມາໂຄ $SIZE, $GENERIC ແລະ $P. ໃນປັດຈຸບັນພວກເຮົາກໍາລັງໄປ
ຢ່າງວ່ອງໄວອະທິບາຍມະຫາພາກອື່ນໆທີ່ຂະຫຍາຍຢູ່ໃນສ່ວນ "ລະຫັດ" ຂອງ PDL::PP ພ້ອມ
ກັບຕົວຢ່າງຂອງການນໍາໃຊ້ຂອງເຂົາເຈົ້າ.

$T macro $T ຖືກໃຊ້ສໍາລັບການປ່ຽນປະເພດ. ນີ້ແມ່ນເປັນປະໂຫຍດຫຼາຍໃນເວລາທີ່ທ່ານຕ້ອງໃຊ້
ຟັງຊັນພາຍນອກທີ່ແຕກຕ່າງກັນ (ເຊັ່ນ: ຫ້ອງສະໝຸດ) ຂຶ້ນກັບປະເພດການປ້ອນຂໍ້ມູນຂອງການໂຕ້ຖຽງ.
syntax ທົ່ວໄປແມ່ນ

$Ttypeletters(type_alternatives)

ບ່ອນທີ່ "ຕົວພິມນ້ອຍ" ແມ່ນການປ່ຽນສ່ວນຍ່ອຍຂອງຕົວອັກສອນ "BSULFD" ເຊິ່ງຢືນຢູ່.
ສໍາລັບ Byte, Short, Ushort, ແລະອື່ນໆ ແລະ "type_alternatives" ແມ່ນການຂະຫຍາຍເມື່ອປະເພດ
ການປະຕິບັດ PP ແມ່ນເທົ່າກັບທີ່ລະບຸໄວ້ໃນຈົດຫມາຍທີ່ກ່ຽວຂ້ອງ. ໃຫ້
ສະແດງໃຫ້ເຫັນຄໍາອະທິບາຍທີ່ບໍ່ສາມາດເຂົ້າໃຈໄດ້ໂດຍຕົວຢ່າງ. ສົມມຸດວ່າທ່ານມີສອງ C
ປະຕິບັດຫນ້າທີ່ມີ prototypes

void float_func(float *in, float *out);
void double_func(double *in, double *out);

ເຊິ່ງໂດຍພື້ນຖານແລ້ວເຮັດສິ່ງດຽວກັນແຕ່ຜູ້ຫນຶ່ງຍອມຮັບການລອຍຕົວແລະຕົວຊີ້ສອງເທົ່າອື່ນໆ.
ທ່ານ​ສາ​ມາດ​ໂຕ້​ຕອບ​ເຂົາ​ເຈົ້າ​ກັບ PDL ໂດຍ​ການ​ກໍາ​ນົດ​ຫນ້າ​ທີ່​ທົ່ວ​ໄປ "foofunc​" (ຊຶ່ງ​ຈະ​
ເອີ້ນຟັງຊັນທີ່ຖືກຕ້ອງຂຶ້ນກັບປະເພດຂອງການຫັນເປັນ):

pp_def('foofunc',
Pars => 'a(n); [o] b();',
ລະຫັດ => ' $TFD(float_func,double_func) ($P(a),$P(b));'
ປະເພດທົ່ວໄປ => [qw(FD)],
);

ກະລຸນາສັງເກດວ່າທ່ານບໍ່ສາມາດເວົ້າໄດ້

ລະຫັດ => ' $TFD(float,double)_func ($P(a),$P(b));'

ນັບຕັ້ງແຕ່ມະຫາພາກ $T ຂະຫຍາຍອອກດ້ວຍຊ່ອງຕໍ່ທ້າຍ, ປຽບທຽບກັບ C preprocessor macro.
ຮູບແບບທີ່ຍາວກວ່າເລັກນ້ອຍທີ່ສະແດງຢູ່ຂ້າງເທິງແມ່ນຖືກຕ້ອງ. ຖ້າທ່ານຕ້ອງການຄວາມສັ້ນແທ້ໆ, ເຈົ້າ
ແນ່ນອນສາມາດເຮັດໄດ້

'$TBSULFD('.(ເຂົ້າຮ່ວມ ',',ແຜນທີ່ {"long_identifier_name_$_"}
qw/byt ສັ້ນ unseigned lounge flotte dubble/).');'

$PP
ມະຫາພາກ $PP ຖືກໃຊ້ສໍາລັບອັນທີ່ເອີ້ນວ່າ ທາງດ້ານຮ່າງກາຍ ຕົວຊີ້ ການເຂົ້າເຖິງ. ໄດ້ ທາງດ້ານຮ່າງກາຍ ຫມາຍເຖິງ
ບາງການເພີ່ມປະສິດທິພາບພາຍໃນຂອງ PDL (ສໍາລັບຜູ້ທີ່ຄຸ້ນເຄີຍກັບ PDL ຫຼັກທີ່ພວກເຮົາເປັນ
ເວົ້າກ່ຽວກັບການເພີ່ມປະສິດທິພາບ vaffine). ມະຫາພາກນີ້ແມ່ນສໍາລັບການນໍາໃຊ້ພາຍໃນແລະທ່ານ
ບໍ່ຄວນໃຊ້ມັນຢູ່ໃນລະຫັດປົກກະຕິໃດໆຂອງເຈົ້າ.

$COMP (ແລະພາກສ່ວນ "OtherPars")
Macro $COMP ຖືກໃຊ້ເພື່ອເຂົ້າເຖິງຄ່າທີ່ບໍ່ແມ່ນ pdl ໃນສ່ວນລະຫັດ. ຊື່ຂອງມັນແມ່ນ
ມາຈາກການປະຕິບັດການຫັນປ່ຽນໃນ PDL. ຕົວແປທີ່ທ່ານສາມາດອ້າງອີງ
ການນໍາໃຊ້ $COMP ແມ່ນສະມາຊິກຂອງໂຄງສ້າງ ``ລວບລວມ´ ທີ່ເປັນຕົວແທນຂອງ PDL
ການຫັນປ່ຽນຢູ່ໃນຄໍາຖາມແຕ່ຍັງບໍ່ທັນມີຂໍ້ມູນກ່ຽວກັບຂະຫນາດໃດໆ
(ສໍາລັບລາຍລະອຽດເພີ່ມເຕີມກວດເບິ່ງ PDL::Internals). ຢ່າງໃດກໍຕາມ, ທ່ານສາມາດປະຕິບັດກັບ $COMP ຄືກັນກັບ
ກ່ອງດໍາໂດຍບໍ່ຮູ້ຫຍັງກ່ຽວກັບການປະຕິບັດການຫັນປ່ຽນໃນ PDL.
ດັ່ງນັ້ນເວລາໃດທີ່ເຈົ້າຈະໃຊ້ມະຫາພາກນີ້? ການ​ນໍາ​ໃຊ້​ຕົ້ນ​ຕໍ​ຂອງ​ມັນ​ແມ່ນ​ການ​ເຂົ້າ​ເຖິງ​ຄຸນ​ຄ່າ​ຂອງ​ການ​ໂຕ້​ຖຽງ​ວ່າ​
ຖືກປະກາດໄວ້ໃນພາກ "OtherPars" ຂອງຄໍານິຍາມ "pp_def". ແຕ່ຫຼັງຈາກນັ້ນທ່ານບໍ່ໄດ້
ໄດ້ຍິນກ່ຽວກັບກະແຈ "OtherPars" ແລ້ວບໍ?! ຂໍ​ໃຫ້​ມີ​ຕົວຢ່າງ​ອີກ​ອັນ​ໜຶ່ງ​ທີ່​ເປັນ​ຕົວຢ່າງ
ການນໍາໃຊ້ປົກກະຕິຂອງທັງສອງລັກສະນະໃຫມ່:

pp_def('pnmout',
Pars => 'a(ມ)',
OtherPars => "char* fd",
ປະເພດທົ່ວໄປ => [qw(BUSL)],
ລະຫັດ => 'PerlIO *fp;
IO * io;

io = GvIO(gv_fetchpv($COMP(fd),FALSE,SVt_PVIO));
ຖ້າ (!io || !(fp = IoIFP(io)))
croak("ບໍ່ສາມາດຄິດອອກ FP");

ຖ້າ (PerlIO_write(fp,$P(a),len) != len)
croak("ຂຽນຜິດພາດ pnm");
');

ຟັງຊັນນີ້ໃຊ້ເພື່ອຂຽນຂໍ້ມູນຈາກ pdl ໄປຫາໄຟລ໌. ຕົວອະທິບາຍໄຟລ໌ຜ່ານ
ເປັນສະຕຣິງເຂົ້າໄປໃນຟັງຊັນນີ້. ພາລາມິເຕີນີ້ບໍ່ໄດ້ເຂົ້າໄປໃນພາກ "Pars".
ເນື່ອງຈາກວ່າມັນບໍ່ສາມາດປະຕິບັດທີ່ເປັນປະໂຫຍດຄືກັບ pdl ແຕ່ແທນທີ່ຈະເປັນຊື່ທີ່ເຫມາະສົມ
ສ່ວນ "OtherPars". ພາລາມິເຕີໃນພາກ "OtherPars" ປະຕິບັດຕາມສິ່ງທີ່ຢູ່ໃນ "Pars"
ພາກສ່ວນໃນເວລາທີ່ເອີ້ນຟັງຊັນ, ie

ເປີດ FILE,">out.dat" ຫຼືຕາຍ "ບໍ່ສາມາດເປີດ out.dat";
pnmout($pdl,'FILE');

ໃນເວລາທີ່ທ່ານຕ້ອງການທີ່ຈະເຂົ້າເຖິງພາລາມິເຕີນີ້ພາຍໃນພາກສ່ວນລະຫັດ, ທ່ານຕ້ອງບອກ PP ໂດຍ
ການນໍາໃຊ້ Macro $COMP, ie ທ່ານຂຽນ "$COMP(fd)" ໃນຕົວຢ່າງ. ຖ້າບໍ່ດັ່ງນັ້ນ PP
ບໍ່ຮູ້ວ່າ "fd" ທີ່ເຈົ້າອ້າງເຖິງແມ່ນຄືກັນກັບທີ່ລະບຸໄວ້ໃນ
ສ່ວນ "OtherPars".

ການນໍາໃຊ້ອີກອັນຫນຶ່ງສໍາລັບພາກສ່ວນ "OtherPars" ແມ່ນເພື່ອກໍານົດຂະຫນາດທີ່ມີຊື່ໃນລາຍເຊັນ.
ຂໍ​ໃຫ້​ມີ​ຕົວ​ຢ່າງ​ວິ​ທີ​ການ​ທີ່​ເຮັດ​ໄດ້​:

pp_def('setdim',
Pars => '[o] a(n)',
OtherPars => 'int ns => n',
ລະຫັດ => 'loop(n) %{ $a() = n; %}',
);

ນີ້ບອກວ່າຂະຫນາດທີ່ມີຊື່ວ່າ "n" ຈະຖືກເລີ່ມຕົ້ນຈາກມູນຄ່າຂອງ ອື່ນໆ
ພາລາມິເຕີ "ns" ເຊິ່ງເປັນປະເພດຈໍານວນເຕັມ (ຂ້ອຍເດົາເຈົ້າຮູ້ວ່າພວກເຮົາໃຊ້
"CType From => named_dim" syntax). ດຽວນີ້ທ່ານສາມາດໂທຫາຟັງຊັນນີ້ໃນແບບປົກກະຕິ:

setdim(($a=null),5);
ພິມ $a;
[ 0 1 2 3 4 ]

ຍອມຮັບວ່າຟັງຊັນນີ້ບໍ່ມີປະໂຫຍດຫຼາຍແຕ່ມັນສະແດງໃຫ້ເຫັນວິທີການເຮັດວຽກ. ຖ້າ​ເຈົ້າ
ໂທຫາຟັງຊັນທີ່ມີ pdl ທີ່ມີຢູ່ແລ້ວແລະທ່ານບໍ່ຈໍາເປັນຕ້ອງລະບຸຢ່າງຊັດເຈນ
ຂະຫນາດຂອງ "n" ນັບຕັ້ງແຕ່ PDL::PP ສາມາດຄິດໄລ່ມັນອອກຈາກຂະຫນາດຂອງ pdl ທີ່ບໍ່ແມ່ນ null. ໃນ
ກໍລະນີນີ້ທ່ານພຽງແຕ່ໃຫ້ພາລາມິເຕີມິຕິເປັນ "-1":

$a = hist($b);
setdim($a,-1);

ສິ່ງນັ້ນຄວນເຮັດມັນ.

ຟັງຊັນ PP ເທົ່ານັ້ນທີ່ພວກເຮົາໄດ້ໃຊ້ໃນຕົວຢ່າງມາເຖິງຕອນນັ້ນແມ່ນ "loop". ນອກຈາກນັ້ນ,
ໃນປັດຈຸບັນມີສອງຫນ້າທີ່ອື່ນໆທີ່ຖືກຮັບຮູ້ຢູ່ໃນພາກ "ລະຫັດ":

threadloop
ດັ່ງທີ່ພວກເຮົາໄດ້ຍິນຂ້າງເທິງລາຍເຊັນຂອງຫນ້າທີ່ກໍານົດ PP ກໍານົດຂະຫນາດຂອງທັງຫມົດ
ການໂຕ້ຖຽງ pdl ມີສ່ວນຮ່ວມໃນ a primitive ການດໍາເນີນງານ. ຢ່າງໃດກໍຕາມ, ທ່ານມັກຈະໂທຫາ
ຫນ້າທີ່ທີ່ທ່ານກໍານົດດ້ວຍ PP ກັບ pdls ທີ່ມີຂະຫນາດຫຼາຍກວ່ານັ້ນ
ລະບຸໄວ້ໃນລາຍເຊັນ. ໃນ​ກໍ​ລະ​ນີ​ນີ້​ການ​ດໍາ​ເນີນ​ງານ primitive ແມ່ນ​ປະ​ຕິ​ບັດ​ໃນ​ທັງ​ຫມົດ​
subslices ຂອງຂະຫນາດທີ່ເຫມາະສົມໃນສິ່ງທີ່ເອີ້ນວ່າ a ກະ​ທູ້ loop (ເບິ່ງຕື່ມ
ພາບລວມຂ້າງເທິງ ແລະ PDL::Indexing). ສົມມຸດວ່າເຈົ້າມີແນວຄິດກ່ຽວກັບແນວຄິດນີ້ເຈົ້າ
ອາດຈະຂອບໃຈວ່າການປະຕິບັດງານທີ່ລະບຸໄວ້ໃນພາກລະຫັດຄວນຈະເປັນ
ປັບປຸງໃຫ້ເໝາະສົມເນື່ອງຈາກນີ້ເປັນສາຍຮັດທີ່ແໜ້ນທີ່ສຸດພາຍໃນເສັ້ນດ້າຍ. ຢ່າງໃດກໍຕາມ, ຖ້າທ່ານທົບທວນຄືນ
ຕົວຢ່າງທີ່ພວກເຮົາກໍານົດຫນ້າທີ່ "pnmout", ທ່ານຈະຮັບຮູ້ຢ່າງໄວວາວ່າຊອກຫາ
up the "IO" file descriptor ໃນ loop thread ພາຍໃນແມ່ນບໍ່ມີປະສິດທິພາບຫຼາຍໃນເວລາຂຽນ
pdl ທີ່ມີຫຼາຍແຖວ. ວິທີການທີ່ດີກວ່າຈະເປັນການຊອກຫາ "IO" descriptor ຫນຶ່ງຄັ້ງ
ຢູ່ນອກ loop thread ແລະນໍາໃຊ້ມູນຄ່າຂອງມັນຫຼັງຈາກນັ້ນພາຍໃນ loop thread ໃກ້ຊິດທີ່ສຸດ. ນີ້​ແມ່ນ
ແນ່ນອນວ່າຫນ້າທີ່ "threadloop" ມີປະໂຫຍດ. ນີ້ແມ່ນຄໍານິຍາມທີ່ຖືກປັບປຸງ
ຂອງ "pnmout" ເຊິ່ງໃຊ້ຟັງຊັນນີ້:

pp_def('pnmout',
Pars => 'a(ມ)',
OtherPars => "char* fd",
ປະເພດທົ່ວໄປ => [qw(BUSL)],
ລະຫັດ => 'PerlIO *fp;
IO * io;
int len;

io = GvIO(gv_fetchpv($COMP(fd),FALSE,SVt_PVIO));
ຖ້າ (!io || !(fp = IoIFP(io)))
croak("ບໍ່ສາມາດຄິດອອກ FP");

ເລນ = $ຫລືຂະຫຍາຍໂຕ(m) * sizeof($GENERIC());

threadloop %{
ຖ້າ (PerlIO_write(fp,$P(a),len) != len)
croak("ຂຽນຜິດພາດ pnm");
%}
');

ນີ້ເຮັດວຽກດັ່ງຕໍ່ໄປນີ້. ປົກກະຕິແລ້ວລະຫັດ C ທີ່ທ່ານຂຽນຢູ່ໃນສ່ວນ "ລະຫັດ" ແມ່ນຖືກຈັດໃສ່
ພາຍໃນ loop thread (ie PP ສ້າງລະຫັດ XS wrapping ທີ່ເຫມາະສົມປະມານມັນ).
ຢ່າງໃດກໍຕາມ, ເມື່ອທ່ານໃຊ້ຟັງຊັນ "threadloop", PDL:: PP ຮັບຮູ້ນີ້ແລະ.
ບໍ່ໄດ້ຫໍ່ລະຫັດຂອງທ່ານດ້ວຍ loop thread ເພີ່ມເຕີມ. ນີ້ມີຜົນກະທົບທີ່ລະຫັດທ່ານ
ຂຽນຢູ່ນອກ loop thread ແມ່ນປະຕິບັດພຽງແຕ່ຄັ້ງດຽວຕໍ່ການຫັນປ່ຽນແລະພຽງແຕ່ລະຫັດ
with ທີ່ຢູ່ອ້ອມຮອບ "%{ ... %}" ຄູ່ແມ່ນຖືກຈັດໃສ່ພາຍໃນ loop thread ທີ່ແຫນ້ນທີ່ສຸດ. ນີ້
ຍັງມາຢູ່ໃນມືໃນເວລາທີ່ທ່ານຕ້ອງການທີ່ຈະປະຕິບັດການຕັດສິນໃຈ (ຫຼືລະຫັດອື່ນໆ, ໂດຍສະເພາະ
CPU intensive code) ພຽງແຕ່ຫນຶ່ງຄັ້ງຕໍ່ກະທູ້, ie

pp_addhdr('
#ກໍານົດ RAW 0
#ກໍານົດ ASCII 1
');
pp_def('do_raworascii',
Pars => 'a(); b(); [o]c()',
OtherPars => 'ໂໝດ int',
ລະຫັດ => 'ສະຫຼັບ ($COMP(ຮູບແບບ)) {
ກໍລະນີ RAW:
threadloop %{
/* ເຮັດວັດຖຸດິບ */
%}
ທໍາລາຍ;
ກໍລະນີ ASCII:
threadloop %{
/* ເຮັດ ASCII ສິ່ງ */
%}
ທໍາລາຍ;
default:
croak("ຮູບແບບທີ່ບໍ່ຮູ້ຈັກ");
}'
);

ປະເພດ
ຟັງຊັນປະເພດເຮັດວຽກຄ້າຍຄືກັນກັບມະຫາພາກ $T. ຢ່າງໃດກໍຕາມ, ດ້ວຍຫນ້າທີ່ "ປະເພດ".
ລະຫັດໃນບລັອກຕໍ່ໄປນີ້ (ຂັ້ນດ້ວຍ "%{" ແລະ "%}" ຕາມປົກກະຕິ) ຖືກປະຕິບັດສໍາລັບທຸກຄົນ
ກໍລະນີເຫຼົ່ານັ້ນທີ່ປະເພດຂອງການດໍາເນີນການແມ່ນ ໃດ of ປະເພດທີ່ເປັນຕົວແທນໂດຍ
ຕົວອັກສອນໃນການໂຕ້ຖຽງກັບ "ປະເພດ", eg

ລະຫັດ => '...

ປະເພດ(BSUL) %{
/* ເຮັດ​ການ​ປະ​ຕິ​ບັດ​ປະ​ເພດ​ເລກ​ເຕັມ */
%}
ປະເພດ(FD) %{
/* ເຮັດ​ການ​ດໍາ​ເນີນ​ງານ​ຈຸດ​ທີ່​ເລື່ອນ */
%}
... '

ໄດ້ RedoDimsCode ສ່ວນ
ປຸ່ມ "RedoDimsCode" ເປັນກະແຈທາງເລືອກທີ່ຖືກນໍາໃຊ້ເພື່ອຄິດໄລ່ຂະຫນາດຂອງ piddles ຢູ່.
runtime ໃນກໍລະນີທີ່ກົດລະບຽບມາດຕະຖານສໍາລັບຂະຫນາດຄອມພິວເຕີ້ຈາກລາຍເຊັນບໍ່ແມ່ນ
ພຽງພໍ. ເນື້ອໃນຂອງ "RedoDimsCode" ແມ່ນຖືກຕີຄວາມຫມາຍໃນລັກສະນະດຽວກັນ
ພາກສ່ວນລະຫັດຖືກຕີຄວາມ - ie, PP macro ແມ່ນຂະຫຍາຍແລະຜົນໄດ້ຮັບແມ່ນ
ແປເປັນລະຫັດ C. ຈຸດປະສົງຂອງລະຫັດແມ່ນເພື່ອກໍານົດຂະຫນາດຂອງບາງຂະຫນາດທີ່
ປາກົດຢູ່ໃນລາຍເຊັນ. ການຈັດສັນການເກັບຮັກສາແລະ threadloops ແລະອື່ນໆຈະໄດ້ຮັບການສ້າງຕັ້ງຂຶ້ນເປັນ
ຖ້າຂະຫນາດທີ່ຄິດໄລ່ໄດ້ປາກົດຢູ່ໃນລາຍເຊັນ. ໃນລະຫັດຂອງທ່ານ, ທ່ານທໍາອິດຄິດໄລ່
ຂະຫນາດທີ່ຕ້ອງການຂອງຂະຫນາດທີ່ມີຊື່ໃນລາຍເຊັນຕາມຄວາມຕ້ອງການຂອງເຈົ້າແລະຫຼັງຈາກນັ້ນ
ມອບຄ່ານັ້ນໃຫ້ມັນຜ່ານທາງ $SIZE() ມະຫາພາກ.

ເປັນຕົວຢ່າງ, ພິຈາລະນາສະຖານະການຕໍ່ໄປນີ້. ທ່ານກຳລັງຕິດຕໍ່ກັບຫ້ອງສະໝຸດພາຍນອກ
ປົກກະຕິທີ່ຕ້ອງການອາເຣຊົ່ວຄາວເພື່ອໃຫ້ພື້ນທີ່ເຮັດວຽກຖືກສົ່ງຜ່ານເປັນການໂຕ້ຖຽງ. ສອງ
input data array ທີ່ຜ່ານແມ່ນ p(m) ແລະ x(n). array ຂໍ້ມູນຜົນໄດ້ຮັບແມ່ນ y(n). ໄດ້
ປົກກະຕິຕ້ອງການອາເຣພື້ນທີ່ເຮັດວຽກທີ່ມີຄວາມຍາວ n+m*m, ແລະທ່ານຕ້ອງການບ່ອນເກັບມ້ຽນ
ຖືກສ້າງຂື້ນໂດຍອັດຕະໂນມັດຄືກັບວ່າມັນຈະເປັນ piddle ໃດໆທີ່ມີທຸງ [t] ຫຼື [o]. ແມ່ນ​ຫຍັງ
ທ່ານຕ້ອງການແມ່ນເວົ້າບາງສິ່ງບາງຢ່າງເຊັ່ນ:

pp_def( "myexternalfunc",
Pars => " p(ມ); x(n); [o] y; [t] ວຽກ(n+m*m); ", ...

ແຕ່ມັນຈະບໍ່ເຮັດວຽກ, ເພາະວ່າ PP ບໍ່ສາມາດຕີຄວາມຫມາຍສໍານວນດ້ວຍເລກເລກໃນຕົວເລກ
ລາຍເຊັນ. ແທນທີ່ເຈົ້າຂຽນ

pp_def( "myexternalfunc",
Pars => " p(ມ); x(n); [o] y; [t] ວຽກ(wn); ",
RedoDimsCode => "
int im = $PDL(p)->dims[0];
int ໃນ = $PDL(x)-> dims[0];
int min = ໃນ + im * im;
int inw = $PDL(work)-> dims[0];
$SIZE(wn) = inw >= ນາທີ ? inw: ນາທີ; ",
ລະຫັດ => "
externalfunc($P(p),$P(x),$ຫລືຂະຫຍາຍໂຕ(m),$SIZE(n),$P(work));
";)

ລະຫັດນີ້ເຮັດວຽກດັ່ງຕໍ່ໄປນີ້: ມະຫາພາກ $PDL(p) ຂະຫຍາຍໄປຫາຕົວຊີ້ໄປຫາໂຄງສ້າງ pdl ສໍາລັບ
piddle p. ທ່ານບໍ່ຕ້ອງການຕົວຊີ້ໄປຫາຂໍ້ມູນ (ເຊັ່ນ $P) ໃນກໍລະນີນີ້, ເພາະວ່າທ່ານ
ຕ້ອງການເຂົ້າເຖິງວິທີການສໍາລັບ piddle ໃນລະດັບ C. ທ່ານໄດ້ຮັບຂະຫນາດທໍາອິດຂອງ
ແຕ່ລະ piddles ແລະເກັບຮັກສາໃຫ້ເຂົາເຈົ້າຢູ່ໃນຈໍານວນເຕັມ. ຫຼັງ​ຈາກ​ນັ້ນ​, ທ່ານ​ຄິດ​ໄລ່​ຄວາມ​ຍາວ​ຕໍາ​່​ສຸດ​ທີ່​ໄດ້​
array ການເຮັດວຽກສາມາດ. ຖ້າຜູ້ໃຊ້ສົ່ງ piddle "ເຮັດວຽກ" ດ້ວຍການເກັບຮັກສາພຽງພໍ, ຫຼັງຈາກນັ້ນປ່ອຍໃຫ້ມັນ
ຄົນດຽວ. ຖ້າຜູ້ໃຊ້ສົ່ງ, ເວົ້າວ່າ pdl null, ຫຼືບໍ່ມີ pdl ທັງຫມົດ, ຫຼັງຈາກນັ້ນຂະຫນາດຂອງ wn ຈະເປັນ
ສູນ ແລະທ່ານຕັ້ງມັນຄືນເປັນຄ່າຕໍ່າສຸດ. ກ່ອນທີ່ລະຫັດໃນພາກລະຫັດແມ່ນ
PP ທີ່ຖືກປະຕິບັດຈະສ້າງການເກັບຮັກສາທີ່ເຫມາະສົມສໍາລັບ "ເຮັດວຽກ" ຖ້າມັນບໍ່ມີ. ໃຫ້ສັງເກດວ່າທ່ານ
ພຽງແຕ່ເອົາຂະຫນາດທໍາອິດຂອງ "p" ແລະ "x" ເພາະວ່າຜູ້ໃຊ້ອາດຈະສົ່ງ piddles ກັບ
ຂະຫນາດກະທູ້ພິເສດ. ແນ່ນອນ, piddle "ເຮັດວຽກ" ຊົ່ວຄາວ (ຫມາຍເຫດ [t] ທຸງ)
ບໍ່ຄວນໃຫ້ຂະໜາດກະທູ້ໃດໆ.

ທ່ານຍັງສາມາດໃຊ້ "RedoDimsCode" ເພື່ອກໍານົດຂະຫນາດຂອງ piddle ທີ່ຖືກທຸງດ້ວຍ [o]. ໃນ​ນີ້
ກໍລະນີທີ່ທ່ານກໍານົດຂະຫນາດສໍາລັບຂະຫນາດທີ່ມີຊື່ໃນລາຍເຊັນໂດຍໃຊ້ $SIZE() ຄືໃນ
ຕົວຢ່າງກ່ອນຫນ້າ. ຢ່າງໃດກໍຕາມ, ເນື່ອງຈາກວ່າ piddle ຖືກທຸງດ້ວຍ [o] ແທນທີ່ຈະເປັນ [t],
ຂະ​ຫນາດ​ກະ​ທູ້​ຈະ​ໄດ້​ຮັບ​ການ​ເພີ່ມ​ຖ້າ​ຫາກ​ວ່າ​ຕ້ອງ​ການ​ເຊັ່ນ​ດຽວ​ກັນ​ກັບ​ຂະ​ຫນາດ​ຂອງ​ຂະ​ຫນາດ​ໄດ້​
ຄິດໄລ່ຈາກລາຍເຊັນຕາມກົດລະບຽບປົກກະຕິ. ນີ້ແມ່ນຕົວຢ່າງຈາກ
PDL::ຄະນິດສາດ

pp_def("ໂພລີໂຣດ",
Pars => 'cr(n); ci(n); [o]rr(ມ); [o]ri(ມ);',
RedoDimsCode => 'int sn = $PDL(cr)->dims[0]; $ຫລືຂະຫຍາຍໂຕ(m) = sn-1;',

piddles ການປ້ອນຂໍ້ມູນແມ່ນສ່ວນທີ່ແທ້ຈິງແລະຈິນຕະນາການຂອງຕົວຄູນຊັບຊ້ອນຂອງ a
ພຍານາມ. piddles ຜົນຜະລິດແມ່ນພາກສ່ວນທີ່ແທ້ຈິງແລະຈິນຕະນາການຂອງຮາກ. ມີ "n"
ຮາກເປັນ "n" ລໍາດັບ polynomial ແລະ polynomial ດັ່ງກ່າວມີສໍາປະສິດ "n + 1" (the
zeoreth ຜ່ານ "n"th). ໃນຕົວຢ່າງນີ້, threading ຈະເຮັດວຽກຢ່າງຖືກຕ້ອງ. ນັ້ນແມ່ນ, ໄດ້
ຂະ​ຫນາດ​ທໍາ​ອິດ​ຂອງ piddle ຜົນ​ຜະ​ລິດ​ທີ່​ມີ​ການ​ປັບ​ຂະ​ຫນາດ​ຂອງ​ຕົນ​, ແຕ່​ກະ​ທູ້​ອື່ນໆ​
ຂະຫນາດຈະຖືກມອບຫມາຍຄືກັບວ່າບໍ່ມີ "RedoDimsCode".

ແຜນທີ່ພິມ ການຈັດການ in ໄດ້ "Pars ອື່ນໆ" ສ່ວນ
ພາກສ່ວນ "OtherPars" ທີ່ໄດ້ກ່າວມາຂ້າງເທິງນີ້ມັກຈະມີຄວາມສໍາຄັນຢ່າງແທ້ຈິງໃນເວລາທີ່ທ່ານ
ການໂຕ້ຕອບຫ້ອງສະຫມຸດພາຍນອກກັບ PDL. ຢ່າງໃດກໍຕາມ, ໃນຫຼາຍໆກໍລະນີ, ຫ້ອງສະຫມຸດພາຍນອກ
ໃຊ້ປະເພດທີ່ມາຈາກຫຼືຕົວຊີ້ຂອງປະເພດຕ່າງໆ.

ວິທີການມາດຕະຖານໃນການຈັດການນີ້ໃນ Perl ແມ່ນການໃຊ້ໄຟລ໌ "typemap". ນີ້ແມ່ນປຶກສາຫາລືໃນ
ບາງລາຍລະອຽດໃນ perlxs ໃນເອກະສານ Perl ມາດຕະຖານ. ໃນ PP ການທໍາງານແມ່ນຫຼາຍ
ຄ້າຍຄືກັນ, ດັ່ງນັ້ນທ່ານສາມາດສ້າງໄຟລ໌ "typemap" ໃນໄດເລກະທໍລີທີ່ໄຟລ໌ PP ຂອງທ່ານອາໄສຢູ່
ແລະ​ເມື່ອ​ມັນ​ຖືກ​ສ້າງ​ຂຶ້ນ​ມັນ​ຈະ​ຖືກ​ອ່ານ​ອັດ​ຕະ​ໂນ​ມັດ​ເພື່ອ​ຊອກ​ຫາ​ການ​ແປ​ພາ​ສາ​ທີ່​ເຫມາະ​ສົມ​
ລະຫວ່າງປະເພດ C ແລະປະເພດການກໍ່ສ້າງຂອງ Perl.

ທີ່ເວົ້າວ່າ, ມີສອງສາມຄວາມແຕກຕ່າງທີ່ສໍາຄັນຈາກການຈັດການທົ່ວໄປຂອງປະເພດ
ໃນ XS. ທໍາອິດ, ແລະອາດຈະສໍາຄັນທີ່ສຸດ, ແມ່ນວ່າໃນເວລານີ້ຊີ້ໃຫ້ເຫັນເຖິງປະເພດຕ່າງໆ
ບໍ່ອະນຸຍາດໃຫ້ຢູ່ໃນພາກ "OtherPars". ເພື່ອໃຫ້ໄດ້ຮັບປະມານຂໍ້ຈໍາກັດນີ້, ທ່ານຈະຕ້ອງໃຊ້
ປະເພດ "IV" (ຂໍຂອບໃຈ Judd Taylor ສໍາລັບການຊີ້ໃຫ້ເຫັນວ່ານີ້ແມ່ນມີຄວາມຈໍາເປັນສໍາລັບການພົກພາ).

ມັນອາດຈະດີທີ່ສຸດທີ່ຈະສະແດງຕົວຢ່າງນີ້ດ້ວຍສອງສາມລະຫັດ:

ຕົວຢ່າງເຊັ່ນຟັງຊັນ "gsl_spline_init" ມີການປະກາດ C ຕໍ່ໄປນີ້:

int gsl_spline_init(gsl_spline * spline,
const double xa[], const double ya[], size_t size);

ເຫັນໄດ້ຊັດເຈນວ່າອາເຣ "xa" ແລະ "ya" ແມ່ນຕົວເລືອກສໍາລັບການຖືກສົ່ງຜ່ານເປັນ piddles ແລະ
ການໂຕ້ຖຽງ "ຂະຫນາດ" ແມ່ນພຽງແຕ່ຄວາມຍາວຂອງ piddles ເຫຼົ່ານີ້ເພື່ອໃຫ້ສາມາດຈັດການໄດ້
"$SIZE()" ມະຫາພາກໃນ PP. ບັນຫາແມ່ນຕົວຊີ້ໄປຫາປະເພດ "gsl_spline". ທໍາມະຊາດ
ການແກ້ໄຂຈະເປັນການຂຽນການປະກາດ "OtherPars" ຂອງແບບຟອມ

OtherPars => 'gsl_spline *spl'

ແລະຂຽນໄຟລ໌ "typemap" ສັ້ນທີ່ຈັດການກັບປະເພດນີ້. ນີ້ບໍ່ໄດ້ຜົນໃນປັດຈຸບັນ
ແນວໃດກໍ່ຕາມ! ດັ່ງນັ້ນສິ່ງທີ່ທ່ານຕ້ອງເຮັດຄືການໄປປະມານບັນຫາເລັກນ້ອຍ (ແລະໃນບາງທາງ
ນີ້​ແມ່ນ​ງ່າຍ​ຂຶ້ນ​!):

ການແກ້ໄຂແມ່ນເພື່ອປະກາດ "spline" ໃນພາກ "OtherPars" ໂດຍໃຊ້ "ມູນຄ່າຈໍານວນເຕັມ",
"IV". ນີ້ເຊື່ອງລັກສະນະຂອງຕົວແປຈາກ PP ແລະຫຼັງຈາກນັ້ນທ່ານຈໍາເປັນຕ້ອງ (ດີເພື່ອຫຼີກເວັ້ນ
ຄໍາເຕືອນ compiler ຢ່າງຫນ້ອຍ!) ດໍາເນີນການພິມປະເພດໃນເວລາທີ່ທ່ານໃຊ້ຕົວແປໃນລະຫັດຂອງທ່ານ.
ດັ່ງນັ້ນ "OtherPars" ຄວນໃຊ້ແບບຟອມ:

OtherPars => 'IV spl'

ແລະເມື່ອທ່ານໃຊ້ມັນຢູ່ໃນລະຫັດທີ່ທ່ານຈະຂຽນ

INT2PTR(gsl_spline *, $COMP(spl))

ບ່ອນທີ່ Perl API macro "INT2PTR" ໄດ້ຖືກນໍາໃຊ້ເພື່ອຈັດການຕົວຊີ້ຕົວຊີ້ເພື່ອຫຼີກເວັ້ນ
ຄໍາເຕືອນ compiler ແລະບັນຫາສໍາລັບເຄື່ອງຈັກທີ່ມີ Perl 32bit ແລະ 64bit ປະສົມ
ການຕັ້ງຄ່າ. ການວາງນີ້ຮ່ວມກັນດັ່ງທີ່ Andres Jordan ໄດ້ເຮັດ (ດ້ວຍການດັດແກ້
ການນໍາໃຊ້ "IV" ໂດຍ Judd Taylor) ໃນ "gsl_interp.pd" ໃນແຫຼ່ງການແຈກຢາຍທີ່ທ່ານໄດ້ຮັບ:

pp_def('init_meat',
Pars => 'double x(n); double y(n);',
OtherPars => 'IV spl',
ລະຫັດ =>'
gsl_spline_init,( INT2PTR(gsl_spline *, $COMP(spl)), $P(x),$P(y),$SIZE(n)));'
);

ບ່ອນທີ່ຂ້ອຍໄດ້ຖອນການໂທ wrapper ມະຫາພາກ, ແຕ່ນັ້ນຈະປິດບັງການສົນທະນາ.

ຄວາມແຕກຕ່າງເລັກນ້ອຍອື່ນໆເມື່ອປຽບທຽບກັບການຈັດການແຜນຜັງມາດຕະຖານໃນ Perl, ແມ່ນວ່າ
ຜູ້​ໃຊ້​ບໍ່​ສາ​ມາດ​ລະ​ບຸ​ທີ່​ຕັ້ງ typemap ທີ່​ບໍ່​ໄດ້​ມາດ​ຕະ​ຖານ​ຫຼື​ຊື່​ໄຟລ​໌ typemap ການ​ນໍາ​ໃຊ້​
"TYPEMAPS" ທາງເລືອກໃນ MakeMaker ... ດັ່ງນັ້ນທ່ານສາມາດນໍາໃຊ້ໄຟລ໌ທີ່ເອີ້ນວ່າ "typemap" ແລະ / ຫຼືໄຟລ໌.
"IV" trick ຂ້າງເທິງ.

ອື່ນ ໆ ທີ່ເປັນປະໂຫຍດ PP ໃຊ້ in ຂໍ້ມູນ ປະຕິບັດງານ ຄໍານິຍາມ
ທ່ານໄດ້ຍິນແລ້ວກ່ຽວກັບປຸ່ມ "OtherPars". ໃນປັດຈຸບັນ, ບໍ່ມີກະແຈອື່ນໆຈໍານວນຫຼາຍ
ສໍາລັບການດໍາເນີນງານຂໍ້ມູນທີ່ຈະເປັນປະໂຫຍດໃນປົກກະຕິ (ອັນໃດກໍ່ຕາມ) ການຂຽນໂປລແກລມ PP. ໃນ
ຄວາມຈິງ, ມັນຈະເປັນຫນ້າສົນໃຈທີ່ຈະໄດ້ຍິນກ່ຽວກັບກໍລະນີທີ່ທ່ານຄິດວ່າທ່ານຕ້ອງການຫຼາຍກ່ວາສິ່ງທີ່
ແມ່ນສະຫນອງໃຫ້ໃນເວລານີ້. ກະລຸນາເວົ້າຢູ່ໃນບັນຊີລາຍຊື່ທາງໄປສະນີ PDL. ອື່ນໆທີ່ສຸດ
ກະແຈທີ່ຮັບຮູ້ໂດຍ "pp_def" ແມ່ນເປັນປະໂຫຍດແທ້ໆສໍາລັບສິ່ງທີ່ພວກເຮົາໂທຫາ slice ການດໍາເນີນງານ (ເບິ່ງ
ຂ້າງເທິງ).

ສິ່ງຫນຶ່ງທີ່ກໍາລັງວາງແຜນຢ່າງແຂງແຮງແມ່ນຈໍານວນການໂຕ້ຖຽງທີ່ປ່ຽນແປງ, ເຊິ່ງຈະເປັນ
tricky ພຽງ​ເລັກ​ນ້ອຍ​.

ບັນຊີລາຍຊື່ບໍ່ຄົບຖ້ວນຂອງກະແຈທີ່ມີຢູ່:

ໃນ​ສະ​ຖານ​ທີ່
ການຕັ້ງຄ່າກະແຈນີ້ໝາຍເຖິງສິ່ງທີ່ເຮັດປະຈຳເປັນບ່ອນເຮັດວຽກ - ຄືການປ້ອນຂໍ້ມູນ ແລະຜົນຜະລິດ
piddles ແມ່ນຄືກັນ. ຕົວຢ່າງຄື "$a->inplace->sqrt()" (ຫຼື "sqrt(inplace($a))").

Inplace => 1
ໃຊ້ໃນເວລາທີ່ປົກກະຕິແມ່ນຫນ້າທີ່ unary, ເຊັ່ນ "sqrt".

ແທນທີ່ => ['a']
ຖ້າ​ຫາກ​ວ່າ​ມີ​ຫຼາຍ​ກວ່າ​ຫນຶ່ງ piddles ການ​ປ້ອນ​ຂໍ້​ມູນ​, ລະ​ບຸ​ຊື່​ຂອງ​ຫນຶ່ງ​ທີ່​ສາ​ມາດ​ເປັນ​ໄດ້​
ປ່ຽນແທນໂດຍໃຊ້ການອ້າງອີງອາເຣ.

ທັບ => ['a','b']
ຖ້າ​ຫາກ​ວ່າ​ມີ​ຫຼາຍ​ກ​່​ວາ​ຫນຶ່ງ piddle ຜົນ​ຜະ​ລິດ​, ໃຫ້​ລະ​ບຸ​ຊື່​ຂອງ input piddle ແລະ​
output piddle ໃນ 2-element array reference. ນີ້ອາດຈະບໍ່ຈໍາເປັນ, ແຕ່ປະໄວ້
ເພື່ອຄວາມສົມບູນ.

ຖ້າມີການໃຊ້ຄຸນຄ່າທີ່ບໍ່ດີ, ຕ້ອງໄດ້ຮັບການດູແລເພື່ອຮັບປະກັນການຂະຫຍາຍພັນຂອງພືດ
badflag ໃນເວລາທີ່ inplace ຖືກນໍາໃຊ້; ພິຈາລະນາ excerpt ນີ້ຈາກ ພື້ນຖານ/ບໍ່ດີ/bad.pd:

pp_def('replacebad',HandleBad => 1,
Pars => 'a(); [o]b();',
OtherPars => 'ຄູ່ໃໝ່',
ທັບ => 1,
CopyBadStatusCode =>
'/* propogate badflag ຖ້າ inplace ແລະມັນມີການປ່ຽນແປງ */
ຖ້າ (a == b && $ISPDLSTATEBAD(a) )
PDL->propogate_badflag(b, 0 );

/* ສະເຫມີໃຫ້ແນ່ໃຈວ່າຜົນຜະລິດແມ່ນ "ດີ" */
$SETPDLSTATEGOOD(b);
',
...

ນັບຕັ້ງແຕ່ການປົກກະຕິນີ້ເອົາຄ່າທີ່ບໍ່ດີທັງຫມົດ, ຫຼັງຈາກນັ້ນ piddle ຜົນຜະລິດມີທຸງທີ່ບໍ່ດີຂອງມັນ
ລຶບລ້າງ. ຖ້າແລ່ນ inplace (ດັ່ງນັ້ນ "a = = b"), ພວກເຮົາຕ້ອງບອກເດັກນ້ອຍທັງຫມົດຂອງ "a"
ວ່າທຸງທີ່ບໍ່ດີໄດ້ຖືກລຶບລ້າງ (ເພື່ອປະຫຍັດເວລາພວກເຮົາໃຫ້ແນ່ໃຈວ່າພວກເຮົາໂທຫາ
"PDL->propogate_badgflag" ພຽງແຕ່ຖ້າ input piddle ມີທຸງທີ່ບໍ່ດີຂອງມັນ).

ຫມາຍເຫດ: ຄວາມຄິດອັນຫນຶ່ງແມ່ນວ່າເອກະສານສໍາລັບການປົກກະຕິສາມາດອັດຕະໂນມັດ
ທຸງເພື່ອຊີ້ບອກວ່າມັນສາມາດໄດ້ຮັບການປະຕິບັດ inplace, ie ບາງສິ່ງບາງຢ່າງທີ່ຄ້າຍຄືກັນກັບວິທີການ
"HandleBad" ກໍານົດ "BadDoc" ຖ້າມັນບໍ່ໄດ້ຖືກສະຫນອງ (ມັນບໍ່ແມ່ນການແກ້ໄຂທີ່ເຫມາະສົມ).

ອື່ນ ໆ PDL::PP ຫນ້າທີ່ to ສະຫນັບສະຫນູນ concise ຊຸດ ຄໍານິຍາມ
ມາຮອດປະຈຸ, ພວກເຮົາໄດ້ອະທິບາຍຫນ້າທີ່ "pp_def" ແລະ "pp_done". PDL::PP ສົ່ງອອກຈໍານວນຫນ້ອຍ
ຫນ້າທີ່ອື່ນໆທີ່ຈະຊ່ວຍໃຫ້ທ່ານຂຽນຄໍານິຍາມຊຸດຂະຫຍາຍ PDL ສັ້ນໆ.

pp_addhdr

ເລື້ອຍໆໃນເວລາທີ່ທ່ານໂຕ້ຕອບຫ້ອງສະຫມຸດຫນ້າທີ່ເປັນໃນຕົວຢ່າງຂ້າງເທິງນີ້, ທ່ານຕ້ອງປະກອບ
C ເພີ່ມເຕີມປະກອບມີໄຟລ໌. ເນື່ອງຈາກໄຟລ໌ XS ຖືກສ້າງຂຶ້ນໂດຍ PP ພວກເຮົາຕ້ອງການວິທີການບາງຢ່າງ
ເຮັດໃຫ້ PP ໃສ່ທີ່ເຫມາະສົມປະກອບມີຄໍາແນະນໍາໃນສະຖານທີ່ທີ່ເຫມາະສົມເຂົ້າໄປໃນ XS ທີ່ຜະລິດ
ໄຟລ໌. ເພື່ອເຮັດສິ່ງນີ້, ມີຫນ້າທີ່ "pp_addhdr". ນີ້​ແມ່ນ​ຍັງ​ຫນ້າ​ທີ່​ທີ່​ຈະ​ນໍາ​ໃຊ້​
ເມື່ອທ່ານຕ້ອງການກໍານົດບາງຟັງຊັນ C ສໍາລັບການນໍາໃຊ້ພາຍໃນໂດຍບາງຟັງຊັນ XS
(ເຊິ່ງສ່ວນຫຼາຍແມ່ນຫນ້າທີ່ກໍານົດໂດຍ "pp_def"). ໂດຍການລວມເອົາຫນ້າທີ່ເຫຼົ່ານີ້ຢູ່ທີ່ນີ້ທ່ານ
ໃຫ້ແນ່ໃຈວ່າ PDL::PP ໃສ່ລະຫັດຂອງເຈົ້າກ່ອນຈຸດທີ່ໂມດູນ XS ຕົວຈິງ
ພາກສ່ວນເລີ່ມຕົ້ນແລະດັ່ງນັ້ນຈະຖືກປະໄວ້ untouched ໂດຍ xsubpp (cf. perlxs ແລະ perlxstut
ຫນ້າຜູ້ຊາຍ).

ການໂທແບບປົກກະຕິຈະເປັນ

pp_addhdr('
#ລວມທັງ /* ພວກເຮົາຕ້ອງການ defs ຂອງ XXXX */
#include "libprotos.h" /* ຕົ້ນແບບຂອງຟັງຊັນຫ້ອງສະໝຸດ */
#include "mylocaldecs.h" /* Local decs */

static void do_the real_work(PDL_Byte * in, PDL_Byte * out, int n)
{
/* ເຮັດ​ການ​ຄິດ​ໄລ່​ບາງ​ຢ່າງ​ທີ່​ມີ​ຂໍ້​ມູນ */
}
');

ນີ້ຮັບປະກັນວ່າຄົງທີ່ທັງຫມົດແລະຕົວແບບທີ່ທ່ານຕ້ອງການຈະຖືກລວມເຂົ້າຢ່າງຖືກຕ້ອງແລະ
ທີ່ທ່ານສາມາດໃຊ້ຟັງຊັນພາຍໃນທີ່ກຳນົດໄວ້ໃນ "pp_def", ເຊັ່ນ:

pp_def('barfoo',
Pars => 'a(n); [o] b(n)',
ປະເພດທົ່ວໄປ => ['B'],
ລະຫັດ => ' int ns = $SIZE(n);
do_the_real_work($P(a),$P(b),ns);
',
);

pp_addpm

ໃນຫຼາຍໆກໍລະນີ, ລະຫັດ PP ຕົວຈິງ (ຫມາຍຄວາມວ່າການໂຕ້ຖຽງກັບ "pp_def" ໂທ) ແມ່ນພຽງແຕ່ສ່ວນຫນຶ່ງຂອງ
ຊຸດທີ່ທ່ານກໍາລັງປະຕິບັດໃນປັດຈຸບັນ. ມັກຈະມີລະຫັດ Perl ແລະ XS ເພີ່ມເຕີມ
ລະ​ຫັດ​ທີ່​ທ່ານ​ປົກ​ກະ​ຕິ​ຈະ​ໄດ້​ຂຽນ​ເຂົ້າ​ໄປ​ໃນ pm ແລະ XS ໄຟລ​໌​ທີ່​ໃນ​ປັດ​ຈຸ​ບັນ​ອັດ​ຕະ​ໂນ​ມັດ​
ສ້າງຂຶ້ນໂດຍ PP. ດັ່ງນັ້ນວິທີການເອົາສິ່ງດັ່ງກ່າວເຂົ້າໄປໃນໄຟລ໌ທີ່ສ້າງຂຶ້ນແບບໄດນາມິກເຫຼົ່ານັ້ນ?
ໂຊກດີ, ມີສອງສາມຫນ້າທີ່, ໂດຍທົ່ວໄປເອີ້ນວ່າ "pp_addXXX" ທີ່ຊ່ວຍທ່ານ.
ໃນ​ການ​ດໍາ​ເນີນ​ການ​ນີ້​.

ໃຫ້ສົມມຸດວ່າທ່ານມີລະຫັດ Perl ເພີ່ມເຕີມທີ່ຄວນຈະເຂົ້າໄປໃນການສ້າງ pm- ໄຟລ໌. ນີ້
ແມ່ນບັນລຸໄດ້ຢ່າງງ່າຍດາຍດ້ວຍຄໍາສັ່ງ "pp_addpm":

pp_addpm(<<'EOD');

=head1 NAME

PDL::Lib::Mylib -- ການໂຕ້ຕອບ PDL ກັບຫ້ອງສະໝຸດ Mylib

=head1 ລາຍລະອຽດ

ຊຸດນີ້ປະຕິບັດການໂຕ້ຕອບກັບຊຸດ Mylib ຢ່າງເຕັມທີ່
ການສະຫນັບສະຫນູນ threading ແລະດັດສະນີ (ເບິ່ງ L ).

= ຕັດ

ໃຊ້ PGPLOT;

=head2 use_myfunc
ຟັງຊັນນີ້ໃຊ້ການດໍາເນີນງານ myfunc ກັບທັງຫມົດ
ອົງປະກອບຂອງ input pdl ໂດຍບໍ່ຄໍານຶງເຖິງຂະຫນາດ
ແລະສົ່ງຜົນລວມຂອງຜົນໄດ້ຮັບ
= ຕັດ

sub use_myfunc {
$pdl ຂອງຂ້ອຍ = shift;

myfunc($pdl->clump(-1),($res=null));

ກັບຄືນ $res->sum;
}

DOE

pp_add_ສົ່ງອອກ

ທ່ານອາດຈະໄດ້ຮັບຄວາມຄິດ. ໃນບາງກໍລະນີ, ທ່ານຕ້ອງການສົ່ງອອກເພີ່ມເຕີມຂອງທ່ານ
ຫນ້າທີ່. ເພື່ອຫຼີກເວັ້ນການຕົກຢູ່ໃນບັນຫາກັບ PP ທີ່ຍັງສັບສົນກັບ @EXPORT
array ທ່ານພຽງແຕ່ບອກ PP ໃຫ້ເພີ່ມຫນ້າທີ່ຂອງທ່ານເຂົ້າໃນບັນຊີລາຍຊື່ຂອງຫນ້າທີ່ສົ່ງອອກ:

pp_add_exported('use_myfunc gethynx');

pp_add_isa

ຄໍາສັ່ງ "pp_add_isa" ເຮັດວຽກຄືກັບຟັງຊັນ "pp_add_exported". ການໂຕ້ຖຽງກັບ
"pp_add_isa" ຖືກເພີ່ມບັນຊີລາຍຊື່ @ISA, ຕົວຢ່າງ

pp_add_isa('ບາງ::ອື່ນໆ::ຫ້ອງຮຽນ ');

pp_bless

ຖ້າ pp_def routines ຂອງທ່ານຖືກໃຊ້ເປັນວິທີການວັດຖຸໃຊ້ "pp_bless" ເພື່ອລະບຸ.
ຊຸດ (ie class) ທີ່​ທ່ານ pp_defວິທີການ ed ຈະຖືກເພີ່ມ. ຍົກ​ຕົວ​ຢ່າງ,
"pp_bless('PDL::MyClass')". ຄ່າເລີ່ມຕົ້ນແມ່ນ "PDL" ຖ້າອັນນີ້ຖືກລະເວັ້ນ.

pp_addxs

ບາງຄັ້ງທ່ານຕ້ອງການເພີ່ມລະຫັດ XS ຂອງທ່ານເອງ (ໂດຍທົ່ວໄປແລ້ວບໍ່ກ່ຽວຂ້ອງກັບ
ບັນຫາ threading / indexing ໃດໆແຕ່ສະຫນອງບາງຫນ້າທີ່ອື່ນທີ່ທ່ານຕ້ອງການເຂົ້າເຖິງ
ຈາກດ້ານ Perl) ໄປຫາໄຟລ໌ XS ທີ່ສ້າງຂຶ້ນ, ສໍາລັບການຍົກຕົວຢ່າງ

pp_addxs('','

# ກໍານົດ endianness ຂອງເຄື່ອງຈັກ

int
isbigendian()
ລະຫັດ:
unsigned short i;
PDL_Byte *b;

i = 42; b = (PDL_Byte*) (void*) &i;

ຖ້າ (*b == 42)
RETVAL = 0;
ອື່ນຖ້າ (*(b+1) == 42)
RETVAL = 1;
ອື່ນ
croak("Impossible - ເຄື່ອງຈັກບໍ່ແມ່ນ endian ໃຫຍ່ຫຼືນ້ອຍ!!\n");
ຂາອອກ:
RETVAL
');

ໂດຍສະເພາະ "pp_add_exported" ແລະ "pp_addxs" ຄວນຖືກນໍາໃຊ້ຢ່າງລະມັດລະວັງ. PP ໃຊ້
PDL:: ຜູ້ສົ່ງອອກ, ດັ່ງນັ້ນການປ່ອຍໃຫ້ PP ສົ່ງອອກຫນ້າທີ່ຂອງທ່ານຫມາຍຄວາມວ່າພວກເຂົາໄດ້ຮັບການເພີ່ມເຂົ້າໃນ
ບັນຊີລາຍຊື່ມາດຕະຖານຂອງຟັງຊັນທີ່ຖືກສົ່ງອອກໂດຍຄ່າເລີ່ມຕົ້ນ (ບັນຊີລາຍຊື່ທີ່ກໍານົດໂດຍແທັກການສົ່ງອອກ
``:Func''). ຖ້າທ່ານໃຊ້ "pp_addxs" ທ່ານບໍ່ຄວນພະຍາຍາມເຮັດຫຍັງທີ່ກ່ຽວຂ້ອງກັບ threading
ຫຼືດັດສະນີໂດຍກົງ. PP ແມ່ນດີກວ່າຫຼາຍໃນການສ້າງລະຫັດທີ່ເຫມາະສົມຈາກຂອງທ່ານ
ຄໍານິຍາມ.

pp_add_boot

ສຸດທ້າຍ, ທ່ານອາດຈະຕ້ອງການເພີ່ມບາງລະຫັດໃສ່ສ່ວນ BOOT ຂອງໄຟລ໌ XS (ຖ້າທ່ານບໍ່ເຮັດ
ຮູ້ວ່າແມ່ນຫຍັງຄືການກວດສອບ perlxs). ນີ້ແມ່ນເຮັດໄດ້ຢ່າງງ່າຍດາຍດ້ວຍຄໍາສັ່ງ "pp_add_boot":

pp_add_boot(<
descrip = mylib_initialize(KEEP_OPEN);

ຖ້າ (ຄໍາອະທິບາຍ == NULL)
croak("ບໍ່ສາມາດເລີ່ມຕົ້ນຫ້ອງສະໝຸດ");

GlobalStruc->descrip = ອະທິບາຍ;
GlobalStruc->maxfiles = 200;
EOB

pp_export_nothing

ໂດຍຄ່າເລີ່ມຕົ້ນ, PP.pm ວາງຍ່ອຍທັງໝົດທີ່ກຳນົດໄວ້ໂດຍໃຊ້ຟັງຊັນ pp_def ເຂົ້າໃນຜົນໄດ້ຮັບ .pm
ບັນຊີລາຍຊື່ສົ່ງອອກຂອງໄຟລ໌. ນີ້ສາມາດສ້າງບັນຫາຖ້າຫາກວ່າທ່ານກໍາລັງສ້າງວັດຖຸ subclassed ບ່ອນທີ່
ທ່ານບໍ່ຕ້ອງການວິທີການສົ່ງອອກໃດໆ. (ເຊັ່ນ: ວິທີການພຽງແຕ່ຈະຖືກເອີ້ນວ່າການນໍາໃຊ້
$object-> syntax ວິທີການ).

ສໍາລັບກໍລະນີເຫຼົ່ານີ້ທ່ານສາມາດໂທຫາ pp_export_nothing() ເພື່ອລຶບບັນຊີລາຍການສົ່ງອອກ. ຕົວຢ່າງ (ທີ່
ໃນຕອນທ້າຍຂອງໄຟລ໌ .pd):

pp_export_nothing();
pp_done();

pp_core_importList

ໂດຍຄ່າເລີ່ມຕົ້ນ, PP.pm ວາງ 'ໃຊ້ Core;' ເສັ້ນເຂົ້າໄປໃນໄຟລ໌ .pm ຜົນຜະລິດ. ນີ້ນໍາເຂົ້າຂອງ Core
ສົ່ງອອກຊື່ເຂົ້າໄປໃນ namespace ໃນປັດຈຸບັນ, ເຊິ່ງສາມາດສ້າງບັນຫາຖ້າຫາກວ່າທ່ານກໍາລັງ over-
ຂີ່ວິທີການຫນຶ່ງຂອງ Core ໃນໄຟລ໌ປະຈຸບັນ. ທ່ານສິ້ນສຸດການໄດ້ຮັບຂໍ້ຄວາມເຊັ່ນ
"ຄໍາເຕືອນ: sub sumover ກໍານົດຄືນໃຫມ່ໃນໄຟລ໌ subclass.pm" ເມື່ອແລ່ນໂຄງການ.

ສໍາລັບກໍລະນີເຫຼົ່ານີ້, pp_core_importList ສາມາດຖືກນໍາໃຊ້ເພື່ອປ່ຽນສິ່ງທີ່ນໍາເຂົ້າຈາກ
Core.pm. ຍົກ​ຕົວ​ຢ່າງ:

pp_core_importList('()')

ນີ້ຈະສົ່ງຜົນໃຫ້

ໃຊ້ Core();

ຖືກສ້າງຢູ່ໃນໄຟລ໌ .pm ຜົນຜະລິດ. ອັນນີ້ຈະເຮັດໃຫ້ບໍ່ມີຊື່ຖືກນໍາເຂົ້າຈາກ
Core.pm. ເຊັ່ນດຽວກັນ, ໂທຫາ

pp_core_importList('qw/ barf /')

ຈະສົ່ງຜົນໃຫ້

ໃຊ້ Core qw/barf/;

ຖືກສ້າງຢູ່ໃນໄຟລ໌ .pm ຜົນຜະລິດ. ນີ້ຈະສົ່ງຜົນໃຫ້ພຽງແຕ່ 'barf' ຖືກນໍາເຂົ້າ
ຈາກ Core.pm.

pp_setversion

ຂ້ອຍແນ່ໃຈວ່າອັນນີ້ອະນຸຍາດໃຫ້ທ່ານຕັ້ງໄຟລ໌ .pm ແລະ .xs ພ້ອມກັນ.
ສະ​ບັບ​, ດັ່ງ​ນັ້ນ​ການ​ຫຼີກ​ເວັ້ນ​ການ​ສະ​ບັບ​ທີ່​ບໍ່​ຈໍາ​ເປັນ - skew ລະ​ຫວ່າງ​ສອງ​. ການນໍາໃຊ້ນີ້, ພຽງແຕ່ມີ
ແຖວຕໍ່ໄປນີ້ໃນບາງຈຸດໃນໄຟລ໌ .pd ຂອງທ່ານ:

pp_setversion('0.0.3');

ຢ່າງໃດກໍຕາມ, ຢ່າໃຊ້ມັນຖ້າທ່ານໃຊ້ Module::Build::PDL. ເບິ່ງເອກະສານຂອງໂມດູນນັ້ນສໍາລັບ
ລາຍລະອຽດ.

pp_deprecate_module

ຖ້າໂມດູນສະເພາະໃດນຶ່ງຖືກຖືວ່າລ້າສະໄຫມ, ຟັງຊັນນີ້ສາມາດໃຊ້ເພື່ອໝາຍມັນເປັນ
ເຊົາໃຊ້ແລ້ວ. ນີ້ມີຜົນກະທົບຂອງ emitting ເຕືອນໃນເວລາທີ່ຜູ້ໃຊ້ພະຍາຍາມ "ນໍາໃຊ້" ໄດ້
ໂມດູນ. POD ທີ່ສ້າງຂຶ້ນສໍາລັບໂມດູນນີ້ຍັງມີການປະກາດການຍົກເລີກ. ໄດ້
ໂມດູນການທົດແທນສາມາດຜ່ານເປັນການໂຕ້ຖຽງເຊັ່ນນີ້:

pp_deprecate_module( infavor => "PDL::NewNonDeprecatedModule" );

ໃຫ້ສັງເກດວ່າຫນ້າທີ່ມີຜົນກະທົບ ພຽງແຕ່ ການເຕືອນໄພ runtime ແລະ POD.

ການເຮັດໃຫ້ ຂອງ​ທ່ານ PP ຫນ້າທີ່ "ສ່ວນຕົວ"


ໃຫ້ເວົ້າວ່າທ່ານມີຫນ້າທີ່ຢູ່ໃນໂມດູນຂອງທ່ານທີ່ເອີ້ນວ່າ PDL::foo ທີ່ໃຊ້ PP
ຟັງຊັນ "bar_pp" ເພື່ອເຮັດການຍົກຫນັກ. ແຕ່ເຈົ້າບໍ່ຢາກໂຄສະນາວ່າ "bar_pp"
ມີຢູ່. ເພື່ອເຮັດສິ່ງນີ້, ທ່ານຕ້ອງຍ້າຍຫນ້າທີ່ PP ຂອງທ່ານໄປຢູ່ເທິງສຸດຂອງໄຟລ໌ໂມດູນຂອງທ່ານ, ຫຼັງຈາກນັ້ນ
ໂທ

pp_export_nothing()

ເພື່ອລຶບລາຍຊື່ "ສົ່ງອອກ". ເພື່ອຮັບປະກັນວ່າບໍ່ມີເອກະສານ (ເຖິງແມ່ນວ່າເອກະສານ PP ເລີ່ມຕົ້ນ) ແມ່ນ
ສ້າງ, ຕັ້ງ

Doc => undef

ແລະເພື່ອປ້ອງກັນບໍ່ໃຫ້ຟັງຊັນຈາກການຖືກເພີ່ມໃສ່ຕາຕະລາງສັນຍາລັກ, ຕັ້ງຄ່າ

PMFunc => ''

ໃນການປະກາດ pp_def ຂອງທ່ານ (ເບິ່ງ Image2D.pd ສໍາລັບຕົວຢ່າງ). ນີ້​ປະ​ສິດ​ທິ​ຜົນ​ຈະ​ເຮັດ​ໃຫ້​
ຟັງຊັນ PP ຂອງທ່ານ "ສ່ວນຕົວ." ຢ່າງໃດກໍຕາມ, ມັນແມ່ນ ສະເຫມີໄປ ເຂົ້າເຖິງໄດ້ຜ່ານ PDL::bar_pp ເນື່ອງຈາກ Perl's
ການອອກແບບໂມດູນ. ແຕ່ການເຮັດໃຫ້ມັນເປັນສ່ວນຕົວຈະເຮັດໃຫ້ຜູ້ໃຊ້ໄປໄກຈາກລາວຫຼາຍ
ວິທີການນໍາໃຊ້ມັນ, ດັ່ງນັ້ນເຂົາຫຼືນາງ shoulders ຜົນສະທ້ອນ!

ຫຼັງຈາກນັ້ນນໍາ ປະຕິບັດງານ


ພາກສ່ວນການເຮັດວຽກຂອງຄູ່ມືນີ້ແມ່ນສະໜອງໃຫ້ໂດຍໃຊ້ dataflow ແລະ lazy evaluation:
ເມື່ອທ່ານຕ້ອງການ, ຂໍໃຫ້ Tjl ຂຽນມັນ. ການຈັດສົ່ງໃນຫນຶ່ງອາທິດຈາກເວລາທີ່ຂ້ອຍໄດ້ຮັບອີເມວ
ເປັນໄປໄດ້ 95% ແລະການຈັດສົ່ງສອງອາທິດແມ່ນ 99% ເປັນໄປໄດ້.

ແລະຢ່າງໃດກໍ່ຕາມ, ການດໍາເນີນງານຂອງຕ່ອນຕ້ອງການຄວາມຮູ້ທີ່ໃກ້ຊິດຫຼາຍຂອງ PDL ພາຍໃນ
ກ​່​ວາ​ການ​ດໍາ​ເນີນ​ງານ​ຂໍ້​ມູນ​. ຍິ່ງໄປກວ່ານັ້ນ, ຄວາມສັບສົນຂອງບັນຫາທີ່ກ່ຽວຂ້ອງແມ່ນ
ສູງກ່ວານັ້ນຢ່າງຫຼວງຫຼາຍໃນການດໍາເນີນງານຂໍ້ມູນສະເລ່ຍ. ຖ້າເຈົ້າຢາກຊັກຊວນ
ຕົວ ທ່ານ ເອງ ຂອງ ຄວາມ ເປັນ ຈິງ ນີ້ ເບິ່ງ ຢູ່ ໃນ ພື້ນຖານ/Slices/slices.pd ໄຟລ໌ໃນ PDL
ການ​ແຜ່​ກະ​ຈາຍ :-). ຢ່າງ​ໃດ​ກໍ​ຕາມ, functions generated using the slice operations are at the
ຫົວ​ໃຈ​ຂອງ​ການ​ຈັດ​ການ​ດັດ​ຊະ​ນີ​ແລະ​ຄວາມ​ສາ​ມາດ​ຂະ​ບວນ​ການ​ຂໍ້​ມູນ​ຂອງ PDL​.

ນອກຈາກນີ້, ມີຫຼາຍບັນຫາເປື້ອນກັບ piddles virtual ແລະ vaffines ທີ່ພວກເຮົາຈະ
ຂ້າມທັງຫມົດຢູ່ທີ່ນີ້.

ແຜ່ນນ້ອຍໆ ແລະ ບໍ່ດີ ຄ່າ
ການດໍາເນີນງານ Slice ຈໍາເປັນຕ້ອງສາມາດຈັດການກັບຄ່າທີ່ບໍ່ດີ (ຖ້າການສະຫນັບສະຫນູນຖືກລວບລວມເຂົ້າໄປໃນ PDL).
ສິ່ງທີ່ງ່າຍທີ່ສຸດທີ່ຈະເຮັດແມ່ນເບິ່ງ ພື້ນຖານ/Slices/slices.pd ເພື່ອເບິ່ງວິທີການນີ້ເຮັດວຽກ.

ຄຽງຄູ່ກັບ "BadCode", ຍັງມີປຸ່ມ "BadBackCode" ແລະ "BadRedoDimsCode" ສໍາລັບ.
"pp_def". ຢ່າງໃດກໍ່ຕາມ, "EquivCPOffsCode" ຄວນ ບໍ່ ຕ້ອງ​ການ​ປ່ຽນ​ແປງ​, ເນື່ອງ​ຈາກ​ວ່າ​ການ​ປ່ຽນ​ແປງ​ໃດໆ​
ດູດຊຶມເຂົ້າໄປໃນຄໍານິຍາມຂອງມະຫາພາກ "$EQUIVCPOFFS()" (ເຊັ່ນວ່າມັນຖືກຈັດການ
ອັດຕະໂນມັດໂດຍ PDL::PP>.

A ສອງສາມ ອ່ືນ on ລາຍລັກອັກສອນ a ການຕັດ ປົກກະຕິ...
ສອງສາມວັກຕໍ່ໄປນີ້ອະທິບາຍການຂຽນແບບປົກກະຕິຂອງການຕັດໃໝ່ ('ໄລຍະ'); ໃດ
ຂໍ້ຜິດພາດແມ່ນ CED. (--CED 26-Aug-2002)

ການຈັດການ of "ເຕືອນ" ແລະ "barf" in PP ລະຫັດ


ສໍາລັບການພິມຂໍ້ຄວາມເຕືອນຫຼືການເອົາລູກອອກ / ການເສຍຊີວິດ, ທ່ານສາມາດໂທຫາ "ເຕືອນ" ຫຼື "barf" ຈາກ PP.
ລະຫັດ. ຢ່າງໃດກໍ່ຕາມ, ທ່ານຄວນຮູ້ວ່າການໂທເຫຼົ່ານີ້ໄດ້ຖືກກໍານົດຄືນໃຫມ່ໂດຍໃຊ້ C
preprocessor macro ກັບ "PDL->barf" ແລະ "PDL->warn". ຄໍານິຍາມໃຫມ່ເຫຼົ່ານີ້ແມ່ນຢູ່ໃນສະຖານທີ່
ບໍ່ໃຫ້ເຈົ້າໂທຫາ "ເຕືອນ" ຫຼື "barf" ຂອງ perl ໂດຍບໍ່ໄດ້ຕັ້ງໃຈ, ເຊິ່ງສາມາດເຮັດໃຫ້ເກີດ
segfaults ໃນລະຫວ່າງການ pthreading (ie processor multi-threading).

ສະບັບຂອງ PDL ຂອງຕົນເອງຂອງ "barf" ແລະ "warn" ຈະຈັດຄິວເຕືອນຫຼືຂໍ້ຄວາມ barf ຈົນກ່ວາຫຼັງຈາກນັ້ນ.
pthreading ແມ່ນສໍາເລັດ, ແລະຫຼັງຈາກນັ້ນໂທຫາສະບັບ perl ຂອງປົກກະຕິເຫຼົ່ານີ້.

ເບິ່ງ PDL::ParallelCPU ສໍາລັບຂໍ້ມູນເພີ່ມເຕີມກ່ຽວກັບ pthreading.

ການ ນຳ ໃຊ້ ປົກກະຕິ


ໂຄງສ້າງ PDL "ຫຼັກ", ກໍານົດໃນ ພື້ນຖານ/Core/pdlcore.h.PL, ມີຕົວຊີ້ໄປຫາ a
ຈໍານວນຂອງກິດຈະວັດທີ່ອາດຈະເປັນປະໂຫຍດສໍາລັບທ່ານ. ສ່ວນໃຫຍ່ຂອງການປົກກະຕິເຫຼົ່ານີ້ຈັດການກັບ
manipulating piddles, ແຕ່ບາງອັນແມ່ນທົ່ວໄປກວ່າ:

PDL->qsort_B( PDL_Byte *xx, int a, int b )
ຈັດຮຽງອາເຣ "xx" ລະຫວ່າງດັດຊະນີ "a" ແລະ "b". ນອກຈາກນີ້ຍັງມີສະບັບສໍາລັບ
ປະເພດຂໍ້ມູນ PDL ອື່ນໆ, ທີ່ມີ postfix "_S", "_U", "_L", "_F", ແລະ "_D". ໂມດູນໃດທີ່ໃຊ້
ອັນນີ້ຕ້ອງຮັບປະກັນວ່າ "PDL::Ufunc" ຖືກໂຫລດ.

PDL->qsort_ind_B( PDL_Byte *xx, int *ix, int a, int b )
ສໍາລັບ "PDL->qsort_B", ແຕ່ເວລານີ້ຈັດຮຽງດັດສະນີແທນທີ່ຈະເປັນຂໍ້ມູນ.

ປົກກະຕິ "med2d" ໃນ Lib/Image2D/image2d.pd ສະແດງໃຫ້ເຫັນວິທີການປົກກະຕິດັ່ງກ່າວຖືກນໍາໃຊ້.

ເອກະສານ FOR PP ເອກະສານ


ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ຈະ​ສ້າງ​ຊຸດ​ຈາກ​ໄຟລ​໌ PP ຂອງ​ທ່ານ (ການ​ຂະ​ຫຍາຍ​ໄຟລ​໌​ປົກ​ກະ​ຕິ​ແມ່ນ​
".pd" ຫຼື ".pp" ສໍາລັບໄຟລ໌ທີ່ມີລະຫັດ PP) ມັນງ່າຍທີ່ສຸດ ແລະປອດໄພທີ່ສຸດທີ່ຈະອອກ.
ການສ້າງຄໍາສັ່ງທີ່ເຫມາະສົມກັບ Makefile. ໃນຕໍ່ໄປນີ້ພວກເຮົາຈະອະທິບາຍ
ຮູບແບບປົກກະຕິຂອງ Perl Makefile ທີ່ຈະສ້າງແລະຕິດຕັ້ງຊຸດຂອງທ່ານໂດຍອັດຕະໂນມັດ
ລາຍລະອຽດໃນໄຟລ໌ PP. ສ່ວນໃຫຍ່ຂອງກົດລະບຽບການກໍ່ສ້າງ xs, pm ແລະໄຟລ໌ທີ່ຕ້ອງການອື່ນໆ
ຈາກໄຟລ໌ PP ແມ່ນຖືກກໍານົດໄວ້ກ່ອນແລ້ວໃນ PDL::Core::ຊຸດ Dev. ພວກເຮົາພຽງແຕ່ຕ້ອງ
ບອກ MakeMaker ໃຫ້ໃຊ້ມັນ.

ໃນກໍລະນີຫຼາຍທີ່ສຸດ, ທ່ານສາມາດກໍານົດ Makefile ຂອງທ່ານເຊັ່ນ

# Makefile.PL ສໍາລັບຊຸດທີ່ກໍານົດໄວ້ໂດຍລະຫັດ PP.

ໃຊ້ PDL::Core::Dev; # ຮັບພັດທະນາລະບົບສາທາລະນູປະໂພກ
ໃຊ້ ExtUtils::MakeMaker;

$package = ["mylib.pd",Mylib,PDL::Lib::Mylib];
%hash = pdlpp_stdargs($package);
$hash{OBJECT} .= ' ເພີ່ມເຕີມ_Ccode$(OBJ_EXT) ' ;
$hash{clean}->{FILES} .= ' todelete_Ccode$(OBJ_EXT) ' ;
$hash{'VERSION_FROM'} = 'mylib.pd';
WriteMakefile(%hash);

sub MY::postamble { pdlpp_postamble($package); }

ທີ່ນີ້, ບັນຊີລາຍຊື່ໃນ $package ແມ່ນ: ທໍາອິດ: ຊື່ໄຟລ໌ແຫຼ່ງ PP, ຫຼັງຈາກນັ້ນຄໍານໍາຫນ້າສໍາລັບ
ໄຟລ໌ທີ່ຜະລິດແລະສຸດທ້າຍແມ່ນຊື່ຊຸດທັງຫມົດ. ທ່ານສາມາດດັດແປງ hash ໃນອັນໃດກໍ່ຕາມ
ວິທີທີ່ທ່ານຕ້ອງການແຕ່ມັນຈະສົມເຫດສົມຜົນທີ່ຈະຢູ່ໃນຂອບເຂດຈໍາກັດບາງຢ່າງເພື່ອໃຫ້ຊຸດຂອງທ່ານ
ຈະສືບຕໍ່ເຮັດວຽກກັບ PDL ຮຸ່ນຕໍ່ມາ.

ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ບໍ່​ຕ້ອງ​ການ​ທີ່​ຈະ​ນໍາ​ໃຊ້​ການ​ໂຕ້​ຖຽງ prepackaged​, ນີ້​ແມ່ນ​ທົ່ວ​ໄປ​ Makefile.PL ທີ່ທ່ານສາມາດເຮັດໄດ້
ປັບ​ໃຫ້​ເຫມາະ​ສົມ​ກັບ​ຄວາມ​ຕ້ອງ​ການ​ຂອງ​ທ່ານ​ເອງ​:

# Makefile.PL ສໍາລັບຊຸດທີ່ກໍານົດໄວ້ໂດຍລະຫັດ PP.

ໃຊ້ PDL::Core::Dev; # ຮັບພັດທະນາລະບົບສາທາລະນູປະໂພກ
ໃຊ້ ExtUtils::MakeMaker;

WriteMakefile(
'NAME' => 'PDL::Lib::Mylib',
'VERSION_FROM' => 'mylib.pd',
'TYPEMAPS' => [&PDL_TYPEMAP()],
'OBJECT' => 'mylib$(OBJ_EXT) additional_Ccode$(OBJ_EXT)',
'PM' => { 'Mylib.pm' => '$(INST_LIBDIR)/Mylib.pm'},
'INC' => &PDL_INCLUDE(), # add include dirs ຕາມຄວາມຕ້ອງການຂອງ lib ຂອງທ່ານ
'LIBS' => [''], # ເພີ່ມເສັ້ນທາງເຊື່ອມຕໍ່ຕາມຄວາມຈໍາເປັນ
'ສະອາດ' => {'FILES' =>
'Mylib.pm Mylib.xs Mylib$(OBJ_EXT)
additional_Ccode$(OBJ_EXT)'},
);

# ເພີ່ມກົດລະບຽບ genpp; ນີ້ຈະເອີ້ນ PDL::PP ໃນໄຟລ໌ PP ຂອງພວກເຮົາ
# argument ແມ່ນການອ້າງອິງ array ທີ່ array ມີສາມອົງປະກອບ string:
# arg1: ຊື່ຂອງໄຟລ໌ແຫຼ່ງທີ່ປະກອບດ້ວຍລະຫັດ PP
# arg2: ຊື່ພື້ນຖານຂອງໄຟລ໌ xs ແລະ pm ທີ່ຈະສ້າງຂຶ້ນ
# arg3: ຊື່ຂອງແພັກເກດທີ່ຈະຖືກສ້າງຂຶ້ນ
sub MY::postamble { pdlpp_postamble(["mylib.pd",Mylib,PDL::Lib::Mylib]); }

ເພື່ອເຮັດໃຫ້ຊີວິດງ່າຍຂຶ້ນ PDL::Core::Dev ກໍານົດຟັງຊັນ "pdlpp_stdargs" ທີ່ກັບຄືນມາ
hash ທີ່ມີຄ່າເລີ່ມຕົ້ນທີ່ສາມາດຜ່ານໄດ້ (ໂດຍກົງຫຼືຫຼັງຈາກທີ່ເຫມາະສົມ
modification) ໂທຫາ WriteMakefile. ໃນປັດຈຸບັນ, "pdlpp_stdargs" ກັບຄືນ hash ບ່ອນທີ່
ກະແຈຖືກຕື່ມໃສ່ດັ່ງນີ້:

(
'NAME' => $mod,
'TYPEMAPS' => [&PDL_TYPEMAP()],
'OBJECT' => "$pref\$(OBJ_EXT)",
PM => {"$pref.pm" => "\$(INST_LIBDIR)/$pref.pm"},
MAN3PODS => {"$src" => "\$(INST_MAN3DIR)/$mod.\$(MAN3EXT)"},
'INC' => &PDL_INCLUDE(),
'LIBS' => [''],
'ສະອາດ' => {'FILES' => "$pref.xs $pref.pm $pref\$(OBJ_EXT)"},
)

ທີ່ນີ້, $src ແມ່ນຊື່ຂອງໄຟລ໌ແຫຼ່ງທີ່ມີລະຫັດ PP, $pref ຄໍານໍາຫນ້າສໍາລັບການສ້າງ.
ໄຟລ໌ .pm ແລະ .xs ແລະ $mod ຊື່ຂອງໂມດູນການຂະຫຍາຍເພື່ອສ້າງ.

ພາຍໃນ


ພາຍໃນຂອງສະບັບປະຈຸບັນປະກອບດ້ວຍຕາຕະລາງຂະຫນາດໃຫຍ່ທີ່ໃຫ້ກົດລະບຽບ
ອີງຕາມສິ່ງທີ່ຖືກແປແລະ subs ທີ່ປະຕິບັດກົດລະບຽບເຫຼົ່ານີ້.

ຕໍ່ມາ, ມັນຈະເປັນການດີທີ່ຈະເຮັດໃຫ້ຕາຕະລາງສາມາດດັດແປງໄດ້ໂດຍຜູ້ໃຊ້ເພື່ອໃຫ້ແຕກຕ່າງກັນ
ສິ່ງທີ່ອາດຈະຖືກພະຍາຍາມ.

[ຄໍາຄິດເຫັນ Meta: ໃນທີ່ນີ້ຫວັງວ່າຈະມີຫຼາຍຂຶ້ນໃນອະນາຄົດ; ໃນປັດຈຸບັນ, ການເດີມພັນທີ່ດີທີ່ສຸດຂອງທ່ານຈະເປັນ
ເພື່ອອ່ານລະຫັດແຫຼ່ງ :-( ຫຼືຖາມໃນລາຍການ (ລອງໃຊ້ອັນສຸດທ້າຍກ່ອນ) ]

ເອກະສານຊ້ອນ A: ບາງ ໃຊ້ ຮັບຮູ້ by PDL::PP


ເວັ້ນເສຍແຕ່ໄດ້ລະບຸໄວ້ເປັນຢ່າງອື່ນ, ອາກິວເມັນແມ່ນສະຕຣິງ. ກະແຈທີ່ໝາຍດ້ວຍ (ບໍ່ດີ) ແມ່ນເທົ່ານັ້ນ
ໃຊ້ຖ້າການສະຫນັບສະຫນູນມູນຄ່າທີ່ບໍ່ດີຖືກລວບລວມເຂົ້າໄປໃນ PDL.

Pars
ກໍານົດລາຍເຊັນຂອງຫນ້າທີ່ຂອງທ່ານ

OtherPars
ການໂຕ້ຖຽງທີ່ບໍ່ແມ່ນ pdls. ຄ່າເລີ່ມຕົ້ນ: ບໍ່ມີຫຍັງ. ນີ້ແມ່ນລາຍຊື່ເຄິ່ງຈໍ້າສອງເມັດທີ່ແຍກອອກ
arguments, ຕົວຢ່າງ, "OtherPars=>'int k; double value; char* fd'". ເບິ່ງ $COMP(x) ແລະ
ເຂົ້າດຽວກັນໃນເອກະສານຊ້ອນທ້າຍ B.

ລະຫັດ
ລະຫັດຕົວຈິງທີ່ປະຕິບັດຫນ້າທີ່; ຫຼາຍ PP macro ແລະຟັງຊັນ PP
ຖືກຮັບຮູ້ໃນຄ່າສະຕຣິງ

HandleBad (ບໍ່ດີ)
ຖ້າຕັ້ງເປັນ 1, ປົກກະຕິແມ່ນຖືວ່າຮອງຮັບຄ່າທີ່ບໍ່ດີ ແລະລະຫັດໃນ BadCode.
key ຖືກໃຊ້ຖ້າມີຄ່າທີ່ບໍ່ດີ; ມັນຍັງຕັ້ງສິ່ງຕ່າງໆເພື່ອໃຫ້ "$ISBAD()"
ສາມາດນຳໃຊ້ macro ແລະ ອື່ນໆ. ຖ້າຕັ້ງເປັນ 0, ເຮັດໃຫ້ປົກກະຕິພິມຄໍາເຕືອນຖ້າມີ
input piddles ມີທຸງທີ່ບໍ່ດີຂອງເຂົາເຈົ້າກໍານົດ.

BadCode (ບໍ່ດີ)
ໃຫ້ລະຫັດທີ່ຈະໃຊ້ຖ້າຄ່າທີ່ບໍ່ດີອາດຈະຢູ່ໃນ piddles ການປ້ອນຂໍ້ມູນ. ໃຊ້ເທົ່ານັ້ນ
ຖ້າ "HandleBad => 1".

ປະເພດທົ່ວໄປ
ການອ້າງອິງ array. array ອາດມີຊຸດຍ່ອຍຂອງສະຕຣິງໜຶ່ງຕົວອັກສອນ `B',
`S', `U', `L', `Q', `F' ແລະ `D', ເຊິ່ງລະບຸປະເພດຂອງການດໍາເນີນການຂອງທ່ານຈະຍອມຮັບ.
ຄວາມ​ຫມາຍ​ຂອງ​ແຕ່​ລະ​ປະ​ເພດ​ແມ່ນ​:

B - signed byte (ie signed char)
S - ເຊັນສັ້ນ (ຈຳນວນເຕັມສອງໄບຕ໌)
U - unsigned ສັ້ນ
L - ເຊັນຊື່ຍາວ (ຈຳນວນເຕັມສີ່ໄບ, int ໃນລະບົບ 32 ບິດ)
Q - ເຊັນຊື່ long long (ແປດ byte integer)
F - ລອຍ
D - ສອງເທົ່າ

ນີ້ແມ່ນເປັນປະໂຫຍດຫຼາຍ (ແລະສໍາຄັນ!) ເມື່ອຕິດຕໍ່ກັບຫ້ອງສະຫມຸດພາຍນອກ. ຄ່າເລີ່ມຕົ້ນ:
[qw/BSULQFD/]

ໃນ​ສະ​ຖານ​ທີ່
ໝາຍຟັງຊັນວ່າສາມາດເຮັດວຽກແທນໄດ້.

Inplace => 1 ຖ້າ Pars => 'a(); [o]b();'
Inplace => ['a'] ຖ້າ Pars => 'a(); b(); [o]c();'
Inplace => ['a','b'] ຖ້າ Pars => 'a(); b(); [o]c(); [o]d();'

ຖ້າມີການໃຊ້ຄຸນຄ່າທີ່ບໍ່ດີ, ຕ້ອງໄດ້ຮັບການດູແລເພື່ອຮັບປະກັນການຂະຫຍາຍພັນຂອງພືດ
badflag ໃນເວລາທີ່ inplace ຖືກນໍາໃຊ້; ຕົວຢ່າງເບິ່ງລະຫັດສໍາລັບ "replacebad" ໃນ
ພື້ນຖານ/ບໍ່ດີ/bad.pd.

Doc ໃຊ້ເພື່ອລະບຸສະຕຣິງເອກະສານໃນຮູບແບບ Pod. ເບິ່ງ PDL::Doc ສໍາລັບຂໍ້ມູນກ່ຽວກັບ
ສົນທິສັນຍາເອກະສານ PDL. ຫມາຍເຫດ: ໃນກໍລະນີພິເສດທີ່ PP 'Doc' string ແມ່ນ
ແຖວໜຶ່ງອັນນີ້ຖືກໃຊ້ໂດຍຫຍໍ້ສຳລັບການອ້າງອີງໄວ ແລະເອກະສານ!

ຖ້າຊ່ອງຂໍ້ມູນ Doc ຖືກລະເວັ້ນ PP ຈະສ້າງເອກະສານເລີ່ມຕົ້ນ (ຫຼັງຈາກທັງຫມົດມັນຮູ້
ກ່ຽວກັບລາຍເຊັນ).

ຖ້າເຈົ້າຕ້ອງການໃຫ້ຟັງຊັນບໍ່ຖືກບັນທຶກໄວ້ໃນທຸກທາງໃນຈຸດນີ້ (ຕົວຢ່າງ
ສໍາລັບການປົກກະຕິພາຍໃນ, ຫຼືຍ້ອນວ່າທ່ານກໍາລັງເຮັດມັນຢູ່ບ່ອນອື່ນໃນລະຫັດ) ຢ່າງຊັດເຈນ
ລະບຸ "Doc=>undef".

BadDoc (ບໍ່ດີ)
ປະກອບມີຂໍ້ຄວາມທີ່ສົ່ງຄືນໂດຍຄໍາສັ່ງ "badinfo" (ໃນ "perldl") ຫຼືປຸ່ມ "-b"
ກັບ "pdldoc" script shell. ໃນຫຼາຍໆກໍລະນີ, ທ່ານຈະບໍ່ຈໍາເປັນຕ້ອງລະບຸນີ້, ນັບຕັ້ງແຕ່
ຂໍ້ມູນສາມາດຖືກສ້າງຂື້ນໂດຍອັດຕະໂນມັດໂດຍ PDL::PP. ຢ່າງໃດກໍຕາມ, ຕາມທີ່ເຫມາະສົມສໍາລັບຄອມພິວເຕີ,
ຂໍ້ຄວາມທີ່ສ້າງຂຶ້ນ, ມັນເປັນ stilted ແທນທີ່ຈະ; ມັນອາດຈະດີກວ່າທີ່ຈະເຮັດມັນເອງ!

NoPthread
ທຸງທາງເລືອກເພື່ອຊີ້ບອກຟັງຊັນ PDL ຄວນ ບໍ່ ໃຊ້ກະທູ້ຂອງໂປເຊດເຊີ (ie
pthreads ຫຼື POSIX threads) ເພື່ອແບ່ງປັນການເຮັດວຽກໃນທົ່ວ CPU ຫຼາຍແກນ. ທາງເລືອກນີ້ແມ່ນ
ໂດຍປົກກະຕິຈະຕັ້ງເປັນ 1 ຖ້າຟັງຊັນ PDL ພື້ນຖານບໍ່ປອດໄພກະທູ້. ຖ້າທາງເລືອກນີ້
ບໍ່ມີຢູ່, ຈາກນັ້ນຟັງຊັນແມ່ນຖືວ່າປອດໄພ. ຕົວເລືອກນີ້ນຳໃຊ້ເທົ່ານັ້ນ
ຖ້າ PDL ໄດ້ຖືກລວບລວມດ້ວຍກະທູ້ POSIX ຖືກເປີດໃຊ້.

PMCode
ຟັງຊັນ PDL ອະນຸຍາດໃຫ້ທ່ານຜ່ານເຂົ້າໄປໃນ piddle ທີ່ທ່ານຕ້ອງການຜົນຜະລິດທີ່ບັນທຶກໄວ້. ນີ້
ແມ່ນ handy ເພາະວ່າທ່ານສາມາດຈັດສັນ piddle ຜົນຜະລິດຫນຶ່ງຄັ້ງແລະ reuse ຫຼາຍຄັ້ງ; ໄດ້
ທາງເລືອກແມ່ນສໍາລັບ PDL ເພື່ອສ້າງ piddle ໃຫມ່ໃນແຕ່ລະຄັ້ງ, ເຊິ່ງອາດຈະເສຍຄ່າຄອມພິວເຕີ້
ຮອບວຽນຫຼື, ອາດຈະຫຼາຍ, RAM. ຄວາມຍືດຫຍຸ່ນທີ່ເພີ່ມນີ້ມາໃນຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມ
ຄວາມຊັບຊ້ອນ: PDL::PP ຕ້ອງຂຽນຟັງຊັນທີ່ສະຫຼາດພໍທີ່ຈະນັບໄດ້
ການໂຕ້ຖຽງຜ່ານໄປຫາມັນແລະສ້າງ piddles ໃຫມ່ໃນການບິນ, ແຕ່ວ່າພຽງແຕ່ຖ້າຫາກວ່າທ່ານຕ້ອງການໃຫ້ເຂົາເຈົ້າ.

PDL::PP ແມ່ນ smart ພຽງພໍທີ່ຈະເຮັດແນວນັ້ນ, ແຕ່ມີຂໍ້ຈໍາກັດກ່ຽວກັບຄໍາສັ່ງໂຕ້ຖຽງແລະ
ຄ້າຍຄືກັນ. ຖ້າທ່ານຕ້ອງການຟັງຊັນທີ່ມີຄວາມຍືດຫຍຸ່ນຫຼາຍ, ທ່ານສາມາດຂຽນ Perl-side ຂອງທ່ານເອງ
wrapper ແລະລະບຸມັນຢູ່ໃນລະຫັດ PMCode. ສາຍ​ທີ່​ທ່ານ​ສະ​ຫນອງ​ໃຫ້​ຕ້ອງ (ຄວນ​)
ກໍານົດຟັງຊັນ Perl ທີ່ມີຊື່ທີ່ກົງກັບສິ່ງທີ່ທ່ານໃຫ້ pp_def ໃນຄັ້ງທໍາອິດ
ສະຖານທີ່. ເມື່ອເຈົ້າຕ້ອງການເອີ້ນຟັງຊັນທີ່ສ້າງ PP ໃນທີ່ສຸດ, ເຈົ້າຈະຕ້ອງໃຊ້
ສະຫນອງ piddles ທັງຫມົດໃນຄໍາສັ່ງທີ່ແນ່ນອນທີ່ລະບຸໄວ້ໃນລາຍເຊັນ: piddles ຜົນຜະລິດແມ່ນ
ບໍ່ແມ່ນທາງເລືອກ, ແລະຟັງຊັນທີ່ສ້າງ PP ຈະບໍ່ສົ່ງຄືນຫຍັງ. ສັບສົນ
ຊື່ທີ່ເຈົ້າຈະເອີ້ນແມ່ນ _ _int.

ຂ້າ​ພະ​ເຈົ້າ​ເຊື່ອ​ວ່າ​ເອ​ກະ​ສານ​ນີ້​ຕ້ອງ​ການ​ຄວາມ​ກະ​ຈ່າງ​ແຈ້ງ​ເພີ່ມ​ເຕີມ, ແຕ່​ນີ້​ຈະ​ຕ້ອງ​ເຮັດ.
🇧🇷

PMFunc
ເມື່ອ pp_def ສ້າງຟັງຊັນ, ມັນມັກຈະກໍານົດພວກມັນຢູ່ໃນຊຸດ PDL. ຈາກນັ້ນ,
ໃນໄຟລ໌ .pm ທີ່ມັນສ້າງສໍາລັບໂມດູນຂອງທ່ານ, ປົກກະຕິແລ້ວມັນຈະເພີ່ມແຖວນັ້ນ
ໂດຍ​ສະ​ເພາະ​ແມ່ນ​ສໍາ​ເນົາ​ທີ່​ເຮັດ​ວຽກ​ໃນ​ຕາ​ຕະ​ລາງ​ສັນ​ຍາ​ລັກ​ຂອງ​ຊຸດ​ປັດ​ຈຸ​ບັນ​ຂອງ​ທ່ານ​ທີ່​ມີ​ລະ​ຫັດ​
ເບິ່ງຄືວ່ານີ້:

*func_name = \&PDL::func_name;

ມັນເປັນເລັກນ້ອຍທີ່ສະຫລາດກວ່ານັ້ນ (ມັນຮູ້ວ່າເວລາທີ່ຈະຫໍ່ສິ່ງດັ່ງກ່າວໃນ a
BEGIN block, ສໍາລັບການຍົກຕົວຢ່າງ, ແລະຖ້າຫາກວ່າທ່ານກໍານົດບາງສິ່ງບາງຢ່າງທີ່ແຕກຕ່າງກັນສໍາລັບ pp_bless), ແຕ່
ນັ້ນແມ່ນຈຸດສໍາຄັນຂອງມັນ. ຖ້າທ່ານບໍ່ສົນໃຈທີ່ຈະນໍາເຂົ້າຟັງຊັນເຂົ້າໄປໃນປະຈຸບັນຂອງທ່ານ
ຕາຕະລາງສັນຍາລັກຂອງຊຸດ, ທ່ານສາມາດກໍານົດ

PMFunc => '',

PMFunc ບໍ່ມີຜົນຂ້າງຄຽງອື່ນໆ, ດັ່ງນັ້ນທ່ານສາມາດນໍາໃຊ້ມັນເພື່ອໃສ່ລະຫັດ Perl ດ້ວຍຕົນເອງ.
ເຂົ້າໄປໃນໂມດູນຂອງເຈົ້າຖ້າທ່ານຕ້ອງການ. ຢ່າງໃດກໍຕາມ, ທ່ານຄວນໃຊ້ pp_addpm ຖ້າທ່ານຕ້ອງການເພີ່ມ Perl
ລະ​ຫັດ​ກັບ​ໂມ​ດູນ​ຂອງ​ທ່ານ​.

ເອກະສານຊ້ອນ B: PP ມະຫາພາກ ແລະ ຫນ້າທີ່


ມາໂຄຣ
Macros ທີ່ຕິດສະຫຼາກໂດຍ (ບໍ່ດີ) ຖືກນໍາໃຊ້ພຽງແຕ່ຖ້າການສະຫນັບສະຫນູນມູນຄ່າທີ່ບໍ່ດີຖືກລວບລວມເຂົ້າໄປໃນ PDL.

$variablename_from_sig()
ເຂົ້າເຖິງ pdl (ໂດຍຊື່ຂອງມັນ) ທີ່ລະບຸໄວ້ໃນລາຍເຊັນ

$COMP(x)
ເຂົ້າເຖິງຄ່າໃນໂຄງສ້າງຂໍ້ມູນສ່ວນຕົວຂອງການຫັນປ່ຽນນີ້ (ສ່ວນຫຼາຍແມ່ນໃຊ້ເພື່ອ
ໃຊ້ການໂຕ້ຖຽງທີ່ລະບຸໄວ້ໃນພາກ "OtherPars")

$SIZE(n)
ແທນທີ່ເວລາແລ່ນດ້ວຍຂະໜາດຕົວຈິງຂອງ a ຊື່ວ່າ ຂະຫນາດ (ຕາມທີ່ລະບຸໄວ້ໃນ
ລາຍເຊັນ)

$ທົ່ວໄປ()
ແທນທີ່ດ້ວຍປະເພດ C ທີ່ເທົ່າກັບປະເພດ runtime ຂອງການດໍາເນີນງານ

$P(a) ຕົວຊີ້ເຂົ້າຫາ PDL ທີ່ມີຊື່ວ່າ "a" ໃນລາຍເຊັນ. ເປັນປະໂຫຍດສໍາລັບການຕິດຕໍ່ກັບ C
ຫນ້າທີ່

$PP(a) ຕົວຊີ້ທາງກາຍະພາບເຂົ້າເຖິງ pdl "a"; ສ່ວນໃຫຍ່ສໍາລັບການນໍາໃຊ້ພາຍໃນ

$TXXX(ທາງເລືອກ,ທາງເລືອກ)
ທາງເລືອກການຂະຫຍາຍຕາມປະເພດຂອງການດໍາເນີນງານ, ບ່ອນທີ່ XXX ແມ່ນບາງອັນ
ສະຕຣິງທີ່ຖືກຈັບຄູ່ໂດຍ "/[BSULFD+]/".

$PDL(a)
ສົ່ງຕົວຊີ້ໄປຫາໂຄງສ້າງຂໍ້ມູນ pdl (pdl *) ຂອງ piddle "a"

$ISBAD(a()) (ບໍ່ດີ)
ໃຫ້ຜົນເປັນຈິງຖ້າຄ່າທີ່ເກັບໄວ້ໃນ "a()" ເທົ່າກັບຄ່າທີ່ບໍ່ດີຂອງ piddle ນີ້.
ຮຽກຮ້ອງໃຫ້ "HandleBad" ຖືກຕັ້ງເປັນ 1.

$ISGOOD(a()) (ບໍ່ດີ)
ໃຫ້ຜົນເປັນຈິງ ຖ້າຄ່າທີ່ເກັບໄວ້ໃນ "a()" ບໍ່ເທົ່າກັບຄ່າທີ່ບໍ່ດີສຳລັບອັນນີ້
ປິວ. ຮຽກຮ້ອງໃຫ້ "HandleBad" ຖືກຕັ້ງເປັນ 1.

$SETBAD(a()) (ບໍ່ດີ)
ກໍານົດ "a()" ເທົ່າກັບຄ່າທີ່ບໍ່ດີສໍາລັບ piddle ນີ້. ຮຽກຮ້ອງໃຫ້ "HandleBad" ຖືກຕັ້ງ
to 1

ຫນ້າທີ່
"ວົງຮອບ(DIMS) %{ ... %}"
loop ໃນໄລຍະທີ່ມີຊື່; ຂອບເຂດຈໍາກັດແມ່ນຖືກສ້າງຂຶ້ນໂດຍອັດຕະໂນມັດໂດຍ PP

" threadloop %{ ... %}"
ຫຸ້ມລະຫັດຕໍ່ໄປນີ້ຢູ່ໃນ loop thread

"ປະເພດ(TYPES) ​​%{ ... %}"
ປະຕິບັດລະຫັດຕໍ່ໄປນີ້ຖ້າປະເພດຂອງການດໍາເນີນການໃດໆຂອງ "TYPES"

ເອກະສານຊ້ອນ C: ຫນ້າທີ່ ນຳ ເຂົ້າ by PDL::PP


ຈໍານວນຂອງຟັງຊັນຖືກນໍາເຂົ້າໃນເວລາທີ່ທ່ານ "ໃຊ້ PDL::PP". ເຫຼົ່ານີ້ລວມມີຫນ້າທີ່
ຄວບຄຸມລະຫັດ C ຫຼື XS ທີ່ສ້າງຂຶ້ນ, ຫນ້າທີ່ຄວບຄຸມລະຫັດ Perl ທີ່ສ້າງຂຶ້ນ, ແລະ
ຟັງຊັນທີ່ຈັດການແພັກເກັດແລະຕາຕະລາງສັນຍາລັກທີ່ລະຫັດຖືກສ້າງຂື້ນ.

ກຳ ລັງຜະລິດ C ແລະ XS ລະຫັດ
PDL::ຈຸດປະສົງຫຼັກຂອງ PP ແມ່ນເພື່ອເຮັດໃຫ້ມັນງ່າຍສໍາລັບທ່ານທີ່ຈະຫໍ່ເຄື່ອງຈັກ threading ປະມານຂອງທ່ານ
ລະຫັດ C ຂອງຕົນເອງ, ແຕ່ທ່ານສາມາດເຮັດສິ່ງອື່ນໄດ້, ເຊັ່ນກັນ.

pp_def
ໃຊ້ເພື່ອຫໍ່ເຄື່ອງຈັກ threading ປະມານລະຫັດ C ຂອງທ່ານ. ເກືອບທັງ ໝົດ ຂອງເອກະສານນີ້
ສົນທະນາກ່ຽວກັບການນໍາໃຊ້ pp_def.

pp_done
ຊີ້ບອກວ່າທ່ານເຮັດແລ້ວກັບ PDL::PP ແລະວ່າມັນຄວນຈະສ້າງໄຟລ໌ .xs ແລະ .pm ຂອງມັນ
ອີງໃສ່ຫນ້າທີ່ pp_* ອື່ນໆທີ່ທ່ານໄດ້ໂທຫາ. ຟັງຊັນນີ້ໃຊ້ເວລາບໍ່
ການໂຕ້ຖຽງ.

pp_addxs
ອັນນີ້ເຮັດໃຫ້ທ່ານສາມາດເພີ່ມລະຫັດ XS ໃສ່ໄຟລ໌ .xs ຂອງທ່ານໄດ້. ນີ້ແມ່ນເປັນປະໂຫຍດຖ້າທ່ານຕ້ອງການສ້າງ Perl-
ຟັງຊັນທີ່ສາມາດເຂົ້າເຖິງໄດ້ທີ່ເອີ້ນລະຫັດ C ແຕ່ບໍ່ສາມາດ ຫຼືບໍ່ຄວນເອີ້ນການໃສ່ກະທູ້
ເຄື່ອງຈັກ. XS ແມ່ນມາດຕະຖານຫມາຍຄວາມວ່າທີ່ທ່ານຫໍ່ Perl-accessible C ລະຫັດ. ເຈົ້າ​ສາ​ມາດ
ຮຽນຮູ້ເພີ່ມເຕີມຢູ່ perlxs.

pp_add_boot
ຟັງຊັນນີ້ເພີ່ມສະຕຣິງອັນໃດກໍໄດ້ທີ່ທ່ານຜ່ານໄປຫາພາກສ່ວນ XS BOOT. ສ່ວນ BOOT
ແມ່ນລະຫັດ C ທີ່ຖືກເອີ້ນໂດຍ Perl ເມື່ອໂມດູນຂອງທ່ານຖືກໂຫລດແລະເປັນປະໂຫຍດສໍາລັບ
ການເລີ່ມຕົ້ນອັດຕະໂນມັດ. ທ່ານສາມາດຮຽນຮູ້ເພີ່ມເຕີມກ່ຽວກັບ XS ແລະສ່ວນ BOOT ຢູ່ perlxs.

pp_addhdr
ເພີ່ມລະຫັດ pure-C ໃສ່ໄຟລ໌ XS ຂອງທ່ານ. ໄຟລ໌ XS ມີໂຄງສ້າງທີ່ລະຫັດ C ບໍລິສຸດຕ້ອງ
ມາກ່ອນຂໍ້ມູນຈໍາເພາະຂອງ XS. ນີ້ອະນຸຍາດໃຫ້ທ່ານລະບຸລະຫັດ C ດັ່ງກ່າວ.

pp_boundscheck
ໂດຍປົກກະຕິ PDL ກວດເບິ່ງຂອບເຂດຂອງການເຂົ້າເຖິງຂອງທ່ານກ່ອນທີ່ຈະສ້າງພວກມັນ. ທ່ານ​ສາ​ມາດ​ເຮັດ​ໄດ້​
ເປີດ ຫຼືປິດເວລາແລ່ນໂດຍການຕັ້ງຄ່າ MyPackage::set_boundscheck. ຟັງຊັນນີ້ອະນຸຍາດໃຫ້ທ່ານ
ເພື່ອເອົາຄວາມຍືດຫຍຸ່ນ runtime ແລະ ບໍ່ເຄີຍ ເຮັດການກວດສອບຂອບເຂດ. ມັນຍັງສົ່ງຄືນ
ສະຖານະການກວດສອບຂອບເຂດໃນປະຈຸບັນຖ້າເອີ້ນວ່າໂດຍບໍ່ມີການໂຕ້ຖຽງໃດໆ.

ຫມາຍເຫດ: ຂ້ອຍບໍ່ພົບຫຍັງກ່ຽວກັບການກວດສອບຂອບເຂດໃນເອກະສານອື່ນໆ. ນັ້ນ
ຕ້ອງໄດ້ຮັບການແກ້ໄຂ.

ກຳ ລັງຜະລິດ Perl ລະຫັດ
ຫຼາຍຟັງຊັນທີ່ນໍາເຂົ້າໃນເວລາທີ່ທ່ານໃຊ້ PDL::PP ຊ່ວຍໃຫ້ທ່ານສາມາດດັດແປງເນື້ອໃນຂອງ
ສ້າງໄຟລ໌ .pm. ນອກເຫນືອຈາກ pp_def ແລະ pp_done, ບົດບາດຂອງຫນ້າທີ່ເຫຼົ່ານີ້ແມ່ນ
ຕົ້ນຕໍເພື່ອເພີ່ມລະຫັດໃສ່ພາກສ່ວນຕ່າງໆຂອງໄຟລ໌ .pm ທີ່ສ້າງຂຶ້ນຂອງທ່ານ.

pp_addpm
ເພີ່ມລະຫັດ Perl ໃສ່ໄຟລ໌ .pm ທີ່ສ້າງຂຶ້ນ. PDL:: PP ຕິດຕາມສາມຢ່າງ
ພາກສ່ວນທີ່ແຕກຕ່າງກັນຂອງລະຫັດທີ່ສ້າງຂຶ້ນ: ເທິງ, ກາງ, ແລະລຸ່ມ. ທ່ານສາມາດເພີ່ມ
Perl code to the Middle section using the one-argument form , where the argument is the
ລະຫັດ Perl ທີ່ທ່ານຕ້ອງການສະຫນອງ. ໃນຮູບແບບການໂຕ້ຖຽງສອງ, ການໂຕ້ຖຽງທໍາອິດແມ່ນເປັນ
hash ທີ່ບໍ່ເປີດເຜີຍຊື່ທີ່ມີກະແຈອັນດຽວທີ່ລະບຸບ່ອນທີ່ຈະໃສ່ການໂຕ້ຖຽງທີສອງ,
ເຊິ່ງເປັນສະຕຣິງທີ່ທ່ານຕ້ອງການເພີ່ມໃສ່ໄຟລ໌ .pm. hash ແມ່ນຫນຶ່ງໃນເຫຼົ່ານີ້
ສາມ:

{ຢູ່ => 'ເທິງສຸດ'}
{ຢູ່ => 'ກາງ'}
{ຢູ່ => 'ບັອດ'}

ຍົກ​ຕົວ​ຢ່າງ:

pp_addpm({At => 'Bot'}, <

=head1 ເອກະສານບາງອັນ

ຂ້ອຍຮູ້ວ່າຂ້ອຍກຳລັງພິມນີ້ຢູ່ກາງໄຟລ໌ຂອງຂ້ອຍ, ແຕ່ມັນຈະໄປຢູ່
ດ້ານລຸ່ມ.

= ຕັດ

POD

ຄໍາເຕືອນ: ຖ້າ, ຢູ່ເຄິ່ງກາງຂອງໄຟລ໌ .pd ຂອງທ່ານ, ທ່ານວາງເອກະສານທີ່ຫມາຍເຖິງ
ດ້ານລຸ່ມຂອງຝັກຂອງເຈົ້າ, ເຈົ້າຈະສັບສົນ CPAN ຢ່າງລະອຽດ. ໃນທາງກົງກັນຂ້າມ, ຖ້າຢູ່ໃນ
ກາງຂອງ .pd fil ຂອງທ່ານ, ທ່ານເພີ່ມລະຫັດ Perl ບາງຈຸດສໍາລັບລຸ່ມສຸດຫຼືເທິງສຸດຂອງທ່ານ
ໄຟລ໌ .pm, ທ່ານພຽງແຕ່ມີຕົວທ່ານເອງທີ່ຈະສັບສົນ. :-)

pp_beginwrap
ເພີ່ມການຫໍ່ BEGIN-block. ການປະກາດທີ່ແນ່ນອນສາມາດຖືກຫໍ່ຢູ່ໃນບລັອກ BEGIN, ເຖິງແມ່ນວ່າ
ພຶດຕິກໍາເລີ່ມຕົ້ນແມ່ນເພື່ອບໍ່ມີການຫໍ່ດັ່ງກ່າວ.

pp_addbegin
ຕັ້ງລະຫັດທີ່ຈະເພີ່ມໃສ່ເທິງສຸດຂອງໄຟລ໌ .pm ຂອງທ່ານ, ເຖິງແມ່ນວ່າລະຫັດຂ້າງເທິງທີ່ທ່ານລະບຸ
ກັບ "pp_addpm({At => 'Top'}, ...)". ບໍ່ຄືກັບ pp_addpm, ການເອີ້ນອັນນີ້ຂຽນທັບອັນໃດກໍໄດ້
ຢູ່ທີ່ນັ້ນກ່ອນ. ໂດຍທົ່ວໄປແລ້ວ, ທ່ານອາດຈະບໍ່ໃຊ້ມັນ.

ການຕິດຕາມ ອອນໄລນ໌ ຈໍານວນ
ເມື່ອທ່ານໄດ້ຮັບຄວາມຜິດພາດການລວບລວມ, ບໍ່ວ່າຈະຈາກລະຫັດ C-like ຫຼືລະຫັດ Perl ຂອງທ່ານ, ມັນສາມາດຊ່ວຍໄດ້
ເພື່ອເຮັດໃຫ້ຄວາມຜິດພາດເຫຼົ່ານັ້ນກັບຄືນໄປຫາຕົວເລກແຖວໃນໄຟລ໌ແຫຼ່ງທີ່ຄວາມຜິດພາດ
ເກີດຂື້ນ.

pp_line_numbers
ເອົາເລກແຖວ ແລະສາຍລະຫັດ (ປົກກະຕິແລ້ວຍາວ). ເລກແຖວຄວນ
ຊີ້ບອກເສັ້ນທີ່ວົງຢືມເລີ່ມຕົ້ນ. ປົກກະຕິນີ້ແມ່ນ "__LINE__" ຂອງ Perl
ຕົວຫນັງສື, ເວັ້ນເສຍແຕ່ວ່າທ່ານກໍາລັງໃຊ້ heredocs, ໃນກໍລະນີນີ້ມັນແມ່ນ "__LINE__ + 1". ໄດ້
string ທີ່ສົ່ງຄືນມີ #line directives interspersed ເພື່ອຊ່ວຍໃຫ້ compiler ລາຍງານຄວາມຜິດພາດ
ໃນ​ເສັ້ນ​ທີ່​ເຫມາະ​ສົມ​.

ການດັດແກ້ ໄດ້ ສັນຍາລັກ ຕາຕະລາງ ແລະ ການສົ່ງອອກ ພຶດຕິກໍາ
PDL::PP ປົກກະຕິແລ້ວສົ່ງອອກຟັງຊັນທັງໝົດທີ່ສ້າງຂຶ້ນໂດຍໃຊ້ pp_def, ແລະປົກກະຕິແລ້ວຈະຕິດຕັ້ງພວກມັນ
ເຂົ້າໄປໃນຕາຕະລາງສັນຍາລັກ PDL. ຢ່າງໃດກໍ່ຕາມ, ທ່ານສາມາດດັດແປງພຶດຕິກໍານີ້ດ້ວຍຫນ້າທີ່ເຫຼົ່ານີ້.

pp_bless
ຕັ້ງຊຸດ (ຕາຕະລາງສັນຍາລັກ) ທີ່ລະຫັດ XS ຖືກເພີ່ມ. ຄ່າເລີ່ມຕົ້ນແມ່ນ PDL,
ເຊິ່ງໂດຍທົ່ວໄປແລ້ວແມ່ນສິ່ງທີ່ທ່ານຕ້ອງການ. ຖ້າ​ຫາກ​ວ່າ​ທ່ານ​ນໍາ​ໃຊ້​ພອນ​ໃນ​ຕອນ​ຕົ້ນ​ແລະ​ທ່ານ​ສ້າງ​ເປັນ​
ຟັງຊັນ myfunc, ຫຼັງຈາກນັ້ນທ່ານສາມາດເຮັດດັ່ງຕໍ່ໄປນີ້:

$piddle->myfunc( );
PDL::myfunc($piddle, );

ໃນທາງກົງກັນຂ້າມ, ຖ້າທ່ານອວຍພອນຫນ້າທີ່ຂອງທ່ານເຂົ້າໄປໃນຊຸດອື່ນ, ທ່ານບໍ່ສາມາດຮຽກຮ້ອງ
ພວກມັນເປັນວິທີການ PDL, ແລະຕ້ອງເອີ້ນພວກມັນເປັນ:

MyPackage::myfunc($piddle, );

ແນ່ນອນ, ທ່ານສາມາດນໍາໃຊ້ລະຫັດ PMFunc ເພື່ອເພີ່ມຫນ້າທີ່ຂອງທ່ານໃສ່ສັນຍາລັກ PDL
ຕາຕະລາງ, ແຕ່ເປັນຫຍັງເຮັດແນວນັ້ນ?

pp_add_isa
ເພີ່ມໃສ່ບັນຊີລາຍຊື່ຂອງໂມດູນຈາກທີ່ທ່ານ ໂມດູນ ສືບທອດ. ບັນຊີລາຍຊື່ເລີ່ມຕົ້ນແມ່ນ

qw(PDL::Exporter DynaLoader)

pp_core_importlist
ຢູ່ເທິງສຸດຂອງໄຟລ໌ .pm ທີ່ສ້າງຂຶ້ນຂອງເຈົ້າແມ່ນເສັ້ນທີ່ມີລັກສະນະນີ້:

ໃຊ້ PDL::Core;

ທ່ານສາມາດແກ້ໄຂໄດ້ໂດຍການລະບຸສະຕຣິງໃສ່ pp_core_importlist. ຍົກ​ຕົວ​ຢ່າງ,

pp_core_importlist('::Blarg');

ຈະມີຜົນໃນ

ໃຊ້ PDL::Core::Blarg;

ທ່ານສາມາດນໍາໃຊ້ນີ້, ສໍາລັບການຍົກຕົວຢ່າງ, ເພື່ອເພີ່ມບັນຊີລາຍຊື່ຂອງສັນຍາລັກທີ່ຈະນໍາເຂົ້າຈາກ PDL::Core. ສໍາລັບ
ຍົກຕົວຢ່າງ:

pp_core_importlist(" ':ພາຍໃນ'");

ຈະ​ນໍາ​ໄປ​ສູ່​ການ​ຄໍາ​ສັ່ງ​ການ​ນໍາ​ໃຊ້​ດັ່ງ​ຕໍ່​ໄປ​ນີ້​:

ໃຊ້ PDL::Core ':Internal';

pp_setversion
ກໍານົດສະບັບຂອງໂມດູນຂອງທ່ານ. ເວີຊັນຕ້ອງສອດຄ່ອງກັນລະຫວ່າງ .xs ແລະ .pm
ໄຟລ໌, ແລະຖືກນໍາໃຊ້ເພື່ອຮັບປະກັນວ່າຫ້ອງສະຫມຸດຂອງ Perl ຂອງທ່ານບໍ່ທົນທຸກຈາກສະບັບ
skew.

pp_add_ສົ່ງອອກ
ເພີ່ມໃສ່ລາຍຊື່ສົ່ງອອກອັນໃດກໍໄດ້ທີ່ທ່ານໃຫ້ມັນ. ຟັງຊັນທີ່ສ້າງຂຶ້ນໂດຍໃຊ້ pp_def
ຖືກເພີ່ມໃສ່ລາຍຊື່ໂດຍອັດຕະໂນມັດ. ຟັງຊັນນີ້ເປັນປະໂຫຍດຖ້າທ່ານກໍານົດ Perl ໃດ
ຟັງຊັນໂດຍໃຊ້ pp_addpm ຫຼື pp_addxs ທີ່ທ່ານຕ້ອງການສົ່ງອອກເຊັ່ນກັນ.

pp_export_nothing
ນີ້ຣີເຊັດລາຍຊື່ຂອງສັນຍາລັກທີ່ສົ່ງອອກເປັນບໍ່ມີຫຍັງເລີຍ. ອັນນີ້ອາດຈະເອີ້ນວ່າດີກວ່າ
"pp_export_clear", ນັບຕັ້ງແຕ່ທ່ານສາມາດເພີ່ມສັນຍາລັກທີ່ສົ່ງອອກຫຼັງຈາກການໂທ
"pp_export_nothing". ເມື່ອໂທຫາກ່ອນທີ່ຈະໂທຫາ pp_done, ນີ້ຮັບປະກັນວ່າເຈົ້າ
ໂມດູນບໍ່ໄດ້ສົ່ງອອກຫຍັງ, ຕົວຢ່າງ, ຖ້າທ່ານຕ້ອງການໃຫ້ນັກຂຽນໂປລແກລມໃຊ້ຂອງທ່ານ
ປະຕິບັດຫນ້າທີ່ເປັນວິທີການ.

ໃຊ້ PDL::PPp ອອນໄລນ໌ໂດຍໃຊ້ບໍລິການ onworks.net


ເຊີບເວີ ແລະສະຖານີເຮັດວຽກຟຣີ

ດາວໂຫຼດແອັບ Windows ແລະ Linux

  • 1
    packfilemanager
    packfilemanager
    ນີ້ແມ່ນຕົວຈັດການໄຟລ໌ Total War pack
    ໂຄງ​ການ​, ເລີ່ມ​ຈາກ​ສະ​ບັບ 1.7​. ກ
    ການແນະນໍາສັ້ນໆກ່ຽວກັບ Warscape
    modding: ...
    ດາວໂຫລດ packfilemanager
  • 2
    IPerf2
    IPerf2
    ເຄື່ອງມືການຈະລາຈອນເຄືອຂ່າຍສໍາລັບການວັດແທກ
    ການປະຕິບັດ TCP ແລະ UDP ດ້ວຍການວັດແທກ
    ປະມານທັງການສົ່ງຜ່ານ ແລະ latency. ໄດ້
    ເປົ້າໝາຍລວມເຖິງການຮັກສາການເຄື່ອນໄຫວ
    iperf cod...
    ດາວໂຫລດ IPerf2
  • 3
    fre:ac - ຕົວແປງສຽງຟຣີ
    fre:ac - ຕົວແປງສຽງຟຣີ
    fre:ac ເປັນຕົວແປງສຽງ ແລະ CD ຟຣີ
    ripper ສໍາລັບຮູບແບບຕ່າງໆແລະຕົວເຂົ້າລະຫັດ.
    ມັນມີ MP3, MP4 / M4A, WMA, Ogg
    ຮູບແບບ Vorbis, FLAC, AAC, ແລະ Bonk
    ສະ​ຫນັບ​ສະ​ຫນູນ​, ...
    ດາວ​ໂຫຼດ​ຟຣີ:ac - ແປງ​ສຽງ​ຟຣີ​
  • 4
    matplotlib
    matplotlib
    Matplotlib ເປັນຫ້ອງສະຫມຸດທີ່ສົມບູນແບບ
    ສໍາລັບການສ້າງ static, ມີການເຄື່ອນໄຫວ, ແລະ
    ການສະແດງພາບແບບໂຕ້ຕອບໃນ Python.
    Matplotlib ເຮັດໃຫ້ສິ່ງທີ່ງ່າຍແລະງ່າຍດາຍ
    ຍາກ...
    ດາວໂຫລດ Matplotlib
  • 5
    Botman
    Botman
    ຂຽນເຫດຜົນ chatbot ຂອງເຈົ້າຄັ້ງດຽວແລະ
    ເຊື່ອມຕໍ່ມັນກັບຫນຶ່ງໃນທີ່ມີຢູ່
    ບໍລິການສົ່ງຂໍ້ຄວາມ, ລວມທັງ Amazon
    Alexa, Facebook Messenger, Slack,
    Telegram ຫຼືແມ້ກະທັ້ງ ...
    ດາວໂຫລດ BotMan
  • 6
    Joplin
    Joplin
    Joplin ເປັນແຫຼ່ງທີ່ບໍ່ເສຍຄ່າແລະເປີດ
    note-taking ແລະ to-do ຄໍາຮ້ອງສະຫມັກທີ່
    ສາມາດຈັດການບັນທຶກຈໍານວນຫລາຍໃນ
    ຮູບແບບ Markdown, ຈັດໃຫ້ເຂົາເຈົ້າເຂົ້າໄປໃນ
    ປື້ມບັນທຶກ ແລະ...
    ດາວໂຫລດ Joplin
  • ເພີ່ມເຕີມ »

Linux ຄຳ ສັ່ງ

Ad