آشنایی با بلوک Ruby – به زبان ساده

بلوک چیست؟
بلوکها تابعهای بینامی هستند که مقدار بازگشتی آنها روی متدی که آنها را فراخوانی کرده اعمال میشود. این تعریف شاید چندان روشن نباشد، بنابراین در ادامه آن را بیشتر توضیح میدهیم.
بلوکها شامل کدی بین مجموعهای از آکولادها یا یک جفت do/end هستند. آکولادها یک تعریف تکخطی ارائه میکنند و جفت do/end یک تعریف چندخطی در اختیار ما قرار میدهد:
چگونه بلوک بسازیم؟
اگر بخواهیم یک تابع ساده بسازیم که یک ورودی که داخل “⭐️” قرار گرفته است را پرینت کند، باید چیزی مانند زیر بنویسیم:
اگر بخواهیم این تابع را با استفاده از نمادگذاری بلوک بازنویسی کنیم، به صورت زیر عمل میکنیم:
چنان که میبینید، مقدار بازگشتی محتوای بلوک، آن چیزی است که به کلیدواژه yield تابع ارسال شده است. همچنین میتوانیم بلوک را با ارسال پارامترهایی به تابعی که ایجاد کردهایم، سفارشیسازی کنیم:
اگر بخواهیم به مقدار خروجی تابع خود در بلوک الصاقی ارجاع بدهیم، میتوانیم آرگومانهایی به yield ارسال کرده و در پارامترهای بلوک به آنها ارجاع بدهیم:
مزیت بلوک نسبت به تابع معمولی چیست؟
تا به اینجا کار خاصی با بلوک انجام ندادهایم که یک متد معمولی نتواند انجام ندهد. بلوکها در مواردی که بخواهیم منطق اشتراکی را روی چارچوبهای مختلف به روشی آسان اعمال کنیم، مفید واقع میشوند.
برای نمونه فرض کنید، میدانیم که همواره باید خروجی یک سری از دستورها را بین یک مجموعه “⭐⭐⭐” پرینت کنیم. در این حالت میتوانیم از بلوکها استفاده کرده و منطق مورد نظر را روی چارچوبهای مختلف بدون نیاز به تابعهای کمکی اعمال کنیم:
چنان که در کد فوق میبینید ستارهها همواره پیش و پس از کد اجرا شده در بلوک پرینت میشوند. حتی با این که قلب قرمز به روشی بسیار متفاوت از قلب بنفش واکشی میشود، اما متد star_wrap به ما امکان میدهد که منطق پوششی ستاره را روی هر دو چارچوب به روشی یکسان اعمال کنیم.
مدیریت خطای بلوک
هر متدی میتواند یک بلوک بپذیرد، هر چند در تابع ارجاع نیافته باشد. در این حالت محتوای بلوک کاری انجام نمیدهد.
ما میتوانیم همه بلوکها را در مثالهای فوق فراخوانی کنیم، زیرا از کلیدواژه yield استفاده کردهایم. بنابراین شاید بپرسید اگر از کلیدواژه yield استفاده کنیم و بلوکی ارائه نکنیم، چه اتفاقی میافتد؟ در این حالت یک خطا ایجاد میشود.
با استفاده از عبارت ?block_given برای بررسی کاربرد بلوک، میتوانیم از بروز این خطا جلوگیری کنیم:
ارسال بلوک به عنوان یک پارامتر
اگر بخواهیم در مورد فراخوانی یک بلوک با صراحت عمل و یک ارجاع به آن بدهیم، باید آن را به صورت یک پارامتر به متدی ارسال کنیم:
در این نمونه، بلوک به شیء Proc تبدیل میشود که میتوان با استفاده از.call آن را فراخوانی کرد. استفاده از بلوکها به این ترتیب در مواردی مفید است که بخواهیم بلوکها را بین تابعها ارسال کنیم. بدین ترتیب پارامتر بلوک را به عنوان آخرین آرگومان و الصاق یک & ارسال میکنیم.
در ادامه متدهای star_wrap_a و star_wrap_b دقیقاً همین کار را انجام میدهند:
کاربرد عملی بلوکها
در یک اپلیکیشن پیشفرض روبی، نمای application.html.erb برای هر صفحهای که کنترلر آن از ApplicationController ارثبری میکند بارگذاری خواهد شد. اگر یک کنترلر فرزند ApplicationController اقدام به رندر یک نما بکند، محتوای آن به application.html.erb ارسال میشود. با توجه به این کارکرد، کد HTML آماده که باید روی همه صفحههای اپلیکیشن اعمال شود، به سهولت انجام مییابد.
برای نمونه در وبسایت زیر، نوار فوقانی آبی رنگ در یک فایل نمای پایه قرار دارد که لیآوت متفاوتی برای هر مسیر ایجاد میکند.

سخن پایانی
لزومی نیست که بلوکها دارای منطق پیچیدهای باشد تا بتوانیم از آنها استفاده کنیم. بلوکها به طور معمول برای تجرید منطق مشترکی که باید روی چارچوبهای مختلف اعمال شود، مورد استفاده قرار میگیرند. اگر بلوکها را به طرز فکرشدهای بنویسیم، کد اصل DRY را بهتر رعایت میکند و خوانایی کد افزایش مییابد.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- راهنمای سریع متدهای آرایه در Ruby — از صفر تا صد
- مجموعه آموزشهای دروس علوم و مهندسی کامپیوتر
- ساخت اپلیکیشن اینستاگرام با Ruby on Rails (بخش اول) — از صفر تا صد
- ساختمان های داده در روبی (Ruby) — درخت های دودویی
==
مطالب مجله فرادرس را در جستجوی گوگل سریعتر ببینید












