itm7.com
چهارشنبه 28 اسفند 1392, 16:51 عصر
با محیط "زمان اجرای پویا" (DLR) در Net. آشنا شوید (http://www.shabakeh-mag.com/article.aspx?id=1008588)
ماهنامه شبکه - بهمن 1392 شماره 135
http://www.shabakeh-mag.com/Data/Articles/Items/2014/3/1008588.jpg
» حمیدرضا تائبی
اشاره: ماهنامه شبکه - برنامهنویسی به معنی حل یک مشکل به روشهای ساختیافته و اصولی با استفاده از ابزارها و امکانات موجود به شیوه بهینه است.
برنامهنویسی به معنی حل یک مشکل به روشهای ساختیافته و اصولی با استفاده از ابزارها و امکانات موجود به شیوه بهینه است. اما همانگونه که اطلاع دارید، هر شاخهای در کامپیوتر از زیرشاخههای متعددی ساخته شده است، دنیای برنامهنویسی نیز از این قاعده مستثنی نیست. بهطوری که زیرشاخههای مختلفی که اغلب زبانهای برنامهنویسی در آنها قرار میگیرند را شامل میشود که هر کدام از آنها بسته به موقعیت و مکانی خاص مورد استفاده قرار میگیرند. بهطور مثال، زمانیکه نیازمند برنامهنویسی سطح پایین (دسترسی به منابع فیزیکی سختافزاری) یا نیازمند دسترسی و دستکاری دادههایی هستیدکه در حافظه کامپیوتر قرار دارند، یا زمانیکه نیازمند طراحی صفحات وب هستید زبان برنامهنویسی اسمبلی بهترین گزینه است و عاقلانه نیست که از زبانی همانند زبان سیپلاسپلاس برای این منظور استفاده کنید. اما خود زبانهای برنامهنویسی به لحاظ گرامر و ترکیب نحوی نیز تفاوتهایی با یکدیگر دارند، بهعنوان، مثال زبان F# عموماً بهعنوان یک برنامهنویسی تابعی شناخته میشود یا HTML یک زبان اسکرپیتنویسی است (زبان مرورگرهای وب). اما یکی از شاخههای مهمی که در دنیای برنامهنویسی امروز بهطور گسترده مورد استفاده قرار میگیرد، برنامهنویسی پویا است. برنامهنویسی پویا فناوری جدیدی نیست و قدمت به نسبت زیادی دارد. بهطوریکه در زمان زبانهای برنامهنویسی سی و جاوا نیز وجود داشت. در زبانهای برنامهنویسی پویا عمل بررسی یک شئ تا زمانیکه برنامه اجرا نشود، انجام نمیگیرد و در آن زمان است که اگر خطایی وجود داشته باشد، پیغام خطایی نشان داده میشود. اما برای اینکه درک بهتری از زبانهای برنامهنویسی پویا و همچنین قابلیتهایی که چارچوب داتنت در این زمینه دراختیار برنامهنویسان قرار میدهد آشنا شوید در این مقاله بر آن شدیم تا بهطور مختصر به معرفی این قالب و همچنین نحوه پیادهسازی اشیاء پویا در داتنت بپردازیم. Dynamic Language Runtime چیست؟
DLR برای نخستینبار در سال 2007 تحت عنوان پروژه MIX توسط مایکروسافت معرفی شد. در سال 2009 نسخه بتای DLR 0.9 و در دسامبر همان سال نسخه نهایی آن عرضه شد. در سال 2010 نسخه 1 آن همراه با داتنت 4 و بهعنوان یکی از اجزای داتنت عرضه شد. شکل1 چرخه تکامل قابلیتهای برنامهنویسی پویا را نشان میدهد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2001.jpg
یکی از مزیتهای پروژه DLR که باعث شده مورد توجه طراحان زبانهای برنامهنویسی قرار گیرد، منبع باز بودن آن است که روی CodePlex قرار دارد و همین موضوع باعث شده پیادهکنندگان زبان توانایی اضافه کردن قابلیتهای بیشتر را روی DLR داشته باشند. DLR یک محیط زمان اجرای پویا است که روی محیط زمان اجرا CLR (سرنامCommon Language Runtime ) اجرا شده و مجموعهای از سرویسها را برای زبانهای برنامهنویسی پویا ویژه محیط زمان اجرا CLR فراهم میکند.
این سرویسها عبارتند از:
- Dynamic type system که با همه زبانهایی که از سرویسهای DLR استفاده میکنند به اشتراک گذاشته شده است.
- Dynamic Method dispatch
- Dynamic code generation
- Hosting Api
DLR به طورعمده با هدف پیادهسازی زبانهای برنامهنویسی پویا روی داتنت بهخصوص IronPython و IronRuby مورد استفاده قرار میگیرد. با داشتن و پیادهسازی چندین زبان برنامهنویسی پویا که از یک سیستم مشترک استفاده میکنند پیادهسازی پروژههایی که ارتباط متقابل با یکدیگر دارند کار چندان سختی نخواهد بود. بهطور مثال، میتوانید از کتابخانههای نوشته شده در زبانهای پویا بهطور مشترک استفاده کرد. همچنین میتوانید از زبانهای CIL شبیه به سیشارپ و ویژوالبیسیک نیز در این زبانها بهره ببرید. اما یکی از وظایف DLR اضافه کردن قابلیتهای ویژه به زبانهای برنامهنویسی ایستا است. به نحوی که با استفاده از آنها میتوانید به برنامهنویسی پویا بپردازید. بهطور کلی DLR با معرفی اشیای پویا در زبانهایی مانند سیشارپ و ویژوال بیسیک، امکان پیادهسازی رفتار پویا در این زبانها را امکانپذیر ساخته است.
از زبانهای برنامهنویسی پویا میتوان به لیسپ، اسمال تاک،PHP، راب، پایتون، ColdFusion ،Lua، کبرا و Groovy اشاره کرد. به طور کلی زبانهای برنامهنویسی پویا قابلیتهای زیر را در اختیار طراحان و توسعهدهندگان قرار میدهند:
1- توانایی وارد کردن چند دستور و اجرای بیدرنگ آنها برای مشاهده نتیجه تولید شده توسط آنها.
2- پشتیبانی از هر دو حالت طراحی بالا به پایین و طراحی سنتی پایین به بالا. برای مثال، زمانیکه از حالت بالا به پایین استفاده میکنید، میتوانید توابعی را فراخوانی کنید که هنوز پیادهسازی نشدهاند و در ادامه زمانیکه به آنها نیازدارید، پیادهسازی آنها را انجام دهید. (این موضوع را در بخش عملی مقاله نشان خواهیم داد.)
3- اصلاح سادهتر دستورات و کدها، بهدلیل اینکه نیازی به تغییر تعاریف نوعهای ایستا در طول کدهایتان نخواهید داشت.
زبانهای برنامهنویسی پویا به طورعمده برای ساخت سایتها و بررسی تحت کنترل سایتها، پیادهسازی انواع مختلفی از ابزارهای کاربردی و تغییر دادهها به شیوه بهینه مورد استفاده قرار میگیرد.
بهطور کلی زبانهای برنامهنویسی پویا بهعنوان زبانهای برنامهنویسی سطح بالایی که در زمان اجرا، اجرا شده و رفتارهای یکسانی با دیگر زبانهای ایستا دارند، شناخته میشوند؛ با این تفاوت که این رفتارها بهجای اینکه در زمان کامپایل انجام شوند در زمان اجرا انجام میشوند. بسیاری از ما در بیشتر زمانها وقت خود را صرف زبانهای برنامهنویسی ایستا میکنیم اما تفاوت این دو سبک از برنامهنویسی در چیست؟ دیاگرام شکل2 تفاوتهای این دو گروه را نشان میدهد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2002.jpg
ساختار DLR
شکل3 معماری محیط زمان اجرای پویا را نشان میدهد. همانگونه که در این شکل مشاهده میکنید، DLR با اضافه کردن چند سرویس به CLR پشتیبانی بهتری را از زبانهای پویا به عمل میآورد. این سرویسها عبارتند از:
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2003.jpg
DLR:Expression trees از این قابلیت برای نمایش ترکیب معنایی زبانها استفاده میشود. برای این منظور DLR عبارتهای LINQ را بسط و توسعه داده است که شامل مواردی همچون کنترل جریان، واگذاری و دیگر مؤلفههای مربوط به LINQ است.
Call site caching: dynamic call site مکانی در دستورات است که در آن عملیاتی شبیه به جمع a+b یا ضرب a.b روی اشیای پویا انجام میگیرد. DLR مشخصات مربوط به a و b و اطلاعاتی درباره این عملیات را Cache یا ذخیره میکند. به این شکل اگر عملی قبلاً انجام شده باشد، DLR همه اطلاعات موردنیاز را برای اعزام dispatch از حافظه نهان (Cache) دریافت میکند. همین موضوع باعث بالارفتن سرعت انجام محاورهها و افزایش کارایی میشود.
DLR:Dynamic object interoperability مجموعهای از کلاسها و رابطهایی که نشاندهنده اشیای پویا و عملیاتی که میتواند توسط پیادهکنندگان زبان و نویسندگان کتابخانههای پویا مورد استفاده قرار گیرد را فراهم میکند. این کلاسها و رابطها عبارتند از: IDynamicMetaObjectProvider ،DynamicMetaObject ،DynamicObject، و ExpandoObject. این قابلیت به زبانهای متفاوت اجازه میدهد که با یکدیگر در ارتباط باشند.
ساخت و بهکارگیری اشیای پویا در داتنت (سیشارپ)
اشیای پویا از این خصلت بهره میبرند که اعضایی از قبیل خاصیتها و متدهایی را در زمان اجرا به جای زمان کامپایل معرفی کرده و نشان دهند. این قابلیت به کاربر اجازه میدهد اشیایی را بسازد که با ساختارهایی که در شرایط عادی با انواع ایستا هماهنگ نبوده یا هم قالب (format) نیستند را بسازد. بهطور مثال، میتوان یک شئ پویا را برای ارجاع به (Dom) م HTML Document Object Model استفاده کرد که میتواند شامل ترکیبی از عناصر معتبر HTML و خصلتها با یکدیگر باشد. اشیای پویا همچنین دسترسی راحت به زبانهای پویایی از قبیل IRonPython و IronRuby را نیز ارائه میدهند. اما همانگونه که در ابتدای مقاله به آن اشاره شد، مایکروسافت برای نخستینبار در نسخه 2010 ویژوال استودیو
DLR را بهطور مستقیم در داتنت وارد کرد و همچنین نوع جدیدی بهنام dynamic را نیز در داتنت 4 قرار داد. نوعی که خود بهصورت ذاتی ایستا است اما یک نوع پویا dynamic را به شیوه غیرمستقیم بعد از بررسی کردن نوع ایستا ارائه میکند. این شئ در بیشتر حالات رفتاری شبیه به یک شئ (object) دارند. در زمان کامپایل برنامه کاربردی هر عنصری که بهصورت dynamic برچسب زده میشود، از هر عملی پشتیبانی میکند. از اینرو لازم نیست نگران این موضوع باشید که آیا این شئ یک مقدار معتبر COM API، شیئی دریافت شده از زبانهای برنامهنویسی پویا مثل Ironpython، شیئی از HTML Document Object Model، شیئی از نوع reflection است یا از جایی خارج از برنامه کاربردیتان دریافت شده است؛ تنها باید این موضوع را بدانید که اگر مقادیر دریافتی معتبر نباشد در زمان اجرا پیغام خطا دریافت خواهید کرد.
در سیشارپ برای تعریف یک شئ پویا از کلمه کلیدی dynamic استفاده میشود. شیئی که با این کلمه کلیدی تعریف میشود در زمان کدنویسی و کامپایل هنوز نوع خاصی ندارد و این در زمان اجرا است که نوع آن مشخص میشود.
در ادامه با چند مثال ساده نحوه پیادهسازی این شئ و ارتباط متقابل آنرا با اشیا و متدها نشان دهیم. (البته پیادهسازی شئ dynamic بسیار گستردهتر از آن چیزی است که در ادامه مشاهده میکنید).
استنناج مقادیر در زمان اجرا
یکی از خصوصیات برجسته و شاخص در زمان کار با اشیای پویا عدم وابستگی آنها به نوع داده تعریف شده برای آنها است. (البته شئ var نیز عملکرد مشابهی دارد اما در مقایسه با نوع dynamic از محدودیتهایی برخوردار است.) همانگونه که در قطعه کد فهرست1 مشاهده میکنید، تعریف شئ پویا با استفاده از کلمه کلید dynamic انجام میشود.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%20f1.jpg
در ادامه انواع مختلفی از نوعهای دادهای استاندارد داتنت بهطور مستقیم به آن اختصاص داده میشود، اما نکته جالب، عدم آگاهی کامپایلر از این نوعها تا زمان اجرای برنامه است. زمانیکه قطعه کد فهرست1 اجرا میشود خروجی آن همانند شکل 4 خواهد بود.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2004.jpg
نحوه فراخوانی متدها توسط اشیای پویا
در قطعه کد فهرست2 همانگونه که مشاهده میکنید، یک شئ پویا بهنام mydynamic با استفاده از کلمه کلیدی dynamic تعریف شده است.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%20f2.jpg
در ادامه متد Method1 فراخوانی میشود. اگر در حالت عادی متد Method1 را به این شکل مورد فراخوانی قرار دهید، کامپایلر سیشارپ پیغام خطای شکل5 را صادر میکند.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2005.jpg
با تعریف پویا کامپایلر هیچ پیغام خطایی را تولید نمیکند، اما این به معنای نبود اشکال نیست. در نتیجه اگر برنامهنویس در زمان تعریف و نحوه بهکارگیری متدها دقت لازم را نداشته باشد و قطعه کد فهرست2 را اجرا کند. در زمان اجرای برنامه پیغام خطایی که در شکل 6 مشاهده میکنید را دریافت خواهد کرد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2006.jpg
نکته جالب دیگری که در این قطعهکد وجود دارد، نبود متدهای nonexistentMethod و someMethod در برنامه است. اما کامپایلر هیچگونه پیغامی خطایی در خصوص نبود این متدها در زمان کامپایل برنامه صادر نکرد، در صورتیکه در زمان اجرای برنامه یک استثنا در خصوص نبود این متدها تولید میشود. این یکی از خصوصیات اشیای پویا است. اما برای حل استثناهایی به این شکل که در زمان اجرا تولید میشوند، میتوانید از کلاس RuntimeBinderExcpetion استفاده کنید.
نبود IntelliSense
نکته مهم دیگری که درمورد نوعهای پویا باید به آن توجه کنید، قابلیت IntelliSense است که در ویژوال استودیو بهطور گسترده مورد استفاده قرار میگیرد و اطلاعاتی را درمورد اشیای مورد استفاده در برنامه نشان میدهد. اما درمورد اشیای پویا، اگر اشارهگر ماوس را روی این اشیا نگه دارید، بهجای نشان دادن نوع شئ مورد استفاده چیزی مشابه شکل7 را مشاهده خواهید کرد. البته این موضوع امری طبیعی و عادی قلمداد میشود، زیرا کامپایلر هیچ تفسیر معنایی از شئ که ساخته شده است در اختیار ندارد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2007.jpg
تبدیل اشیای پویا به نوعهای دیگر
در دنیای داتنت تبدیل اشیاء به یکدیگر بهطور معمول نیازمند دقت و توجه است. بعضی از مقادیر بهصورت صریح و بعضی دیگر بهصورت ضمنی به یکدیگر تبدیل میشوند. در عملیات boxing و unboxing بهطور معمول برنامهنویس باید به نوعهایی که به یکدیگر تبدیل میکند توجه داشته باشد. اما تبدیل اشیای پویا به دیگر نوعهای دادهایی به آسانی انجام میشود. همین موضوع سبب میشود که طراح به آسانی از نوع پویا به انواع دیگر سوئیچ کند. هر عمل تبدیل یک شئ به نوع پویا و برعکس میتواند بهصورت ضمنی تبدیل شود. مثالهای نشان داده شده در فهرست 3 نمونهای از این موارد به شمار میرود.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%20f3.jpg
در نهایت
در این مقاله سعی شد به اختصار و بسیار کوتاه به معرفی DLR، ساختار بهکاررفته در آن و تفاوتهایی که زبانهای برنامهنویسی پویا و ایستا با یکدیگر دارند اشاره کنیم. (البته ذکر تمامی نکات در یک مقاله امکانپذیر نیست. بهطور مثال ما در این مقاله اشارهای به کلاسهایی همچون ExpandoObject که برای اضافه کردن یا حذف اشیا در زمان اجرا مورد استفاده قرار میگیرند، نپرداختیم.) همچنین دیدیم که مایکروسافت پروژه DLR را بهصورت کد منبع باز دراختیار توسعهدهندگان زبانهای برنامهنویسی قرار داده است تا بتوانند قابلیتهایی که در آن وجود ندارد را خود در زبانهایی که پیادهسازی میکنند، اضافه کنند.
در ادامه با نحوه ساخت و بهکارگیری اشیای پویا در سیشارپ آشنا شدیم و دیدیم که بهکارگیری آنها در سیشارپ به آسانی امکانپذیر است؛ اشیایی که از قدرت بالایی بهره میبرند و در بسیاری موارد راهگشا خواهند بود. به عنوان مثال، در زمانهایی که از انواع استاندارد استفاده میکنید باید یکسری تبدیلات را انجام دهید، با استفاده از اشیای پویا بدون نیاز به تبدیل میتوانید این عملیات را مدیریت کنید (بهعنوان مثال، فرض کنید یک شئ را از نوع object تعریف کردهاید و حالا میخواهید یک عمل محاسبات ریاضی را روی آن انجام دهید، در شرایط عادی نیازمند یک تبدیل هستید در غیراین صورت کامپایلر به شما پیغام خطا نشان میدهد، در صورتیکه درمورد اشیای پویا این امر به آسانی و بدون هیچگونه کار اضافی امکانپذیر میشود.)
همچنین نوعهای پویا در زمانهایی که نوعهای ایستا نتوانند به آسانی مورد استفاده قرار گیرند به یاری برنامهنویسان رسیده و مشکلات آنها را بر طرف میکنند. همچنین این نکته را نیز بدانید که عملیات پویا خودشان یک مقدار dynamic تولید میکنند.
منابع
Using Type dynamic (C# Programming Guide) (http://msdn.microsoft.com/en-us/library/dd264736%28v=vs.110%29.aspx)
C# 4.0 – Dynamic Language Runtime - Bruno Terkaly - Developer Evangelist - bterkaly@microsoft.com - Site Home - MSDN Blogs (http://blogs.msdn.com/b/brunoterkaly/archive/2009/07/23/c-4-0-dynamic-language-runtime.aspx)
Dynamic Language Runtime - Wikipedia, the free encyclopedia (http://en.wikipedia.org/wiki/Dynamic_Language_Runtime)
Dynamic Language Runtime Overview (http://msdn.microsoft.com/en-us/library/dd233052%28v=vs.110%29.aspx)
مرجع منابع (http://itm7.com)
ماهنامه شبکه - بهمن 1392 شماره 135
http://www.shabakeh-mag.com/Data/Articles/Items/2014/3/1008588.jpg
» حمیدرضا تائبی
اشاره: ماهنامه شبکه - برنامهنویسی به معنی حل یک مشکل به روشهای ساختیافته و اصولی با استفاده از ابزارها و امکانات موجود به شیوه بهینه است.
برنامهنویسی به معنی حل یک مشکل به روشهای ساختیافته و اصولی با استفاده از ابزارها و امکانات موجود به شیوه بهینه است. اما همانگونه که اطلاع دارید، هر شاخهای در کامپیوتر از زیرشاخههای متعددی ساخته شده است، دنیای برنامهنویسی نیز از این قاعده مستثنی نیست. بهطوری که زیرشاخههای مختلفی که اغلب زبانهای برنامهنویسی در آنها قرار میگیرند را شامل میشود که هر کدام از آنها بسته به موقعیت و مکانی خاص مورد استفاده قرار میگیرند. بهطور مثال، زمانیکه نیازمند برنامهنویسی سطح پایین (دسترسی به منابع فیزیکی سختافزاری) یا نیازمند دسترسی و دستکاری دادههایی هستیدکه در حافظه کامپیوتر قرار دارند، یا زمانیکه نیازمند طراحی صفحات وب هستید زبان برنامهنویسی اسمبلی بهترین گزینه است و عاقلانه نیست که از زبانی همانند زبان سیپلاسپلاس برای این منظور استفاده کنید. اما خود زبانهای برنامهنویسی به لحاظ گرامر و ترکیب نحوی نیز تفاوتهایی با یکدیگر دارند، بهعنوان، مثال زبان F# عموماً بهعنوان یک برنامهنویسی تابعی شناخته میشود یا HTML یک زبان اسکرپیتنویسی است (زبان مرورگرهای وب). اما یکی از شاخههای مهمی که در دنیای برنامهنویسی امروز بهطور گسترده مورد استفاده قرار میگیرد، برنامهنویسی پویا است. برنامهنویسی پویا فناوری جدیدی نیست و قدمت به نسبت زیادی دارد. بهطوریکه در زمان زبانهای برنامهنویسی سی و جاوا نیز وجود داشت. در زبانهای برنامهنویسی پویا عمل بررسی یک شئ تا زمانیکه برنامه اجرا نشود، انجام نمیگیرد و در آن زمان است که اگر خطایی وجود داشته باشد، پیغام خطایی نشان داده میشود. اما برای اینکه درک بهتری از زبانهای برنامهنویسی پویا و همچنین قابلیتهایی که چارچوب داتنت در این زمینه دراختیار برنامهنویسان قرار میدهد آشنا شوید در این مقاله بر آن شدیم تا بهطور مختصر به معرفی این قالب و همچنین نحوه پیادهسازی اشیاء پویا در داتنت بپردازیم. Dynamic Language Runtime چیست؟
DLR برای نخستینبار در سال 2007 تحت عنوان پروژه MIX توسط مایکروسافت معرفی شد. در سال 2009 نسخه بتای DLR 0.9 و در دسامبر همان سال نسخه نهایی آن عرضه شد. در سال 2010 نسخه 1 آن همراه با داتنت 4 و بهعنوان یکی از اجزای داتنت عرضه شد. شکل1 چرخه تکامل قابلیتهای برنامهنویسی پویا را نشان میدهد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2001.jpg
یکی از مزیتهای پروژه DLR که باعث شده مورد توجه طراحان زبانهای برنامهنویسی قرار گیرد، منبع باز بودن آن است که روی CodePlex قرار دارد و همین موضوع باعث شده پیادهکنندگان زبان توانایی اضافه کردن قابلیتهای بیشتر را روی DLR داشته باشند. DLR یک محیط زمان اجرای پویا است که روی محیط زمان اجرا CLR (سرنامCommon Language Runtime ) اجرا شده و مجموعهای از سرویسها را برای زبانهای برنامهنویسی پویا ویژه محیط زمان اجرا CLR فراهم میکند.
این سرویسها عبارتند از:
- Dynamic type system که با همه زبانهایی که از سرویسهای DLR استفاده میکنند به اشتراک گذاشته شده است.
- Dynamic Method dispatch
- Dynamic code generation
- Hosting Api
DLR به طورعمده با هدف پیادهسازی زبانهای برنامهنویسی پویا روی داتنت بهخصوص IronPython و IronRuby مورد استفاده قرار میگیرد. با داشتن و پیادهسازی چندین زبان برنامهنویسی پویا که از یک سیستم مشترک استفاده میکنند پیادهسازی پروژههایی که ارتباط متقابل با یکدیگر دارند کار چندان سختی نخواهد بود. بهطور مثال، میتوانید از کتابخانههای نوشته شده در زبانهای پویا بهطور مشترک استفاده کرد. همچنین میتوانید از زبانهای CIL شبیه به سیشارپ و ویژوالبیسیک نیز در این زبانها بهره ببرید. اما یکی از وظایف DLR اضافه کردن قابلیتهای ویژه به زبانهای برنامهنویسی ایستا است. به نحوی که با استفاده از آنها میتوانید به برنامهنویسی پویا بپردازید. بهطور کلی DLR با معرفی اشیای پویا در زبانهایی مانند سیشارپ و ویژوال بیسیک، امکان پیادهسازی رفتار پویا در این زبانها را امکانپذیر ساخته است.
از زبانهای برنامهنویسی پویا میتوان به لیسپ، اسمال تاک،PHP، راب، پایتون، ColdFusion ،Lua، کبرا و Groovy اشاره کرد. به طور کلی زبانهای برنامهنویسی پویا قابلیتهای زیر را در اختیار طراحان و توسعهدهندگان قرار میدهند:
1- توانایی وارد کردن چند دستور و اجرای بیدرنگ آنها برای مشاهده نتیجه تولید شده توسط آنها.
2- پشتیبانی از هر دو حالت طراحی بالا به پایین و طراحی سنتی پایین به بالا. برای مثال، زمانیکه از حالت بالا به پایین استفاده میکنید، میتوانید توابعی را فراخوانی کنید که هنوز پیادهسازی نشدهاند و در ادامه زمانیکه به آنها نیازدارید، پیادهسازی آنها را انجام دهید. (این موضوع را در بخش عملی مقاله نشان خواهیم داد.)
3- اصلاح سادهتر دستورات و کدها، بهدلیل اینکه نیازی به تغییر تعاریف نوعهای ایستا در طول کدهایتان نخواهید داشت.
زبانهای برنامهنویسی پویا به طورعمده برای ساخت سایتها و بررسی تحت کنترل سایتها، پیادهسازی انواع مختلفی از ابزارهای کاربردی و تغییر دادهها به شیوه بهینه مورد استفاده قرار میگیرد.
بهطور کلی زبانهای برنامهنویسی پویا بهعنوان زبانهای برنامهنویسی سطح بالایی که در زمان اجرا، اجرا شده و رفتارهای یکسانی با دیگر زبانهای ایستا دارند، شناخته میشوند؛ با این تفاوت که این رفتارها بهجای اینکه در زمان کامپایل انجام شوند در زمان اجرا انجام میشوند. بسیاری از ما در بیشتر زمانها وقت خود را صرف زبانهای برنامهنویسی ایستا میکنیم اما تفاوت این دو سبک از برنامهنویسی در چیست؟ دیاگرام شکل2 تفاوتهای این دو گروه را نشان میدهد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2002.jpg
ساختار DLR
شکل3 معماری محیط زمان اجرای پویا را نشان میدهد. همانگونه که در این شکل مشاهده میکنید، DLR با اضافه کردن چند سرویس به CLR پشتیبانی بهتری را از زبانهای پویا به عمل میآورد. این سرویسها عبارتند از:
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2003.jpg
DLR:Expression trees از این قابلیت برای نمایش ترکیب معنایی زبانها استفاده میشود. برای این منظور DLR عبارتهای LINQ را بسط و توسعه داده است که شامل مواردی همچون کنترل جریان، واگذاری و دیگر مؤلفههای مربوط به LINQ است.
Call site caching: dynamic call site مکانی در دستورات است که در آن عملیاتی شبیه به جمع a+b یا ضرب a.b روی اشیای پویا انجام میگیرد. DLR مشخصات مربوط به a و b و اطلاعاتی درباره این عملیات را Cache یا ذخیره میکند. به این شکل اگر عملی قبلاً انجام شده باشد، DLR همه اطلاعات موردنیاز را برای اعزام dispatch از حافظه نهان (Cache) دریافت میکند. همین موضوع باعث بالارفتن سرعت انجام محاورهها و افزایش کارایی میشود.
DLR:Dynamic object interoperability مجموعهای از کلاسها و رابطهایی که نشاندهنده اشیای پویا و عملیاتی که میتواند توسط پیادهکنندگان زبان و نویسندگان کتابخانههای پویا مورد استفاده قرار گیرد را فراهم میکند. این کلاسها و رابطها عبارتند از: IDynamicMetaObjectProvider ،DynamicMetaObject ،DynamicObject، و ExpandoObject. این قابلیت به زبانهای متفاوت اجازه میدهد که با یکدیگر در ارتباط باشند.
ساخت و بهکارگیری اشیای پویا در داتنت (سیشارپ)
اشیای پویا از این خصلت بهره میبرند که اعضایی از قبیل خاصیتها و متدهایی را در زمان اجرا به جای زمان کامپایل معرفی کرده و نشان دهند. این قابلیت به کاربر اجازه میدهد اشیایی را بسازد که با ساختارهایی که در شرایط عادی با انواع ایستا هماهنگ نبوده یا هم قالب (format) نیستند را بسازد. بهطور مثال، میتوان یک شئ پویا را برای ارجاع به (Dom) م HTML Document Object Model استفاده کرد که میتواند شامل ترکیبی از عناصر معتبر HTML و خصلتها با یکدیگر باشد. اشیای پویا همچنین دسترسی راحت به زبانهای پویایی از قبیل IRonPython و IronRuby را نیز ارائه میدهند. اما همانگونه که در ابتدای مقاله به آن اشاره شد، مایکروسافت برای نخستینبار در نسخه 2010 ویژوال استودیو
DLR را بهطور مستقیم در داتنت وارد کرد و همچنین نوع جدیدی بهنام dynamic را نیز در داتنت 4 قرار داد. نوعی که خود بهصورت ذاتی ایستا است اما یک نوع پویا dynamic را به شیوه غیرمستقیم بعد از بررسی کردن نوع ایستا ارائه میکند. این شئ در بیشتر حالات رفتاری شبیه به یک شئ (object) دارند. در زمان کامپایل برنامه کاربردی هر عنصری که بهصورت dynamic برچسب زده میشود، از هر عملی پشتیبانی میکند. از اینرو لازم نیست نگران این موضوع باشید که آیا این شئ یک مقدار معتبر COM API، شیئی دریافت شده از زبانهای برنامهنویسی پویا مثل Ironpython، شیئی از HTML Document Object Model، شیئی از نوع reflection است یا از جایی خارج از برنامه کاربردیتان دریافت شده است؛ تنها باید این موضوع را بدانید که اگر مقادیر دریافتی معتبر نباشد در زمان اجرا پیغام خطا دریافت خواهید کرد.
در سیشارپ برای تعریف یک شئ پویا از کلمه کلیدی dynamic استفاده میشود. شیئی که با این کلمه کلیدی تعریف میشود در زمان کدنویسی و کامپایل هنوز نوع خاصی ندارد و این در زمان اجرا است که نوع آن مشخص میشود.
در ادامه با چند مثال ساده نحوه پیادهسازی این شئ و ارتباط متقابل آنرا با اشیا و متدها نشان دهیم. (البته پیادهسازی شئ dynamic بسیار گستردهتر از آن چیزی است که در ادامه مشاهده میکنید).
استنناج مقادیر در زمان اجرا
یکی از خصوصیات برجسته و شاخص در زمان کار با اشیای پویا عدم وابستگی آنها به نوع داده تعریف شده برای آنها است. (البته شئ var نیز عملکرد مشابهی دارد اما در مقایسه با نوع dynamic از محدودیتهایی برخوردار است.) همانگونه که در قطعه کد فهرست1 مشاهده میکنید، تعریف شئ پویا با استفاده از کلمه کلید dynamic انجام میشود.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%20f1.jpg
در ادامه انواع مختلفی از نوعهای دادهای استاندارد داتنت بهطور مستقیم به آن اختصاص داده میشود، اما نکته جالب، عدم آگاهی کامپایلر از این نوعها تا زمان اجرای برنامه است. زمانیکه قطعه کد فهرست1 اجرا میشود خروجی آن همانند شکل 4 خواهد بود.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2004.jpg
نحوه فراخوانی متدها توسط اشیای پویا
در قطعه کد فهرست2 همانگونه که مشاهده میکنید، یک شئ پویا بهنام mydynamic با استفاده از کلمه کلیدی dynamic تعریف شده است.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%20f2.jpg
در ادامه متد Method1 فراخوانی میشود. اگر در حالت عادی متد Method1 را به این شکل مورد فراخوانی قرار دهید، کامپایلر سیشارپ پیغام خطای شکل5 را صادر میکند.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2005.jpg
با تعریف پویا کامپایلر هیچ پیغام خطایی را تولید نمیکند، اما این به معنای نبود اشکال نیست. در نتیجه اگر برنامهنویس در زمان تعریف و نحوه بهکارگیری متدها دقت لازم را نداشته باشد و قطعه کد فهرست2 را اجرا کند. در زمان اجرای برنامه پیغام خطایی که در شکل 6 مشاهده میکنید را دریافت خواهد کرد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2006.jpg
نکته جالب دیگری که در این قطعهکد وجود دارد، نبود متدهای nonexistentMethod و someMethod در برنامه است. اما کامپایلر هیچگونه پیغامی خطایی در خصوص نبود این متدها در زمان کامپایل برنامه صادر نکرد، در صورتیکه در زمان اجرای برنامه یک استثنا در خصوص نبود این متدها تولید میشود. این یکی از خصوصیات اشیای پویا است. اما برای حل استثناهایی به این شکل که در زمان اجرا تولید میشوند، میتوانید از کلاس RuntimeBinderExcpetion استفاده کنید.
نبود IntelliSense
نکته مهم دیگری که درمورد نوعهای پویا باید به آن توجه کنید، قابلیت IntelliSense است که در ویژوال استودیو بهطور گسترده مورد استفاده قرار میگیرد و اطلاعاتی را درمورد اشیای مورد استفاده در برنامه نشان میدهد. اما درمورد اشیای پویا، اگر اشارهگر ماوس را روی این اشیا نگه دارید، بهجای نشان دادن نوع شئ مورد استفاده چیزی مشابه شکل7 را مشاهده خواهید کرد. البته این موضوع امری طبیعی و عادی قلمداد میشود، زیرا کامپایلر هیچ تفسیر معنایی از شئ که ساخته شده است در اختیار ندارد.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%2007.jpg
تبدیل اشیای پویا به نوعهای دیگر
در دنیای داتنت تبدیل اشیاء به یکدیگر بهطور معمول نیازمند دقت و توجه است. بعضی از مقادیر بهصورت صریح و بعضی دیگر بهصورت ضمنی به یکدیگر تبدیل میشوند. در عملیات boxing و unboxing بهطور معمول برنامهنویس باید به نوعهایی که به یکدیگر تبدیل میکند توجه داشته باشد. اما تبدیل اشیای پویا به دیگر نوعهای دادهایی به آسانی انجام میشود. همین موضوع سبب میشود که طراح به آسانی از نوع پویا به انواع دیگر سوئیچ کند. هر عمل تبدیل یک شئ به نوع پویا و برعکس میتواند بهصورت ضمنی تبدیل شود. مثالهای نشان داده شده در فهرست 3 نمونهای از این موارد به شمار میرود.
http://www.shabakeh-mag.com/data/gallery/2014/3/153%20-%20dlr%20-%20f3.jpg
در نهایت
در این مقاله سعی شد به اختصار و بسیار کوتاه به معرفی DLR، ساختار بهکاررفته در آن و تفاوتهایی که زبانهای برنامهنویسی پویا و ایستا با یکدیگر دارند اشاره کنیم. (البته ذکر تمامی نکات در یک مقاله امکانپذیر نیست. بهطور مثال ما در این مقاله اشارهای به کلاسهایی همچون ExpandoObject که برای اضافه کردن یا حذف اشیا در زمان اجرا مورد استفاده قرار میگیرند، نپرداختیم.) همچنین دیدیم که مایکروسافت پروژه DLR را بهصورت کد منبع باز دراختیار توسعهدهندگان زبانهای برنامهنویسی قرار داده است تا بتوانند قابلیتهایی که در آن وجود ندارد را خود در زبانهایی که پیادهسازی میکنند، اضافه کنند.
در ادامه با نحوه ساخت و بهکارگیری اشیای پویا در سیشارپ آشنا شدیم و دیدیم که بهکارگیری آنها در سیشارپ به آسانی امکانپذیر است؛ اشیایی که از قدرت بالایی بهره میبرند و در بسیاری موارد راهگشا خواهند بود. به عنوان مثال، در زمانهایی که از انواع استاندارد استفاده میکنید باید یکسری تبدیلات را انجام دهید، با استفاده از اشیای پویا بدون نیاز به تبدیل میتوانید این عملیات را مدیریت کنید (بهعنوان مثال، فرض کنید یک شئ را از نوع object تعریف کردهاید و حالا میخواهید یک عمل محاسبات ریاضی را روی آن انجام دهید، در شرایط عادی نیازمند یک تبدیل هستید در غیراین صورت کامپایلر به شما پیغام خطا نشان میدهد، در صورتیکه درمورد اشیای پویا این امر به آسانی و بدون هیچگونه کار اضافی امکانپذیر میشود.)
همچنین نوعهای پویا در زمانهایی که نوعهای ایستا نتوانند به آسانی مورد استفاده قرار گیرند به یاری برنامهنویسان رسیده و مشکلات آنها را بر طرف میکنند. همچنین این نکته را نیز بدانید که عملیات پویا خودشان یک مقدار dynamic تولید میکنند.
منابع
Using Type dynamic (C# Programming Guide) (http://msdn.microsoft.com/en-us/library/dd264736%28v=vs.110%29.aspx)
C# 4.0 – Dynamic Language Runtime - Bruno Terkaly - Developer Evangelist - bterkaly@microsoft.com - Site Home - MSDN Blogs (http://blogs.msdn.com/b/brunoterkaly/archive/2009/07/23/c-4-0-dynamic-language-runtime.aspx)
Dynamic Language Runtime - Wikipedia, the free encyclopedia (http://en.wikipedia.org/wiki/Dynamic_Language_Runtime)
Dynamic Language Runtime Overview (http://msdn.microsoft.com/en-us/library/dd233052%28v=vs.110%29.aspx)
مرجع منابع (http://itm7.com)