توابع
در این فصل، قصد داریم برنامه های خود را به چندین بخش تقسیم کرده، بخش هایی که لازم داریم را در مواقع نیاز صدا بزنیم. در واقع، قرار است یک برنامه به چند زیربرنامه تقسیم شود.
تابع چیست؟
قبل از این که به سراغ پیاده سازی توابع در روبی برویم، بیایید ببینیم که تابع چیست. یک تابع، یک رابطه از مجموعه A به B است که از هز عضو A دقیقا یک عضو از B نظیر می شود. به صورت کلی، و در شبه کد ها تابع را به این شکل نمایش میدهیم :
f(A) -> B
در برنامه نویسی نیز، دقیقا به همین شکل است. یک ورودی به تابع مورد نظر داده شده، سپس خروجی منحصر به فرد دریافت خواهیم کرد.
توابع در روبی
تابع در روبی، به این شکل تعریف میشود :
def funcName(ARGUMENTS)
STATEMENTS
end
با این که برای نام توابع، محدودیتی جز این که با کاراکتر یا_
شروع شوند نیست، ما قرار داد میکنیم که تابع ها را با نام کوچک نام گذاری کنیم.
توابع تهی یا void
این توابع، توابعی هستند که مقداری را بر نمیگردانند (از return در این توابع استفاده نمی شود). از این توابع، برای خواندن ورودی، یا چاپ خروجی استفاده میکنیم. برای مثال تابع زیر یک پیام ساده چاپ میکند :
def hello()
puts "Hello, World!"
end
برای صدا زدن این تابع در کد، کافیست به این شکل نام تابع را در کد خود قرار دهیم :
hello()
تابع تهی با دریافت آرگومان
توابع تهی، گرچه مقداری را بر نمیگردانند، اما قابلیت دریافت آرگومان را دارند. برای مثال، تابع بالا را به شکل دیگری باز نویسی میکنیم :
def hello(name = "World")
puts "Hello, #{name}!"
end
در این تابع، ما آرگومانی به نام name با مقدار پیشفرض World برای تابع تعریف کردیم. اگر تابع را به این شکل فراخوانی کنیم :
hello()
پیام Hello, World! چاپ خواهد شد. اما اگر نامی به آن بدهیم، برای مثال Muhammadreza ، به این شکل خواهد بود :
hello("Muhammadreza")
#=> Hello, Muhammadreza!
توابع غیرتهی
در این توابع، مقدار خروجی حتما باید برگردد. در واقع، در این توابع از دستور العمل return استفاده میکنیم تا نتیجه نهایی را به کاربر برگردانیم. فرض کنیم میخواهیم تابعی بنویسیم که سه عدد را با یکدیگر جمع میکند. تابع ما چنین شکلی خواهد داشت :
def addNums(a, b, c)
return a + b + c
end
اگر این تابع را به این شکل، تنها با سه پارامتر صدا کنیم :
addNums(1, 2, 4)
اتفاقی رخ نمیدهد. دلیل آن نیز این است که تابع اجرا شده است، اما نتیجه آن را چاپ نکرده ایم. برای این که کد ما بتواند نتیجه مناسبی نیز به ما بدهد، باید این کار را بکنیم :
puts addNums(1, 2, 4)
به این شکل، عدد ۷ در خروجی نمایان می شود.
برنامه جمع اعداد بدون محدودیت در تعداد
اکنون قصد داریم برنامه ای بنویسیم که بتواند تعداد نامحدودی از اعداد را به عنوان ورودی دریافت کرده و سپس حاصل جمعشان را بر گرداند. برای دریافت تعداد زیادی ورودی، و در قالب یک آرایه تنها کافیست این چنین عمل کنیم :
def funcName(*args)
STATEMENTS
end
پس ، مشخص شد که شکل کلی تابع ما چگونه است. اکنون، نوبت آن است که با استفاده از یک حلقه، حاصل جمع اعضای یک آرایه را حساب کرده و در متغیری برگردانیم.
def addNums(*nums)
sum = 0
for i in nums
sum += i
end
return sum
end
برای مثال، خروجی این تابع به اعضای ۳ مقدار ۱ و ۱و ۳ ، عدد ۵ خواهد بود. استفاده از این روش، به ما کمک میکند که بتوانیم یک عملیات خاص را بدون محدودیت در تعداد ورودی ها، انجام دهیم.
توابع بازگشتی
این توابع، توابعی هستند که خروجی آنها، بستگی به عملیات هایی دارد که قبل از آن انجام شده است. معروف ترین توابع بازگشتی، توابع فاکتوریل و فیبوناچی هستند. گرچه، اگر نیاز باشد که تابع درون خودش، صدا زده شود، آن تابع بازگشتی است و نیازی نیست که حتما از توابع بازگشتی معروف باشد.
تابع چاپ یک متن
فرض کنیم میخواهیم یک صفحه را با یک متن پر کنیم، صرفا برای این که تست کنیم متن چه رفتاری در صفحه ما دارد و یک نمونه داشته باشیم. برای نوشتن چنین متنی، کافیست این گونه عمل کنیم :
def _printLines(n)
if n > 0
puts "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur semper."
_printLines(n - 1)
end
end
در این تابع، به این شکل عمل می شود، که ابتدا بررسی میکند n از صفر بزرگتر است یا خیر. در صورت بزرگتر بودن، آنقدر این تابع صدا زده می شود که مقدار n با صفر برابر شود. در این صورت است که متنی که به تابع داده ایم، به تعداد دلخواه ما چاپ می شود.
تابع فاکتوریل
این تابع نیز از معروف ترین توابع بازگشتی است. تعریف ریاضی این تابع به این شکل است :
f(n) -> n * f(n - 1)
اکنون، بیایید این تابع را در روبی بازنویسی کنیم. باید در نظر داشته باشیم که صفر فاکتوریل، به صورت قراردادی، برابر با یک در نظر گرفته می شود. پس تابع ما به این شکل خواهد بود :
def factorial(n)
if n == 0
return 1
else
return n * factorial(n - 1)
end
end
در اینجا نیز، همانند قبل، چک می شود که آیا مقدار n برابر صفر است یا خیر. سپس آنقدر این تابع صدا زده می شود که مقدار n صفر شده، و سپس ضرب ها انجام میگیرند.
جمع بندی
در این فصل، فرا گرفتیم که چگونه برنامه های خود را ماژولار تر و بهینه تر بنویسیم. فایده این نوع برنامه نویسی این است که توابع نوشته شده توسط ما در یک برنامه ، ممکن است بعد ها در برنامه های دیگر خودمان یا دیگران به کار بیاید. به این شکل، میتوان یک کتابخانه خوب از توابع مورد نیاز تولید کرد تا در صورت نیاز، از آن استفاده کنیم. در فصلهای آتی، وارد مباحث پیشرفته تر و در نهایت کاربردهای روبی خواهیم شد.