این دستور perlsyn است که می تواند در ارائه دهنده میزبانی رایگان OnWorks با استفاده از یکی از چندین ایستگاه کاری آنلاین رایگان ما مانند Ubuntu Online، Fedora Online، شبیه ساز آنلاین ویندوز یا شبیه ساز آنلاین MAC OS اجرا شود.
برنامه:
نام
perlsyn - نحو پرل
شرح
برنامه پرل متشکل از دنباله ای از اعلان ها و عباراتی است که از
بالا به پایین حلقه ها، زیر روال ها و سایر ساختارهای کنترلی به شما امکان می دهند بپرید
اطراف درون کد
پرل یک است فرم رایگان زبان: می توانید آن را هر طور که دوست دارید قالب بندی و تورفتگی کنید. فضای سفید
بر خلاف زبان هایی مانند پایتون که در آن ها اهمیت زیادی دارد، بیشتر برای جدا کردن توکن ها استفاده می شود
بخشی از نحو، یا Fortran که در آن غیر مادی است.
بسیاری از عناصر نحوی پرل هستند اختیاری. به جای اینکه از شما بخواهد قرار دهید
پرانتز در اطراف هر فراخوانی تابع و اعلام هر متغیر، اغلب می توانید ترک کنید
چنین عناصر صریحی خاموش شده و پرل متوجه منظور شما خواهد شد. این به عنوان شناخته شده است Do
چی I منظور داشتنبه طور خلاصه DWIM. این امکان را به برنامه نویسان می دهد تنبل و به یک سبک کدنویسی کنید
که با آن راحت هستند.
پرل وام نحو و مفاهیم بسیاری از زبان ها: awk، sed، C، Bourne Shell،
اسمال تاک، لیسپ و حتی انگلیسی. زبان های دیگر نحو را از پرل وام گرفته اند،
به ویژه پسوندهای عبارت منظم آن. بنابراین اگر در دیگری برنامه ریزی کرده اید
زبان قطعات آشنا را در پرل خواهید دید. آنها اغلب یکسان کار می کنند، اما perltrap را می بینند
برای اطلاعات در مورد تفاوت آنها.
اعلامیه ها
تنها چیزهایی که باید در پرل اعلام کنید فرمتهای گزارش و برنامههای فرعی (و
گاهی اوقات حتی زیربرنامه نیست). یک متغیر اسکالر مقدار تعریف نشده ("undef") را نگه می دارد.
تا زمانی که یک مقدار تعریف شده به آن اختصاص داده شود که هر چیزی غیر از "undef" باشد. چه زمانی
به عنوان یک عدد، "undef" به عنوان 0 در نظر گرفته می شود. هنگامی که به عنوان یک رشته استفاده می شود، به عنوان رشته در نظر گرفته می شود
رشته خالی، ""; و هنگامی که به عنوان مرجعی استفاده می شود که به آن اختصاص داده نمی شود، با آن برخورد می شود
به عنوان یک خطا اگر هشدارها را فعال کنید، یک مقدار اولیه به شما اطلاع داده می شود
هر زمان که "undef" را به عنوان یک رشته یا یک عدد در نظر بگیرید. خب معمولا زمینه های بولی،
مانند:
اگر ($a) {}
از هشدار معاف هستند (زیرا آنها به حقیقت اهمیت می دهند تا تعریف).
عملگرهایی مانند "++"، "--"، "+="، "-="، و ".="، که بر روی متغیرهای تعریف نشده کار می کنند.
مانند:
unef $a;
$a++;
همچنین همیشه از چنین هشدارهایی مستثنی هستند.
یک اعلان را می توان در هر جایی که یک عبارت می تواند قرار داد، اما تاثیری بر اجرای آن ندارد
دنباله اصلی عبارات: اعلان ها همگی در زمان کامپایل اعمال می شوند. همه
اعلان ها معمولاً در ابتدا یا انتهای اسکریپت قرار می گیرند. با این حال، اگر
شما از متغیرهای خصوصی با دامنه لغوی استفاده می کنید که با "my()"، "state()"، یا
"our()"، باید مطمئن شوید که قالب یا زیربرنامه شما در همان تعریف است
اگر انتظار دارید بتوانید به آن متغیرهای خصوصی دسترسی داشته باشید، محدوده را به عنوان my block کنید.
اعلان یک زیربرنامه اجازه می دهد تا از نام زیربرنامه به گونه ای استفاده شود که گویی یک عملگر لیست است
از آن نقطه به بعد در برنامه شما می توانید یک زیربرنامه را بدون تعریف آن اعلام کنید
با گفتن "نام فرعی"، به این ترتیب:
زیر نام من
$me = myname $0 یا مرگ "نمی توان نام من را دریافت کرد";
یک اعلان خالی مانند آن تابع را به عنوان یک عملگر لیست اعلام می کند، نه یک واحد
عملگر، بنابراین باید مراقب باشید که از پرانتز (یا "یا" به جای "||".) استفاده کنید.
"||" عملگر خیلی محکم متصل می شود تا از عملگرهای بعد از لیست استفاده شود. بخشی از آخرین می شود
عنصر همیشه می توانید از پرانتز در اطراف آرگومان های عملگرهای لیست برای چرخاندن آن استفاده کنید
لیست اپراتور به چیزی که بیشتر شبیه یک فراخوانی تابع عمل می کند. متناوبا، از سوی دیگر،
می توانید از نمونه اولیه "($)" برای تبدیل زیربرنامه به یک عملگر unary استفاده کنید:
زیر نام من ($)؛
$me = myname $0 || die "can't get myname";
اکنون آنطور که انتظار دارید تجزیه میشود، اما همچنان باید عادت استفاده را داشته باشید
پرانتز در آن شرایط برای اطلاعات بیشتر در مورد نمونه های اولیه، به perlsub مراجعه کنید.
اعلانهای زیربرنامه نیز میتوانند با عبارت "require" بارگذاری شوند یا هر دو بارگذاری شوند.
و با عبارت "use" به فضای نام شما وارد می شود. برای جزئیات بیشتر به perlmod مراجعه کنید.
یک دنباله عبارت ممکن است حاوی اعلان هایی از متغیرهای دارای دامنه لغوی باشد، اما جدا از هم
از اعلان نام متغیر، اعلان مانند یک عبارت معمولی عمل می کند و هست
در توالی گزاره ها به گونه ای توضیح داده می شود که گویی یک بیانیه معمولی است. که
به این معنی که در واقع دارای اثرات زمان کامپایل و زمان اجرا است.
نظرات
متن از یک کاراکتر "#" تا انتهای خط یک نظر است و نادیده گرفته می شود.
استثناها عبارتند از "#" در داخل یک رشته یا عبارت منظم.
ساده بیانیه
تنها نوع بیان ساده عبارتی است که از نظر عوارض جانبی آن ارزیابی می شود. هر
دستور ساده باید با نقطه ویرگول خاتمه یابد، مگر اینکه دستور نهایی در باشد
یک بلوک، در این صورت نقطه ویرگول اختیاری است. اما در هر صورت نقطه ویرگول را قرار دهید
بلوک بیش از یک خط را اشغال می کند، زیرا ممکن است در نهایت یک خط دیگر اضافه کنید. توجه داشته باشید که
عملگرهایی مانند "eval {}"، "sub {}" و "do {}" وجود دارد نگاه مانند مرکب
عبارات، اما اینطور نیستند - آنها فقط اصطلاحاتی در یک عبارت هستند - و بنابراین نیاز به صریح دارند
خاتمه زمانی که به عنوان آخرین مورد در یک بیانیه استفاده می شود.
حقیقت و دروغ
عدد 0، رشتههای «0» و «»، لیست خالی «()»، و «undef» همه در یک نادرست هستند.
زمینه بولی تمام مقادیر دیگر درست هستند. نفی یک مقدار واقعی توسط "!" یا نه"
مقدار نادرست خاصی را برمی گرداند. هنگامی که به عنوان یک رشته ارزیابی می شود به عنوان ""، اما به عنوان یک رفتار می شود
بیشتر عملگرهای پرل که true یا false را برمیگردانند، این رفتار را دارند
راه.
بیانیه اصلاح کننده ها
هر عبارت ساده ای ممکن است به صورت اختیاری با a دنبال شود تنها اصلاح کننده، درست قبل از
نقطه ویرگول پایانی (یا پایان بلوک). اصلاح کننده های ممکن عبارتند از:
اگر EXPR
مگر اینکه EXPR
در حالی که EXPR
تا EXPR
برای LIST
foreach LIST
هنگامی که EXPR
"EXPR" به دنبال اصلاح کننده به عنوان "شرط" نامیده می شود. حقیقت آن یا
falsehood تعیین می کند که اصلاح کننده چگونه رفتار خواهد کرد.
"if" یکبار دستور را اجرا می کند if و فقط در صورتی که شرط درست باشد. "مگر اینکه" باشد
در مقابل، دستور را اجرا می کند مگر شرط درست است (یعنی اگر
شرط نادرست است).
اگر طول $ear >= 10;
go_outside() و play() مگر اینکه $is_raining;
اصلاح کننده "for(each)" یک تکرار کننده است: این دستور را برای هر آیتم یک بار اجرا می کند.
LIST (با $_ مستعار برای هر مورد به نوبه خود).
چاپ "Hello $_!\n" برای qw(world Dolly Nurse).
"در حالی که" عبارت را تکرار می کند در حین شرط درست است "تا" برعکس عمل کند، آن را
بیانیه را تکرار می کند تا شرط درست است (یا در حالی که شرط نادرست است):
# هر دوی اینها از 0 تا 10 حساب می شوند.
چاپ $i++ در حالی که $i <= 10;
چاپ $j++ تا $j > 10;
تعدیلکنندههای «در حالی که» و «تا» معنایی معمولی «حلقهای» دارند (مشروط
ابتدا ارزیابی می شود)، به جز زمانی که برای یک "do" -BLOCK (یا برای "do" -SUBROUTINE Perl4 اعمال شود.
بیانیه)، در این صورت بلوک یک بار قبل از ارزیابی شرطی اجرا می شود.
این برای این است که می توانید حلقه هایی مانند:
انجام دادن {
خط $ = ;
...
} تا !defined($line) || $line eq ".\n"
به "do" در perlfunc مراجعه کنید. همچنین توجه داشته باشید که عبارات کنترل حلقه توضیح داده شده در ادامه خواهد بود نه
در این ساختار کار کنید، زیرا اصلاحکنندهها برچسبهای حلقه را نمیگیرند. متاسف. شما همیشه می توانید
یک بلوک دیگر در داخل آن (برای "بعدی") یا اطراف آن (برای "آخرین") قرار دهید تا این کار را انجام دهید.
چیز. برای "بعدی"، فقط پرانتزها را دو برابر کنید:
انجام دادن {{
بعد اگر $x == $y;
#اینجا یه کاری بکن
}} تا $x++ > $z;
برای "آخر"، باید دقیق تر باشید:
حلقه: {
انجام دادن {
آخرین اگر $x = $y**2;
#اینجا یه کاری بکن
} در حالی که $x++ <= $z;
}
توجه: رفتار یک "من"، "وضعیت" یا "ما" که با یک اصلاح کننده بیانیه اصلاح شده است
ساختار شرطی یا حلقه ای (به عنوان مثال، "x $ من اگر ...") است تعریف نشده. ارزش
متغیر "my" ممکن است "undef"، هر مقدار قبلاً اختصاص داده شده یا احتمالاً هر چیزی باشد
دیگر به آن تکیه نکنید. نسخههای آینده پرل ممکن است کاری متفاوت از نسخه انجام دهند
نسخه پرل را امتحان کنید. اینجا اژدها باشید
اصلاح کننده "when" یک ویژگی آزمایشی است که برای اولین بار در Perl 5.14 ظاهر شد. برای استفاده
در آن، شما باید یک اعلان "use v5.14" را وارد کنید. (از نظر فنی، فقط به این نیاز دارد
ویژگی "سوئیچ"، اما این جنبه از آن قبل از 5.14 در دسترس نبود.) فقط عملیاتی
از داخل یک حلقه "foreach" یا یک بلوک "داده شده"، دستور را فقط در صورتی اجرا می کند که
smartmatch "$_ ~~ EXPR" درست است. اگر دستور اجرا شود، یک "بعدی" دنبال می شود.
از درون یک «فروچ» و «شکستن» از درون یک «داده».
تحت اجرای فعلی، حلقه "foreach" می تواند در هر جایی در "when" باشد.
محدوده دینامیکی اصلاح کننده، اما باید در محدوده واژگانی بلوک "مشخص شده" باشد. این
محدود ممکن است در نسخه آینده کاهش یابد. به "تغییر بیانیه ها" در زیر مراجعه کنید.
ترکیب بیانیه
در پرل، به دنباله ای از عبارات که یک محدوده را تعریف می کند، بلوک می گویند. گاهی اوقات الف
بلوک با فایلی که حاوی آن است (در مورد فایل مورد نیاز یا
برنامه به عنوان یک کل)، و گاهی اوقات یک بلوک با وسعت یک رشته (در
مورد ارزشیابی).
اما به طور کلی، یک بلوک با براکتهای فرفری که به نام مهاربند نیز شناخته میشوند، مشخص میشود. تماس خواهیم گرفت
این نحو یک BLOCK می سازد.
عبارات ترکیبی زیر ممکن است برای کنترل جریان استفاده شود:
اگر (EXPR) BLOCK
if (EXPR) BLOCK other BLOCK
if (EXPR) BLOCK elif (EXPR) BLOCK ...
if (EXPR) BLOCK elif (EXPR) BLOCK ... other BLOCK
مگر اینکه (EXPR) BLOCK
مگر اینکه (EXPR) BLOCK other BLOCK
مگر اینکه (EXPR) BLOCK elif (EXPR) BLOCK ...
مگر اینکه (EXPR) BLOCK elsif (EXPR) BLOCK ... other BLOCK
داده شده (EXPR) BLOCK
LABEL while (EXPR) BLOCK
LABEL در حالی که (EXPR) BLOCK ادامه BLOCK
LABEL تا (EXPR) BLOCK
LABEL تا (EXPR) BLOCK ادامه BLOCK
LABEL برای (EXPR; EXPR; EXPR) BLOCK
LABEL برای VAR (LIST) BLOCK
LABEL برای VAR (LIST) BLOCK ادامه BLOCK
LABEL foreach (EXPR; EXPR; EXPR) BLOCK
LABEL برای بلوک VAR (LIST).
LABEL foreach VAR (LIST) BLOCK ادامه BLOCK
BLOCK LABEL
LABEL BLOCK ادامه BLOCK
بلوک فاز
عبارت تجربی "داده شده" است نه بطور خودکار فعال; به "تغییر بیانیه ها" مراجعه کنید
در زیر برای چگونگی انجام این کار، و اخطارهای همراه.
برخلاف C و Pascal، در Perl اینها همه بر اساس BLOCK ها تعریف می شوند، نه عبارات.
این بدان معنی است که براکت های فرفری هستند ضروری- هیچ بیانیه آویزان مجاز نیست. اگر شما
می خواهید شرطی ها را بدون پرانتز بنویسید، چندین راه دیگر برای انجام آن وجود دارد.
موارد زیر همگی همین کار را انجام می دهند:
if (!open(FOO)) { die "Can't open $FOO: $!" }
die "نمی توان $FOO را باز کرد: $!" مگر اینکه باز (FOO)؛
باز (FOO) || die "نمی توان $FOO را باز کرد: $!";
باز (FOO) ? () : die "نمی توان $FOO: $ را باز کرد!";
# کمی عجیب و غریب، آن آخرین
عبارت «اگر» ساده است. زیرا BLOCK ها همیشه با curly محدود می شوند
در پرانتز، هرگز هیچ ابهامی در مورد اینکه «اگر» با «دیگر» همراه است وجود ندارد. اگر استفاده می کنید
«مگر» به جای «اگر»، معنای آزمون معکوس می شود. مانند "اگر"، "مگر" می تواند باشد
به دنبال آن "دیگر". "مگر" حتی می تواند با یک یا چند عبارت "elsif" دنبال شود،
اگرچه ممکن است بخواهید قبل از استفاده از آن ساختار خاص زبان، دو بار فکر کنید
هر کسی که کد شما را میخواند باید حداقل دو بار فکر کند تا بتواند بفهمد
چه خبر است
دستور "while" بلوک را تا زمانی که عبارت درست باشد اجرا می کند. "تا"
دستور تا زمانی که عبارت false باشد بلوک را اجرا می کند. LABEL اختیاری است،
و در صورت وجود، شامل یک شناسه و به دنبال آن یک دو نقطه است. LABEL شناسایی می کند
حلقه برای عبارات کنترل حلقه "next"، "last" و "redo". اگر LABEL حذف شود،
عبارت کنترل حلقه به درونی ترین حلقه محصور کننده اشاره دارد. این ممکن است شامل شود
به صورت پویا پشته تماس خود را در زمان اجرا برای یافتن LABEL به عقب نگاه میکنید. چنین ناامید
در صورت استفاده از پراگما یا از "هشدارهای استفاده"، رفتار باعث ایجاد هشدار می شود -w پرچم.
اگر یک BLOCK "ادامه" وجود داشته باشد، همیشه درست قبل از اینکه شرطی حدود باشد اجرا می شود
دوباره مورد ارزیابی قرار گیرد. بنابراین می توان از آن برای افزایش یک متغیر حلقه استفاده کرد، حتی زمانی که
حلقه از طریق عبارت "next" ادامه یافته است.
هنگامی که یک بلوک با یک کلمه کلیدی فاز کامپایل مانند "BEGIN"، "END"، "INIT" قرار دارد،
"بررسی"، یا "UNITCHECK"، سپس بلوک فقط در مرحله مربوطه اجرا می شود
اجرا. برای جزئیات بیشتر به perlmod مراجعه کنید.
ماژول های برنامه افزودنی همچنین می توانند به تجزیه کننده Perl متصل شوند تا انواع جدیدی از ترکیب را تعریف کنند
بیانیه. اینها با یک کلمه کلیدی که پسوند آن را تشخیص می دهد، معرفی می شوند
سینتکس زیر کلمه کلیدی به طور کامل توسط پسوند تعریف می شود. اگر شما یک
پیادهکننده، برای مکانیسم به "PL_keyword_plugin" در perlapi مراجعه کنید. اگر از چنین مواردی استفاده می کنید
یک ماژول، برای جزئیات نحوی که تعریف می کند، به مستندات ماژول مراجعه کنید.
حلقه کنترل
دستور "next" تکرار بعدی حلقه را شروع می کند:
خط: در حالی که ( ) {
خط بعدی اگر /^#/; # رد کردن نظرات
...
}
دستور "آخرین" بلافاصله از حلقه مورد نظر خارج می شود. بلوک "ادامه"، در صورت وجود،
اجرا نمی شود:
خط: در حالی که ( ) {
آخرین خط اگر /^$/; وقتی با هدر تمام شد، از آن خارج شوید
...
}
دستور "redo" بلوک حلقه را مجدداً بدون ارزیابی مجدد شرطی راه اندازی می کند. در
بلوک "ادامه"، در صورت وجود، وجود دارد نه اجرا شده. این دستور معمولا توسط برنامه هایی استفاده می شود که
می خواهند در مورد آنچه که فقط ورودی بوده به خود دروغ بگویند.
به عنوان مثال، هنگام پردازش یک فایل مانند /etc/termcap. اگر خطوط ورودی شما ممکن است به پایان برسد
اسلش معکوس برای نشان دادن ادامه، شما می خواهید به جلو پرش کنید و رکورد بعدی را دریافت کنید.
در حالی که (<>) {
chomp;
if (s/\\$//) {
$_ .= <>;
انجام مجدد مگر اینکه eof();
}
# اکنون $_ را پردازش کنید
}
که مخفف پرل برای نسخه واضح تر نوشته شده است:
LINE: در حالی که (تعریف شده ($line = )) {
chomp($line);
اگر ($line =~ s/\\$//) {
$line .= ;
دوباره LINE مگر اینکه eof(); # نه eof(ARGV)!
}
# اکنون $line را پردازش کنید
}
توجه داشته باشید که اگر یک بلوک "ادامه" روی کد بالا وجود داشته باشد، فقط اجرا می شود
در خطوطی که توسط regex کنار گذاشته شده اند (از آنجایی که انجام مجدد از بلوک ادامه می گذرد). یک بلوک ادامه
اغلب برای تنظیم مجدد شمارنده های خط یا "m?pat?" مسابقات یکباره:
# با الهام از:1,$g/fred/s//WILMA/
در حالی که (<>) {
m؟(فرد)؟ && s//WILMA $1 WILMA/;
m؟(بارنی)؟ && s//BETTY $1 BETTY/;
m?(هومر)؟ && s//MARGE $1 MARGE/;
} ادامه هید {
چاپ "$ARGV $.: $_";
بستن ARGV اگر eof; # بازنشانی $.
تنظیم مجدد اگر eof; # بازنشانی ?pat?
}
اگر کلمه "در حالی که" با کلمه "تا زمانی که" جایگزین شود، معنای آزمون برعکس می شود.
اما شرطی هنوز قبل از اولین تکرار آزمایش می شود.
عبارات کنترل حلقه در "اگر" یا "اگر" کار نمی کنند، زیرا آنها حلقه نیستند. شما
با این حال، می تواند بریس ها را دو برابر کند تا آنها را چنین کند.
اگر (/pattern/) {{
آخرین اگر /فرد/;
بعدی اگر /barney/; # همان اثر "آخرین"،
# اما به خوبی مستند نیست
#اینجا یه کاری بکن
}}
این به دلیل این واقعیت است که یک بلوک به خودی خود به عنوان یک حلقه عمل می کند که یک بار اجرا می شود، ببینید
"بلوک های اساسی".
فرم "while/if BLOCK BLOCK" موجود در Perl 4 دیگر در دسترس نیست. جایگزین کردن
هر گونه وقوع "if BLOCK" توسط "if (do BLOCK)".
برای حلقه
حلقه "for" به سبک C پرل مانند حلقه "while" مربوطه عمل می کند. یعنی این:
برای ($i = 1؛ $i < 10؛ $i++) {
...
}
مانند این است:
$i = 1;
در حالی که ($i < 10) {
...
} ادامه هید {
$ من ++؛
}
یک تفاوت جزئی وجود دارد: اگر متغیرها با "my" در مقداردهی اولیه اعلان شوند
بخش "for"، دامنه واژگانی آن متغیرها دقیقاً حلقه "for" است (
بدنه حلقه و بخش های کنترل).
به عنوان یک مورد خاص، اگر آزمایش در حلقه "for" (یا حلقه "while" مربوطه) باشد
خالی است، درست تلقی می شود. یعنی هر دو
برای (؛؛) {
...
}
و
در حالی که () {
...
}
به عنوان حلقه های بی نهایت در نظر گرفته می شوند.
علاوه بر حلقهبندی شاخص آرایه معمولی، «for» میتواند خود را به بسیاری موارد جالب دیگر برساند
برنامه های کاربردی. در اینجا یکی از مشکلاتی است که در صورت آزمایش صریح با آن مواجه می شوید
پایان فایل در یک توصیفگر فایل تعاملی که باعث میشود برنامه شما هنگ کند.
$on_a_tty = -t STDIN && -t STDOUT;
فرمان فرعی { print "yes?" if $on_a_tty }
برای ( prompt(); ; سریع() ) {
# کاری بکنید
}
با استفاده از "readline" (یا فرم عملگر، " ") همانطور که شرط یک حلقه "for" است
خلاصه برای موارد زیر این رفتار همان حلقه شرطی "while" است.
برای ( prompt(); defined($_ = ) سریع() ) {
# کاری بکنید
}
برای هر حلقه
حلقه "foreach" روی یک مقدار لیست معمولی تکرار می شود و متغیر اسکالر VAR را بر روی
هر عنصر لیست به نوبه خود باشد. اگر قبل از متغیر کلمه کلیدی "my" قرار گیرد،
سپس از نظر واژگانی دارای محدوده واژگانی است و بنابراین فقط در داخل حلقه قابل مشاهده است. در غیر این صورت،
متغیر به طور ضمنی محلی برای حلقه است و با خروج از حلقه، مقدار قبلی خود را باز می یابد
حلقه اگر متغیر قبلا با "my" اعلان شده بود، به جای آن از آن متغیر استفاده می کند
جهانی، اما هنوز در حلقه محلی است. این محلی سازی ضمنی رخ می دهد
فقط در یک حلقه "foreach".
کلمه کلیدی "foreach" در واقع مترادف کلمه کلیدی "for" است، بنابراین می توانید از هر یک از آنها استفاده کنید.
اگر VAR حذف شود، $_ برای هر مقدار تنظیم می شود.
اگر هر عنصری از LIST یک lvalue باشد، میتوانید با تغییر VAR در داخل حلقه، آن را تغییر دهید.
برعکس، اگر هر عنصری از LIST یک lvalue نیست، هر تلاشی برای اصلاح آن عنصر است
شکست خواهد خورد. به عبارت دیگر، متغیر شاخص حلقه "foreach" یک نام مستعار ضمنی برای است
هر مورد در لیستی که در حال بررسی آنها هستید.
اگر هر بخشی از LIST یک آرایه باشد، اگر اضافه یا حذف کنید، "foreach" بسیار گیج می شود.
عناصر درون بدنه حلقه، به عنوان مثال با "Splice". پس این کار را نکن
اگر VAR متقابل یا متغیر ویژه دیگری باشد، احتمالاً "foreach" آن چیزی را که انتظار دارید انجام نخواهد داد.
این کار را هم نکن
از Perl 5.22، یک نوع آزمایشی از این حلقه وجود دارد که یک متغیر را می پذیرد
قبل از آن یک اسلش برای VAR وجود دارد که در این صورت موارد موجود در LIST باید مرجع باشند.
متغیر بک اسلش شده به نام مستعار هر آیتم ارجاع شده در LIST تبدیل می شود که
باید از نوع صحیح باشد متغیر در این مورد نباید اسکالر باشد و
پس از بک اسلش ممکن است "my" باشد. برای استفاده از این فرم، باید "Refaliasing" را فعال کنید.
ویژگی از طریق "استفاده از ویژگی". (به ویژگی مراجعه کنید. همچنین به "تخصیص به مراجع" در perlref مراجعه کنید.)
مثال:
برای (@ary) { s/foo/bar/ }
برای $elem من (@elements) {
$elem *= 2;
}
برای $count (reverse(1..10)، "BOOM") {
چاپ $count، "\n";
خواب(1)؛
}
for (1..15) { print "Merry Christmas\n"; }
foreach $item (split(/:[\\\n:]*/، $ENV{TERMCAP})) {
چاپ "Item: $item\n";
}
استفاده از ویژگی "refaliasing"؛
بدون هشدار "experimental::refaliasing";
foreach \my %hash (@array_of_hash_references) {
# کاری را انجام دهید که هر % هش کند
}
در اینجا آمده است که چگونه یک برنامه نویس C ممکن است یک الگوریتم خاص را در Perl کدنویسی کند:
برای ($i من = 0؛ $i < @ary1؛ $i++) {
برای ($j من = 0؛ $j < @ary2؛ $j++) {
اگر ($ary1[$i] > $ary2[$j]) {
آخر؛ # نمیشه به بیرون رفت :-(
}
$ary1[$i] += $ary2[$j];
}
# این همان جایی است که آخرش مرا می برد
}
در حالی که در اینجا یک برنامه نویس Perl که با این اصطلاح راحت تر است می تواند این کار را انجام دهد:
OUTER: برای $wid من (@ary1) {
INNER: برای $jet من (@ary2) {
بعدی OUTER اگر $wid > $jet;
$wid += $jet;
}
}
ببینید این کار چقدر راحت تر است؟ تمیزتر، ایمن تر و سریعتر است. تمیزتر است چون اینطور است
سر و صدای کمتر ایمن تر است زیرا اگر کد بعداً بین حلقه های داخلی و خارجی اضافه شود
در، کد جدید به طور تصادفی اجرا نمی شود. "بعدی" به صراحت دیگری را تکرار می کند
حلقه به جای پایان دادن به حلقه درونی. و سریعتر است زیرا Perl اجرا می کند
یک عبارت "foreach" سریعتر از حلقه "for" معادل آن است.
هکرهای ادراکی Perl ممکن است متوجه شده باشند که یک حلقه "for" مقدار بازگشتی دارد و این
این مقدار را می توان با پیچاندن حلقه در یک بلوک "do" بدست آورد. پاداش این کار
کشف این توصیه هشدار دهنده است: مقدار بازگشتی یک حلقه "for" نامشخص است و
ممکن است بدون اطلاع قبلی تغییر کند به آن تکیه نکنید.
اساسی بلوک ها
یک BLOCK به خودی خود (برچسب شده یا نه) از نظر معنایی معادل حلقه ای است که اجرا می شود
یک بار. بنابراین می توانید از هر یک از دستورات کنترل حلقه در آن برای خروج یا راه اندازی مجدد استفاده کنید
مسدود کردن. (توجه داشته باشید که این است نه درست در "eval{}"، "sub{}"، یا برخلاف باور عمومی
بلوک های "do{}" که انجام می دهند نه به عنوان حلقه بشمارید.) بلوک "ادامه" اختیاری است.
ساختار BLOCK را می توان برای شبیه سازی ساختارهای مورد استفاده کرد.
تعویض: {
if (/^abc/) { $abc = 1; آخرین سوئیچ؛ }
if (/^def/) { $def = 1; آخرین سوئیچ؛ }
if (/^xyz/) {$xyz = 1; آخرین سوئیچ؛ }
هیچ چیز = 1;
}
همچنین خواهید دید که حلقه "foreach" برای ایجاد یک تاپالیزر و یک سوئیچ استفاده می شود:
تعویض:
برای ($var) {
if (/^abc/) { $abc = 1; آخرین سوئیچ؛ }
if (/^def/) { $def = 1; آخرین سوئیچ؛ }
if (/^xyz/) {$xyz = 1; آخرین سوئیچ؛ }
هیچ چیز = 1;
}
چنین ساختارهایی معمولاً مورد استفاده قرار میگیرند، هر دو به این دلیل که نسخههای قدیمیتر Perl فاقد آن بودند
بیانیه رسمی "سوئیچ"، و همچنین به این دلیل که نسخه جدید بلافاصله در زیر توضیح داده شده است
تجربی باقی می ماند و گاهی اوقات می تواند گیج کننده باشد.
گزینه بیانیه
با شروع از Perl 5.10.1 (خوب، 5.10.0، اما درست کار نکرد)، می توانید بگویید
از ویژگی "سوئیچ" استفاده کنید.
برای فعال کردن یک ویژگی سوئیچ آزمایشی. این بر اساس نسخه قدیمی a است
پیشنهاد پرل 6، اما دیگر شبیه سازه پرل 6 نیست. شما همچنین دریافت می کنید
هر زمان که اعلام کردید کد شما ترجیح میدهد تحت نسخهای از Perl اجرا شود، ویژگی تغییر دهید
یعنی 5.10 یا بالاتر. مثلا:
استفاده از v5.14;
تحت ویژگی "switch"، Perl کلیدواژه های آزمایشی "given"، "when" را به دست می آورد.
«پیشفرض»، «ادامه» و «شکست». با شروع از Perl 5.16، می توان سوئیچ را پیشوند گذاشت
کلمات کلیدی با "CORE::" برای دسترسی به ویژگی بدون عبارت "use feature". در
کلیدواژههای «داده» و «وقتی» مشابه «تغییر» و «مورد» در زبانهای دیگر هستند، بنابراین
کد در بخش قبل می تواند بازنویسی شود
استفاده از v5.10.1;
برای ($var) {
وقتی (/^abc/) { $abc = 1 }
وقتی (/^def/) { $def = 1 }
وقتی (/^xyz/) {$xyz = 1 }
پیشفرض {$nothing = 1}
}
"Foreach" روشی غیرتجربی برای تنظیم موضعی ساز است. اگر مایل به استفاده از
"داده" بسیار تجربی، که می تواند اینگونه نوشته شود:
استفاده از v5.10.1;
داده شده ($var) {
وقتی (/^abc/) { $abc = 1 }
وقتی (/^def/) { $def = 1 }
وقتی (/^xyz/) {$xyz = 1 }
پیشفرض {$nothing = 1}
}
از 5.14، می توان آن را به این صورت نیز نوشت:
استفاده از v5.14;
برای ($var) {
$abc = 1 وقتی /^abc/;
$def = 1 وقتی /^def/;
$xyz = 1 وقتی /^xyz/;
پیشفرض {$nothing = 1}
}
یا اگر اهمیتی به ایمن بازی کردن ندارید، مانند زیر:
استفاده از v5.14;
داده شده ($var) {
$abc = 1 وقتی /^abc/;
$def = 1 وقتی /^def/;
$xyz = 1 وقتی /^xyz/;
پیشفرض {$nothing = 1}
}
آرگومان های "داده" و "وقتی" در زمینه اسکالر هستند و "داده" $_ را اختصاص می دهد.
متغیر مقدار موضوع آن
دقیقا همان چیزی که EXPR توصیف دقیق استدلال به "وقتی" دشوار است، اما در
به طور کلی، سعی می کند حدس بزند که می خواهید چه کاری انجام دهید. گاهی اوقات به عنوان "$_ ~~ تعبیر می شود
EXPR"، و گاهی اوقات اینطور نیست. همچنین هنگامی که از نظر لغوی توسط a محصور می شود، رفتار متفاوتی دارد
بلوک "داده شده" نسبت به زمانی که به صورت پویا توسط یک حلقه "foreach" محصور می شود. قوانین هستند
درک آن بسیار دشوار است که در اینجا توضیح داده شود. به "جزئیات تجربی در داده شده" مراجعه کنید
و کی" بعدا
به دلیل یک اشکال تاسف بار در نحوه پیاده سازی "داده" بین Perl 5.10 و 5.16، تحت
آن پیادهسازیها، نسخه $_ که توسط "given" اداره میشود، صرفاً یک محدوده لغوی است
کپی از نسخه اصلی، نه یک نام مستعار با دامنه پویا به نسخه اصلی، همانطور که میشد
یک "foreach" یا تحت هر دو مشخصات زبان اصلی و فعلی Perl 6 بودند.
این باگ در پرل 5.18 رفع شد. اگر واقعاً یک $_ واژگانی می خواهید، آن را مشخص کنید
به صراحت، اما توجه داشته باشید که "my $_" اکنون منسوخ شده است و هشدار می دهد مگر اینکه اخطارها
غیر فعال شده است:
داده شده ($_ من = EXPR) { ... }
اگر هنوز باید کد شما روی نسخههای قدیمیتر اجرا شود، برای تاپالیزر خود به «foreach» بچسبید
و کمتر ناراضی خواهید بود.
برو
اگرچه برای افراد ضعیف نیست، پرل از بیانیه "goto" پشتیبانی می کند. وجود دارد
سه شکل: "goto"-LABEL، "goto"-EXPR، و "goto"-&NAME. LABEL یک حلقه در واقع نیست
یک هدف معتبر برای "goto"؛ این فقط نام حلقه است.
فرم "goto"-LABEL عبارت با برچسب LABEL را پیدا می کند و اجرا را در آنجا از سر می گیرد.
ممکن است برای ورود به هر ساختاری که نیاز به مقداردهی اولیه دارد استفاده نشود، مانند a
زیر برنامه یا حلقه "foreach". همچنین نمی توان از آن برای وارد شدن به ساختاری که هست استفاده کرد
دور بهینه شده می توان از آن برای رفتن تقریباً به هر جای دیگری در محدوده پویا استفاده کرد،
از جمله خارج از برنامه های فرعی، اما معمولاً بهتر است از ساختار دیگری مانند
"آخر" یا "بمیر". نویسنده پرل هرگز نیازی به استفاده از این شکل از "گوتو" احساس نکرده است.
(در پرل، یعنی--C موضوع دیگری است).
فرم "goto"-EXPR یک نام برچسب را انتظار دارد که دامنه آن به صورت پویا حل می شود. این
اجازه می دهد تا "goto" های محاسبه شده در هر FORTRAN، اما اگر شما هستید، لزوما توصیه نمی شود
بهینه سازی برای نگهداری:
goto(("FOO"، "BAR"، "GLARCH")[$i]);
فرم "goto"-&NAME بسیار جادویی است و فراخوانی را جایگزین زیرروال نامگذاری شده می کند.
برای زیربرنامه در حال اجرا. این مورد توسط زیرروال های "AUTOLOAD()" که مایل هستند استفاده می شود
برای بارگذاری زیربرنامه دیگری و سپس وانمود کردن به اینکه زیربرنامه دیگر فراخوانی شده است
در وهله اول (به جز اینکه هر گونه تغییر در @_ در زیر روال فعلی وجود دارد
به زیربرنامه دیگر منتشر می شود.) پس از "goto"، حتی "caller()" نیز قادر نخواهد بود
بگویم که این روال ابتدا فراخوانی شد.
تقریباً در همه موارد مانند این، معمولاً استفاده از ساختار یافته ایده بسیار بهتری است
مکانیسمهای جریان «بعدی»، «آخرین» یا «دوباره» را به جای متوسل شدن به «گوتو» کنترل کنید.
برای برنامههای خاص، جفت «eval{}» را بگیرید و پرتاب کنید مرگ () برای استثنا
پردازش نیز می تواند یک رویکرد محتاطانه باشد.
La حذف بیانیه
با شروع در Perl 5.12، Perl یک بیضی، """ را به عنوان یک مکان نگهدار برای کد می پذیرد.
هنوز اجرا نکردی این شکل از بیضی، عبارت اجرا نشده، باید
با عملگر فلیپ فلاپ باینری "..." اشتباه نشود. یکی بیانیه است و
یک اپراتور دیگر (پرل معمولاً آنها را اشتباه نمی گیرد زیرا معمولاً پرل می تواند بگوید
آیا یک اپراتور می خواهد یا یک دستور، اما برای موارد استثنا به زیر مراجعه کنید.)
هنگامی که Perl 5.12 یا جدیدتر با یک عبارت بیضی روبرو می شود، آن را بدون خطا تجزیه می کند.
اما اگر و زمانی که واقعاً باید سعی کنید آن را اجرا کنید، Perl یک استثنا با the میزند
متن "عدم اجرا":
استفاده از v5.12;
زیر اجرا نشده { ... }
eval { unimplemented() };
اگر ($@ =~ /^ در / اجرا نشده است) {
بگویید "من یک بیضی پیدا کردم!"؛
}
شما فقط می توانید از عبارت بیضی برای قرار گرفتن در یک عبارت کامل استفاده کنید. اینها
نمونه هایی از نحوه عملکرد بیضی:
استفاده از v5.12;
{...}
زیر فوو {...}
...
ارزش { ... };
زیر چیزی {
من $self = shift;
...
}
$x = انجام {
من $n;
...
بگویید "هورا!"
$n;
};
گزاره بیضوی نمی تواند برای عبارتی باشد که بخشی از یک عبارت بزرگتر است
بیانیه، زیرا "..." نیز نسخه سه نقطه ای عملگر فلیپ فلاپ است (نگاه کنید به
"اپراتورهای محدوده" در پرلوپ).
این نمونههای تلاش برای استفاده از بیضی، خطاهای نحوی هستند:
استفاده از v5.12;
چاپ ...؛
open(my $fh، ">"، "/dev/passwd") یا ...;
if ($condition && ... ) { say "Howdy" };
مواردی وجود دارد که پرل نمی تواند بلافاصله تفاوت بین a را تشخیص دهد
بیان و بیانیه به عنوان مثال، نحو برای یک بلوک و یک هش ناشناس
سازنده مرجع یکسان به نظر می رسد مگر اینکه چیزی در پرانتزها وجود داشته باشد که Perl a را نشان دهد
اشاره اگر پرل حدس نزند که "{ ... }" یک بلوک است، بیضی یک خطای نحوی است.
در این صورت، فکر نمیکند که «...» بیضی باشد، زیرا در انتظار یک است
بیان به جای بیانیه:
@transformed = map { ... } @input; # اشتباه نوشتاری
در داخل بلوک خود، می توانید از یک ";" استفاده کنید. قبل از بیضی برای نشان دادن اینکه "{ ... }" a است
بلوک و نه سازنده مرجع هش. اکنون بیضی کار می کند:
@transformed = map {; ... } @input; # ';' ابهام می کند
توجه: برخی از مردم به صورت محاوره ای این بیت از نقطه گذاری را به عنوان "یادا-یادا" یا
"سه نقطه"، اما نام واقعی آن در واقع بیضی است.
POD ها: جاسازی شده مستندات
پرل مکانیزمی برای اختلاط اسناد با کد منبع دارد. در حالی که انتظار می رود
شروع یک عبارت جدید، اگر کامپایلر با خطی روبرو شود که با an شروع می شود
علامت مساوی و یک کلمه، مانند این
=head1 اینجا وجود دارد غلاف!
سپس آن متن و تمام متن باقی مانده به بالا و شامل یک خط شروع با
"=cut" نادیده گرفته خواهد شد. قالب متن میانی در perlpod توضیح داده شده است.
این به شما این امکان را می دهد که کد منبع و متن اسناد خود را آزادانه با هم ترکیب کنید، همانطور که در اینجا آمده است
= item snazzle ($)
تابع snazzle() به دیدنی ترین حالت عمل می کند
شکلی که شما احتمالاً می توانید تصور کنید، حتی به استثنای آن
سایبرنتیک پیروتکنیک
=قطع به کامپایلر، خفن از این چیزهای پاد!
زیر snazzle ($) {
من $thingie = shift;
.........
}
توجه داشته باشید که مترجمان پاد باید فقط به پاراگراف هایی که با دستورالعمل پاد شروع می شوند نگاه کنند
(تجزیه را آسان تر می کند)، در حالی که کامپایلر در واقع می داند که به دنبال فرارهای پاد باشد
حتی در وسط یک پاراگراف این بدان معنی است که چیزهای مخفی زیر خواهد بود
هم توسط کامپایلر و هم توسط مترجم نادیده گرفته شده است.
$a=3;
= چیزهای مخفی
هشدار "نه POD نه CODE!"
=قطع کردن
چاپ "got $a\n";
احتمالاً نباید به "warn()" که برای همیشه پادد می شود تکیه کنید. نه همه غلاف
مترجمان در این زمینه رفتار خوبی دارند و شاید گردآورنده انتخابگرتر شود.
همچنین میتوان از دستورالعملهای pod برای اظهار نظر سریع بخشی از کد استفاده کرد.
ساده قدیمی نظرات (نه!)
پرل می تواند دستورات خط را پردازش کند، دقیقاً مانند پیش پردازنده C. با استفاده از این می توان
ایده پرل در مورد نام فایل ها و شماره خطوط در پیام های خطا یا هشدار را کنترل کنید (به خصوص
برای رشته هایی که با "eval()" پردازش می شوند). نحو برای این مکانیسم تقریبا است
مانند اکثر پیش پردازنده های C: با عبارت منظم مطابقت دارد
# مثال: '# خط 42 "new_filename.plx"'
/^\# \s*
خط \s+ (\d+) \s*
(?:\s("؟)([^"]+)\g2)؟ \s*
$/x
با $1 شماره خط برای خط بعدی، و $3 نام فایل اختیاری است
(با یا بدون نقل قول مشخص شده است). توجه داشته باشید که هیچ فضای خالی ممکن است قبل از "#" باشد، بر خلاف
پیش پردازنده های مدرن C
یک دستور العمل نسبتاً واضح وجود دارد: اشکالزداها و نمایهگرها
فقط آخرین خط منبع را نشان می دهد که در یک شماره خط خاص در یک فایل مشخص ظاهر می شود.
باید مراقب بود که باعث برخورد شماره خط در کدی که میخواهید اشکال زدایی کنید، نشود
بعد.
در اینجا چند نمونه وجود دارد که باید بتوانید آنها را در پوسته فرمان خود تایپ کنید:
% پرل
# خط 200 "bzzzt"
# "#" در خط قبلی باید اولین کاراکتر در خط باشد
مرگ 'فو';
__پایان__
foo در خط bzzzt 201.
% پرل
# خط 200 "bzzzt"
eval qq[\n#line 2001 ""\ndie 'foo']; چاپ $@;
__پایان__
foo at - line 2001.
% پرل
eval qq[\n#خط 200 "foo bar"\ndie 'foo']; چاپ $@;
__پایان__
foo at foo bar line 200.
% پرل
# خط 345 "گوپ"
eval "\n#line" . __LINE__ . ' "' . __FILE__ ."\"\ndie 'foo'";
چاپ $@;
__پایان__
foo در goop line 345.
تجربی جزئیات on داده و چه زمانی
همانطور که قبلا ذکر شد، ویژگی "سوئیچ" بسیار آزمایشی در نظر گرفته می شود. این است
ممکن است با اطلاع کمی تغییر کند. به ویژه «وقتی» رفتارهای حیلهآمیزی دارد که
انتظار می رود تغییر کند تا در آینده کمتر مشکل شود. به جریان آن تکیه نکنید
(سوء) پیاده سازی قبل از پرل 5.18، "داده" نیز رفتارهای فریبنده ای داشت که شما باید
همچنان مراقب باشید که آیا کد شما باید روی نسخه های قدیمی پرل اجرا شود.
در اینجا یک مثال طولانی تر از "داده شده" آمده است:
از ویژگی ":5.10" استفاده کنید.
داده شده ($foo) {
when (unef) {
بگویید "$foo تعریف نشده است"؛
}
وقتی ("فو") {
بگویید '$foo رشته "foo" است';
}
وقتی ([1,3,5,7,9،XNUMX،XNUMX،XNUMX،XNUMX]) {
بگویید "$foo یک رقم فرد است"؛
ادامه هید؛ # سقوط از طریق
}
وقتی ($_ < 100) {
بگویید '$foo از نظر عددی کمتر از 100 است';
}
when (\&complicated_check) {
بگویید "یک بررسی پیچیده برای $foo درست است".
}
پیش فرض {
die q(نمی دانم با $foo چه کنم).
}
}
قبل از Perl 5.18، "given(EXPR)" مقدار را به آن اختصاص می داد EXPR صرفاً از نظر لغوی
کپی کنید (!) از $_، نه یک نام مستعار با دامنه پویا به روشی که "foreach" انجام می دهد. این باعث شد
مشابه
{ my $_ = EXPR; ...}
با این تفاوت که بلوک به طور خودکار توسط یک "when" یا یک موفقیت آمیز شکسته شد
صریح "شکستن". از آنجا که فقط یک نسخه بود و از آنجا که فقط از نظر واژگانی محدوده داشت،
به صورت پویا نیست، نمی توانید کارهایی را که در الف به آن عادت دارید با آن انجام دهید
حلقه "foreach". به ویژه، برای فراخوانی های تابع دلخواه کار نمی کند
توابع ممکن است سعی کنند به $_ دسترسی پیدا کنند. برای آن بهترین گزینه به "foreach" بچسبید.
بیشتر قدرت از تطبیق هوشمند ضمنی ناشی می شود که گاهی اوقات می تواند اعمال شود. بیشتر
زمان، "when(EXPR)" به عنوان تطابق هوشمند ضمنی $_، یعنی "$_ ~~ EXPR" در نظر گرفته می شود.
(برای اطلاعات بیشتر در مورد تطبیق هوشمند به «اپراتور Smartmatch» در perlop مراجعه کنید.) اما چه زمانی
EXPR یکی از 10 مورد استثنایی (یا مواردی مانند آنها) است که در زیر ذکر شده است، استفاده می شود
به طور مستقیم به عنوان یک بولی.
1. فراخوانی فرعی تعریف شده توسط کاربر یا فراخوانی روش.
2. تطبیق عبارت منظم به شکل «/REGEX/»، «$foo =~ /REGEX/»، یا «$foo =~
EXPR". همچنین، یک عبارت منظم منطبق به شکل "!/REGEX/"، "$foo !~
/REGEX/، یا "$foo !~ EXPR".
3. تطبیق هوشمندی که از یک عملگر صریح "~~" مانند "EXPR ~~ EXPR" استفاده می کند.
توجه: شما اغلب مجبور خواهید بود از "$c ~~ $_" استفاده کنید زیرا حالت پیش فرض از "$_ ~~ $c" استفاده می کند.
که اغلب برعکس آنچه شما می خواهید است.
4. یک عملگر مقایسه بولی مانند "$_ < 10" یا "$x معادل "abc"". رابطه ای
عملگرهایی که این مورد برای آنها اعمال می شود شش مقایسه عددی ("<"، ">"، "<="، ">="،
"=="، و "!=")، و شش رشته مقایسه ("lt"، "gt"، "le"، "ge"، "eq"، و
"نه").
5. حداقل سه تابع داخلی "defined(...)"، "exists(...)"، و "eof(...)".
اگر به آنها فکر کنیم، ممکن است روزی بعداً موارد بیشتری را اضافه کنیم.
6. یک عبارت نفی، خواه "!(EXPR)" یا "not(EXPR)"، یا یک انحصاری منطقی-یا،
"(EXPR1) xor (EXPR2)". نسخه های بیتی ("~" و "^") گنجانده نشده اند.
7. یک عملگر filetest، دقیقاً با 4 استثنا: "-s"، "-M"، "-A" و "-C"
مقادیر عددی را برمی گرداند، نه مقادیر بولی. عملگر فایل تست "-z" گنجانده نشده است
در لیست استثنا
8. عملگرهای فلیپ فلاپ ".." و "...". توجه داشته باشید که عملگر فلیپ فلاپ "..." است
کاملاً متفاوت از عبارت بیضوی "..." که توضیح داده شد.
در آن 8 مورد بالا، مقدار EXPR مستقیماً به عنوان یک بولی استفاده می شود، بنابراین خیر
تطبیق هوشمند انجام شده است. ممکن است به «وقتی» به عنوان یک مسابقه هوشمند فکر کنید.
علاوه بر این، پرل عملوندهای عملگرهای منطقی را بررسی می کند تا تصمیم بگیرد که آیا از آن استفاده کند یا خیر
تطبیق هوشمند برای هر یک با اعمال تست بالا برای عملوندها:
9. اگر EXPR "EXPR1 && EXPR2" یا "EXPR1 and EXPR2" باشد، آزمایش اعمال می شود. بازگشتی به
هر دو EXPR1 و EXPR2. فقط اگر هر دو عملوندها نیز آزمون را با موفقیت پشت سر می گذارند، بازگشتی، خواهد شد
عبارت به عنوان بولی در نظر گرفته شود. در غیر این صورت از Smart Matching استفاده می شود.
10. اگر EXPR "EXPR1 || EXPR2"، "EXPR1 // EXPR2"، یا "EXPR1 or EXPR2" باشد، تست
اعمال می شود بازگشتی فقط به EXPR1 (که ممکن است خود یک AND با اولویت بالاتر باشد
برای مثال، اپراتور، و بنابراین تابع قانون قبلی است)، نه به EXPR2. اگر EXPR1
استفاده از تطبیق هوشمند است، سپس EXPR2 نیز این کار را انجام می دهد، مهم نیست که EXPR2 شامل چه چیزی است. ولی
اگر EXPR2 نتواند از تطبیق هوشمند استفاده کند، آرگومان دوم وجود نخواهد داشت
یا این کاملاً با حالت "&&" که قبلاً توضیح داده شد متفاوت است، بنابراین مراقب باشید.
این قوانین پیچیده هستند، اما هدف این است که آنها آنچه را که می خواهید انجام دهند (حتی اگر شما
دقیقاً نمی فهمم چرا آنها این کار را انجام می دهند). مثلا:
وقتی (/^\d+$/ && $_ < 75) { ... }
به عنوان یک تطابق بولی در نظر گرفته می شود زیرا قوانین می گویند هم مطابقت regex و هم یک
تست صریح در $_ به عنوان بولی در نظر گرفته می شود.
بنابراین:
When ([qw(foo bar)] && /baz/) { ... }
از تطبیق هوشمند استفاده خواهد کرد زیرا فقط یک از عملوندها یک بولی است: کاربردهای دیگر
تطبیق هوشمند، و این برنده است.
بیشتر:
وقتی ([qw(foo bar)] || /^baz/) { ... }
از تطبیق هوشمند استفاده خواهد کرد (فقط اولین عملوند در نظر گرفته می شود)، در حالی که
وقتی (/^baz/ || [qw(foo bar)]) { ... }
فقط regex را آزمایش می کند، که باعث می شود هر دو عملوند به عنوان بولی در نظر گرفته شوند. مواظب باش
برای این یکی، پس، زیرا یک arrayref همیشه یک مقدار واقعی است، که آن را به طور موثر می سازد
زائد. ایده ی خوبی نیست.
عملگرهای بولین توتولوگ همچنان بهینه سازی می شوند. وسوسه نشوید
نوشتن
When ("foo" یا "bar") { ... }
این به "foo" بهینه می شود، بنابراین "bar" هرگز در نظر گرفته نمی شود (حتی اگر قوانین باشد
بگویید از یک مسابقه هوشمند در "foo" استفاده کنید). برای جایگزینی مانند این، یک آرایه ref کار خواهد کرد،
زیرا این امر باعث ایجاد تطابق هوشمند می شود:
وقتی ([qw(foo bar)] { ... }
این تا حدودی معادل عملکرد سقوط دستور سوئیچ به سبک C است
(با آن اشتباه گرفته نشود پرل قابلیت fallthrough - زیر را ببینید)، که در آن یکسان است
بلوک برای چندین عبارت "case" استفاده می شود.
میانبر مفید دیگر این است که اگر از یک آرایه تحت اللفظی یا هش به عنوان آرگومان استفاده کنید
«داده شده» به مرجع تبدیل می شود. بنابراین "given(@foo)" همان "given(\@foo)" است،
به عنوان مثال.
"پیش فرض" دقیقاً مانند "when(1 == 1)" عمل می کند، یعنی همیشه مطابقت دارد.
شکستن خارج
می توانید از کلمه کلیدی "شکستن" برای خارج شدن از بلوک "داده شده" استفاده کنید. هر "وقتی"
بلوک به طور ضمنی با "شکست" به پایان می رسد.
سقوط از طریق
میتوانید از کلمه کلیدی «ادامه» برای انتقال از یک مورد به مورد دیگر استفاده کنید:
داده شده ($foo) {
وقتی (/x/) { بگویید '$foo حاوی x است'; ادامه هید }
وقتی (/y/) { بگویید "$foo حاوی ay است" }
پیشفرض {بگویید "$foo حاوی ay نیست" }
}
برگشت ارزش
وقتی یک عبارت «داده شده» یک عبارت معتبر نیز باشد (مثلاً وقتی آخرین مورد است
بیانیه یک بلوک)، آن را به صورت زیر ارزیابی می کند:
· یک لیست خالی به محض اینکه با یک "شکست" صریح مواجه می شوید.
· مقدار آخرین عبارت ارزیابی شده موفق بند "when"/"default"،
اگر اتفاقی وجود داشته باشد
· مقدار آخرین عبارت ارزیابی شده بلوک "داده شده" در صورت عدم وجود شرط
درست است
در هر دو مورد آخر، آخرین عبارت در زمینه ای که به آن اعمال شد ارزیابی می شود
بلوک "داده شده"
توجه داشته باشید که برخلاف "if" و "unless"، عبارات ناموفق "when" همیشه به صورت خالی ارزیابی می شوند
فهرست
قیمت دلار من = انجام {
داده شده ($item) {
When (["گلابی"، "سیب"]) { 1 }
شکستن هنگام "رای دادن"؛ #رای من خریدنی نیست
1e10 وقتی /مونالیزا/;
"ناشناس"؛
}
};
در حال حاضر، بلوک های "داده شده" را نمی توان همیشه به عنوان عبارات مناسب استفاده کرد. این ممکن است
در نسخه آینده پرل به آن پرداخته شده است.
سوئیچینگ in a حلقه
به جای استفاده از "given()"، می توانید از حلقه "foreach()" استفاده کنید. به عنوان مثال، در اینجا یک راه وجود دارد
برای شمارش چند بار یک رشته خاص در یک آرایه:
استفاده از v5.10.1;
تعداد $ من = 0;
برای (@array) {
when ("foo") { ++$count }
}
چاپ "\@array حاوی $count کپی از 'foo'\n" است.
یا در نسخه جدیدتر:
استفاده از v5.14;
تعداد $ من = 0;
برای (@array) {
++$count هنگامی که "foo";
}
چاپ "\@array حاوی $count کپی از 'foo'\n" است.
در پایان تمام بلوکهای «وقتی»، یک «بعدی» ضمنی وجود دارد. شما می توانید آن را با
اگر فقط به بازی اول به تنهایی علاقه دارید، یک "آخرین" صریح.
اگر به صراحت یک متغیر حلقه را مشخص کنید، مانند "for $item (array@)" کار نمی کند.
شما باید از متغیر پیش فرض $_ استفاده کنید.
تفاوت از جانب پرل 6
تطبیق هوشمند Perl 5 و ساختارهای "داده شده"/"وقتی" با Perl 6 آنها سازگار نیست.
آنالوگ ها مشهودترین تفاوت و کم اهمیت ترین تفاوت این است که در Perl 5،
پرانتز در اطراف آرگومان برای "given()" و "when()" مورد نیاز است (به جز زمانی که این
آخرین مورد به عنوان یک اصلاح کننده بیانیه استفاده می شود). پرانتز در پرل 6 همیشه در a اختیاری است
ساختار کنترلی مانند "if()"، "while()"، یا "when()"; آنها را نمی توان اختیاری کرد
Perl 5 بدون مقدار زیادی سردرگمی بالقوه، زیرا Perl 5 آن را تجزیه می کند
بیان
داده شده $foo {
...
}
گویی که آرگومان «داده شده» عنصری از هش %foo است که عبارت را تفسیر می کند
مهاربندها به عنوان نحو عنصر هش.
با این حال، آنها تفاوت های بسیار بسیار دیگری دارند. به عنوان مثال، این در Perl 5 کار می کند:
استفاده از v5.12;
my @primary = ("قرمز"، "آبی"، "سبز")؛
if (@primary ~~ "قرمز") {
بگویید "مطابقات هوشمند اولیه قرمز"؛
}
if ("قرمز" ~~ @primary) {
بگویید "تطبیق اولیه هوشمند قرمز"؛
}
بگویید "همین، مردم!"؛
اما در Perl 6 اصلا کار نمی کند. در عوض، باید از (قابل موازی سازی) "any" استفاده کنید.
اپراتور:
در صورت وجود(@primary) معادل "قرمز" {
بگویید "مطابقات هوشمند اولیه قرمز"؛
}
اگر معادله "قرمز" وجود داشته باشد(@primary) {
بگویید "تطبیق اولیه هوشمند قرمز"؛
}
جدول مسابقات هوشمند در "اپراتور Smartmatch" در پرلوپ با آن یکسان نیست
توسط مشخصات Perl 6 پیشنهاد شده است، عمدتاً به دلیل تفاوت بین Perl 6 و Perl
مدل های داده 5، اما همچنین به این دلیل که مشخصات Perl 6 از زمانی که Perl 5 عجله کرد، تغییر کرده است.
پذیرش زودهنگام
در Perl 6، "when()" همیشه یک تطبیق هوشمند ضمنی با آرگومان خود انجام می دهد، در حالی که در Perl
5 راحت است (البته به طور بالقوه گیج کننده) سرکوب این تطابق هوشمند ضمنی در
موقعیتهای مختلف نسبتاً ضعیف تعریف شده، همانطور که تقریباً در بالا ذکر شد. (تفاوت این است
تا حد زیادی به این دلیل که پرل 5، حتی در داخل، نوع بولی ندارد.)
با استفاده از خدمات onworks.net از perlsyn آنلاین استفاده کنید