با سلام خدمت کاربران گرامی سایت پی وی لرن و کاربرانی که علاقمندان به دوره آموزشی پرل Perl. در جلسه گذشته آموزش کار با زمان و تاریخ را به شما ارائه نمودیم و شما را با نحوه تنظیم تاریخ و زمان فعلی و انواع شاخه های تاریخ و زمان را معرفی کردیم. در این جلسه به آموزش کار با subroutine در پرل خواهیم پرداخت.
در آموزش کار با subroutine در پرل به صورت جزئی و مفصل شما را با subroutine ها و کاربردها و انواع آن ها آشنا می نماییم.
subroutine نوعی تابع در پرل است که از گروهی از statements تشکیل شده که در کنار هم یک کار و وظیفه را بر عهده دارند.
می توانید کد خود را با کمک subroutine به زیر فرعی های جداگانه تقسیم کنید.
نحوه تقسیم کدی که قصد تقسیم آن را دارید به زیر مجموعه را دارید به شما بستگی دارد.
اما منطق تقسیم بندی معمولا این است که هر تابع یک کار خاص را انجام دهد.
پرل به طور معمول از subroutine ( زیر مجموعه )، method و تابع استفاده می نماید.
در ابتدای آموزش کار با subroutine در پرل ابتدا به تعریف و توضیح آن می پردازیم.
فرم کلی یک subroutine در زبان پرل به صورت زیر تعریف می شود.
1 2 3 | sub subroutine_name { body of the subroutine } |
در زیر می توانید روش کلی فراخوانی subroutine را ببینید.
1 | subroutine_name( list of arguments ); |
در نسخه های پرل که قبل از نسخه ۰٫۵ بودند سینتکس فراخوانی subroutines ها کمی متفاوت بود.
اما خوشبختانه این روش همچنان در نسخه های جدید تر کار می کند اما از زمانی که نسخه اصلی آن دارای راه های فرعی شده است توصیه می شود که از آن استفاده نشود.
1 | &subroutine_name( list of arguments ); |
به مثال زیر توجه کنید که که یک تابع ساده را تعریف می کند و سپس آن را فراخوانی می نماید.
از آنجا که پرل برنامه شما را قبل از اجرای آن کامپایل می کند، مهم نیست که کدام فرمان زیر را اعلام می کنید.
1 2 3 4 5 6 7 8 9 | #!/usr/bin/perl # Function definition sub Hello { print "Hello, World!\n"; } # Function call Hello(); |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 | Hello, World! |
می توانید مانند سایر زبان های برنامه نویسی دیگر در پرل نیز argument ها را به یک subroutine ارجاع دهید.
می توان این argument ها را به وسیله @ array در داخل تابع قابل دسترسی اند.
بنابرین اولین argument تابع [۰]_$ است و دومین argument آن نیز [۱]_$ است و به همین ترتیب ادامه یابد.
می توان مثل هر اسکالری array ها و Hash ها به عنوان argument ارجاع داد اما ارجاع بیش از حد یک array یا hash به طور معمول موجب می شود که آن ها خاصیت خود را از دست بدهند.
بیاید مثال زیر را بررسی کنیم که از لیستی از اعداد استفاده می کند و میانگین آن ها را به دست آورده و پرینت می نماید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/perl # Function definition sub Average { # get total number of arguments passed. $n = scalar(@_); $sum = 0; foreach $item (@_) { $sum += $item; } $average = $sum / $n; print "Average for the given numbers : $average\n"; } # Function call Average(10, 20, 30); |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 | Average for the given numbers : 20 |
از آن جا که متغیر _@ یک array است.
می توان از آن برای ارائه یک لیست به subroutine استفاده کرد.
از آن جا که پرل لیست ها و array ها توسط پرل پذیرفته و تجزیه می شوند می توان عناصر منحصر به فرد را از _@ استخراج کرد.
اگر لازم است که که یک لیست را با سایر argument های اسکالر ارجاع دهیم در این صورت این لیست را به عنوان آخرین argument به شکل زیر نشان دهید.
1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/perl # Function definition sub PrintList { my @list = @_; print "Given list is @list\n"; } $a = 10; @b = (1, 2, 3, 4); # Function call with list parameter PrintList($a, @b); |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 | Given list is 10 1 2 3 4 |
هنگامی که یک Hash به یک Subroutines یا اپراتوری ارجاع داده می شود که ورود آن را به لیست می پذیرد.
Hash به صورت خودکار به یک لیست از جفت key/value منتقل می شود.
برای مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/perl # Function definition sub PrintHash { my (%hash) = @_; foreach my $key ( keys %hash ) { my $value = $hash{$key}; print "$key : $value\n"; } } %hash = ('name' => 'Tom', 'age' => 19); # Function call with hash parameter PrintHash(%hash); |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 2 | name : Tom age : 19 |
می توانید مانند سایر زبان های برنامه نویسی یک مقدار را به subroutine بازگردانی کرد.
اگر موفق به بازگردانی یک مقدار به یک نشدید هر محاسباتی که در لیست و در subroutine انجام شده است به صورت خودکار مقدار بازگشتی را برمی گرداند.
می توان مثل هر اسکالری array ها و Hash ها به عنوان argument ارجاع داد اما ارجاع بیش از حد یک array یا hash به طور معمول موجب می شود که آن ها خاصیت خود را از دست بدهند.
به همین دلیل است که ترجیح داده می شود که از references یا منابع به جای آن استفاده شود تا هر array و hash را از تابع بازگردانی نماییم.
در جلسات بعدی به طور مفصل به آموزش کار با references خواهیم پرداخت.
بیاید مثال زیر را بررسی کنیم .
این مثال از لیستی از اعداد استفاده می کند و میانگین آن ها را به دست آورده و آن را بازگردانی می نماید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/perl # Function definition sub Average { # get total number of arguments passed. $n = scalar(@_); $sum = 0; foreach $item (@_) { $sum += $item; } $average = $sum / $n; return $average; } # Function call $num = Average(10, 20, 30); print "Average for the given numbers : $num\n"; |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 | Average for the given numbers : 20 |
در ادامه آموزش کار با subroutine در پرل شما را با یک سری از مقادیر خاص در پرل آشنا می نماییم.
به طور پیش فرض، تمام متغیرها در پرل متغیرهای جهانی هستند، به این معنی که می توانند از هر نقطه در برنامه قابل دسترسی باشند.
می توان با ساخت متغیر های خاص یا private variables متغیرهای lexical را در هر زمانی در اپراتور my operator فراخوانی نمود.
my operator یک متغیر به بخش خاصی از کد که می توان به آن دسترسی داشت؛ محدود می کند.
خارج از آن منطقه، این متغیر نمی تواند مورد استفاده قرار گیرد و یا قابل دسترسی باشد.
این منطقه دامنه آن است.
یک ناحیه دامنه ای معمولا یک بلوک از کدها است که با یک مجموعه از braces های اطرافش احاطه شده است.
در زیر می توانید ببینید که چگونه یک یا چند متغیر private را با استفاده از my operator تعریف نمایید.
1 2 3 4 | sub somefunc { my $variable; # $variable is invisible outside somefunc() my ($another, @an_array, %a_hash); # declaring many variables at once } |
حالا بیایید مثال زیر را برای تشخیص تمایز بین متغیر های خاص و منحصر به فرد private با متغیر های جهانی یا global بررسی کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/perl # Global variable $string = "Hello, World!"; # Function definition sub PrintHello { # Private variable for PrintHello function my $string; $string = "Hello, Perl!"; print "Inside the function $string\n"; } # Function call PrintHello(); print "Outside the function $string\n"; |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 2 | Inside the function Hello, Perl! Outside the function Hello, World! |
اغلب از local زمانی استفاده می شود که مقدار فعلی متغیر قابل دیدن و فراخوانی برای subroutines باشد.
یک local مقادیر موقتی ای را به global می دهد. این عمل به عنوان dynamic scoping نامیده می شود.
اگر بیش از یک متغیر به local داده شود در آن صورت باید درون پرانتز جایگذاری شود.
این اپراتور با ذخیره سازی مقادیر فعلی از متغیر ها درون لیست argument های پنهان در stack کار خود را انجام می دهد.
حالا بیایید مثال زیر را برای تشخیص تمایز بین متغیر های خاص و منحصر به فرد private با متغیر های جهانی یا global بررسی کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/perl # Global variable $string = "Hello, World!"; sub PrintHello { # Private variable for PrintHello function local $string; $string = "Hello, Perl!"; PrintMe(); print "Inside the function PrintHello $string\n"; } sub PrintMe { print "Inside the function PrintMe $string\n"; } # Function call PrintHello(); print "Outside the function $string\n"; |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 2 3 | Inside the function PrintMe Hello, Perl! Inside the function PrintHello Hello, Perl! Outside the function Hello, World! |
نوع دیگری از متغیرهای واژگانی وجود دارد که شبیه به متغیرهای خصوصی هستند.
اما این متغیر ها حالت خود را حفظ می کنند و با چندین فراخوانی subroutines مجددا فعال نمی شوند.
این متغیرها با استفاده از اپراتور state تعریف شده و از پرل ۵٫۹٫۴ در دسترس می باشند.
در مثال زیر می توانید نحوه استفاده از state variables را ببینید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/perl use feature 'state'; sub PrintCount { state $count = 0; # initial value print "Value of counter is $count\n"; $count++; } for (1..5) { PrintCount(); } |
اجرای کد بالا خروجی به شکل زیر خواهد داشت.
1 2 3 4 5 | Value of counter is 0 Value of counter is 1 Value of counter is 2 Value of counter is 3 Value of counter is 4 |
اگر از نسخه های قبل از ۵٫۱۰ پرل استفاده می نمایید باید این کد را به شکل زیر بنویسید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/perl { my $count = 0; # initial value sub PrintCount { print "Value of counter is $count\n"; $count++; } } for (1..5) { PrintCount(); } |
به عنوان آخرین موضوع در آموزش کار با subroutine در پرل به معرفی Subroutine Call Context می پردازیم.
زمینه یک subroutine یا statement به عنوان نوعی که انتظار بازگردانی آن را داریم تعریف می شود.
این زمینه اجازه استفاده از یک تابع تکی که مقادیر مختلف را بر اساس آنچه که کاربر انتظار دریافت آن را دارد بازگردانی می کند.
برای مثال یک رشته را هنگامی که در اسکالر context در لیست context فراخوانی می شود بازگردانی می کند.
1 | my $datestring = localtime( time ); |
در این مثال، مقدار timestr$ در حال حاضر یک رشته از تاریخ و زمان فعلی است، به عنوان مثال، چهارشنبه ۳۰ نوامبر ۱۵:۲۱:۳۳ ۲۰۰۰٫ اما در مقابل آن :
1 | ($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time); |
در حال حاضر متغیرهای فردی حاوی مقادیر متناظر با ()subroutine localtime هستند.
در این جلسه آموزش کار با subroutine در پرل را ارائه کردیم.
در جلسه بعد با آموزش references همراه شما خواهیم بود.
با پی وی لرن همراه باشید.