لوآ (زبان برنامه‌نویسی)

سیده آمین ارمان

کاربر نگاه دانلود
کاربر نگاه دانلود
عضویت
2016/05/10
ارسالی ها
1,730
امتیاز واکنش
20,744
امتیاز
795
محل سکونت
البرز
لوآ یک
Please, ورود or عضویت to view URLs content!
سبُک‌وزن، بازتابنده و امری-تابعی است. زبان لوا با ساختار
Please, ورود or عضویت to view URLs content!
(برنامه‌نویسی اسکریپتی) و با هدف داشتن قابلیت‌های
Please, ورود or عضویت to view URLs content!
طراحی شده است.

فلسفلهٔ اولیه ساخت این زبان، استفاده از آن به عنوان یک زبان عمومی و ساده پردازه‌نویسی بود. جامعه هدف لوا شامل کاربران نیمه حرفه‌ای هم می‌شود. در پردازه‌نویسی برای انجام توصیفات پیچیده از یک زبان نهفته شده در یک زبان دیگر استفاده می‌شود. به خاطر سبک بودن کتابخانه لوا، می‌توان لوا را با تمام قابلیت‌ها به عنوان یک زبان نهفته در
Please, ورود or عضویت to view URLs content!
استفاده نمود. حجم مفسر کامپایل شده حدود ۱۵۰KB است.

در طراحی لوا سعی شده است از فرا ساز و کارها بیشتر استفاده شود تا در عین کوچکی، انعطاف‌پذیری زبان افزایش یابد.
Please, ورود or عضویت to view URLs content!
جدول، داده ساختار اصلی مورد استفاده در این زبان است.

لوا یک مفسر اصلی دارد که توسط طراحان اصلی زبان پیاده‌سازی شده است. این مفسر دارای واسط
Please, ورود or عضویت to view URLs content!
نسبتاً سبک و ساده‌ای است.

هر دوی لوا و
Please, ورود or عضویت to view URLs content!
از اشیاء
Please, ورود or عضویت to view URLs content!
استفاده می‌کنند. آنها هر دو از
Please, ورود or عضویت to view URLs content!
الگو گرفته‌اند. بسیاری از مفاهیم مشترک میان آن‌ها وجود دارد، گرچه تفاوت‌های اساسی در
Please, ورود or عضویت to view URLs content!
دارند. در طراحی لوا شبیه به
Please, ورود or عضویت to view URLs content!
است، شاید به این علت که هر دو از
Please, ورود or عضویت to view URLs content!
تاثیر پذیرفته‌اند.

زبان لوا در طول زمان تغییر می‌کند، قابلیت‌هایی از آن کاسته و قابلیت‌هایی بر آن افزوده می‌شوند. اکنون این زبان در نسخه 5.3.2 قرار دارد (آذر 1394)

لوا در صنعت
Please, ورود or عضویت to view URLs content!
محبوبیت زیادی دارد. به جز بازی‌ها لوا در کاربردهای بسیاری هم تجاری و هم غیرتجاری استفاده شده است. نام این زبان از کلمه
Please, ورود or عضویت to view URLs content!
lua به معنای «ماه» می‌آید.
تاریخچه
لوا در سال 1371 توسط
Please, ورود or عضویت to view URLs content!
، لوییز هنریک دی فیگوئردو و والدمر سلس، اعضای تِکگِراف - گروه تکنولوژی گرافیک کامپیوتر (TecGraph) در PUC-Rio، دانشگاه مسیحی
Please, ورود or عضویت to view URLs content!
در برزیل ساخته شد.

از سال 1355 تا 1370 در برزیل قوانین سخت تجارت خارجی روی سخت‌افزار و نرم‌افزار وجود داشت. این قوانین از انگیزه ملی توانایی ساخت نرم‌افزار و سخت‌افزار در داخل برزیل نشات گرفته بود. این قوانین موجب شد که تکگراف نه از نظر اقتصادی و نه سیـاس*ـی امکان داشته باشد که بتواند نرم‌افزار آماده شده از خارج کشور خریداری کند. به جز این مسئله، جدایی جغرافیای برزیل از بقیه مراکز تحقیقات و توسعه، موجب شد که تکگراف ابزارهایی که نیاز داشت را از هیچ تولید کند.

«پدر و مادر» تاریخی لوا زبان‌های توصیف داده/تنظیم (SOL (Simple Object Language و (DEL (Date Entry Language هستند. آن دو به طور مستقل در سال‌هال 1370-1371 در تکگراف تولید شده‌اند، تا دو پروژهٔ متفاوت را منعطف‌تر کنند (هر دوی این پروژه‌ها برنامه‌های گرافیکی تعاملی برای کاربردهای مهندسی در شرکت
Please, ورود or عضویت to view URLs content!
بودند. در SOL و DEL ساختارهای کنترلی وجود نداشت و نیاز به یک زبان برنامه‌سازی کامل‌تر احساس می‌شد. «در 1371 تنها رقیب اصلی لوا
Please, ورود or عضویت to view URLs content!
بود، که به طور صریح برای استفاده نهفته در برنامه‌ها طراحی شده بود. اما تیکل نحوی نا آشنا داشت، پشتیبانی کافی از توصیف داده نداشت و فقط روی محیط
Please, ورود or عضویت to view URLs content!
قابل استفاده بود. ما لیسپ و شما را استفاده نکردیم چون نحو زشتی داشتند. پایتون هنوز در نوزادی به سر می‌برد. در جو آزاد و مستقل تکگراف تقریباً عادی بود که ما باید زبان پردازه‌نویسی خودمان را اختراع می‌کردیم... به این علت که خیلی از کاربران محتمل زیان برنامه‌نویسان حرفه‌ای نبودند، زبان باید از نحو و مفاهیم مرموز خودداری می‌کرد. پیاده‌سازی زبان جدید باید قابلیت اجرا روی محیط‌های مختلف را می‌داشت چون کاربران تکگراف انواع متمایزی رایانه در اختیار داشتند. در نهایت، از آنچه که ما انتظار داشتیم که محصولات دیگر تکگراف هم نیاز به نهفتن یک زبان پردازه‌نویسی داشتند، زبان جدید باید مثال SOL را ادامه می‌داد و به عنوان کتاب‌خانه‌ای همراه API سی ارائه می‌شد.»

در نتیجه لوا به دنیا آمد. سازنده‌های اشیا لوای ۱٫۰ که آن زمان کمی متفاوت از حالت سبُک و انعطاف‌پذیر امروزی متفاوت بودند، نحو توصیف دادهٔ SOL را به کار گرفته بودند (ریشه نام لوا از همین‌جا می‌آید، sol در زبان پرتغالی یه معنای خورشید است و لوا به معنای ماه). ساختارهای کنترلی لوا (if,while,repeat/until) بیشتر از مدولا قرض گرفته شده بودند، اما از CLU هم تاثیر گرفته است (مقدار خروجی چندگانه از توابع و عملیات مقداردهی چندگانه به عنوان گزینه‌ای ساده‌تر از پارامترهای ارجاعی یا اشاره‌گرهای صریح). لوا همچنین از ++C (تعریف محدودتر حوزه متغیرها)، آوک و سنوبال (آرایه‌های انجمنی) هم تاثیر گرفته است. در یک مقاله منتشر شده در مجله «Dr Dobb's Journal»، سازندگان لوا همچنین اذعان می‌کنند که زبان لیسپ و شما هم با داده ساختار تکین خود (لیست) تاثیر مهمی روی تصمیم سازندگان بر استفاده از جدول به عنوان داده ساختار اولیه داشتند. مفاهیم فعلی لوا بیشتر از شما گرفته شده‌اند: «از نظر مفهوم لوا شباهت‌های زیادی به شما دارد، گرچه این شباهت‌ها مستقیماً دیده نمی‌شوند، چون این دو زبان تفاوت‌های نحوی زیادی دارند. تاثیر شما روی لوا به تدریج در زمان تکامل لوا افزایش یافته است: در ابتدا شما فقط زبانی در پس‌زمینه بود اما بعداً به تدریج به عنوان منبعی برای ایده گرفتن مهم شد، به خصوص به خاطر معرفی توابع ناشناس و حوزه‌بندی کامل»

کاربردها
لوا در صنعت
Please, ورود or عضویت to view URLs content!
محبوبیت زیادی دارد. در تعدادی از موتورهای بازی از زبان لوا برای توسعه و به عنوان اسکریپت استفاده می‌شود از جمله:

از جملهٔ بازی‌هایی که از افزون‌بسته‌های (Plugin) لوا پشتیبانی می‌کنند می‌توان به موارد زیر اشاره کرد:

به جز بازی‌ها لوا در کاربردهای بسیاری هم تجاری و هم غیرتجاری استفاده شده است از جمله:

  • Adobe Photoshop Lightroom
  • Apache HTTP Server
  • Damn Small Linux
  • LuaTex
  • nmap
  • WireShark
ساختار کلی
دستورات لوا خط به خط توسط مفسر اجرا می‌شوند. در لوا همچون زبان‌های
Please, ورود or عضویت to view URLs content!
دیگر تابع اصلی (main) وجود ندارد (می‌توان اینطور تصور کرد که کل برنامه یک تابع اصلی است). هر بلوک کد لوا یا مربوط به مقداردهای متغیر است یا اینکه اجرای یک تابع خاص می‌باشد. ارتباط با دنیای بیرون از طریق
Please, ورود or عضویت to view URLs content!
انجام می‌شود. متغیرهایی که تعریف می‌شوند به دو دسته عمومی و محلی تقسیم می‌شوند. متغیرهای محلی متغیرهایی هستند که حوزه آنها یک تابع خاص است. در این زبان پیش‌پردازنده وجود ندارد. در لوا مستقیماً قابلیت‌های زیادی وجود ندارد، بلکه هر برنامه‌نویس با فرا ساز و کارهای تعبیه شده می‌تواند قابلیت لازم خود را اضافه کند. این فرا ساز و کارها عبارتند از: آرایه‌های انجمنی پویا (Dynamic Associative Arrays)، ابزارهای انعطاف‌پذیر (Reflexive Facilities) و فراجدول‌ها (Metatables)

کد نمونه
کدهای این قسمت همگی کامل هستند و بدون هیچ تغییری تفسیر می‌شوند.

برنامهٔ نوشتن عبارت "Hello World" بر روی صفحه:

print('Hello World') -- this is a comment

کامنت‌ها با—مشخص می‌شوند.

جمع کردن دو عدد در ورودی:

a = io.read()
b = io.read()
print(a+b)

توصیف یک پنجره گرافیکی:

d = dialog {
hbox {
button{ label = "ok" },
button{ label = "cancel" }
}
}

در این مثال dialog با یک جدول توصیف می‌شود.

تابع فاکتوریل نمونه‌ای از یک تابع بازگشی در لوا است، که به دو روش پیاده‌سازی شده است:

function factorial(n)
if n == 0 then
return 1
else
return n * factorial(n - 1)
end
end

function factorial2(n) -- Shorter equivalent of the above
return n == 0 and 1 or n * factorial2(n - 1)
end

در تابع دوم از خصوصیت محاسبه کمینه عبارت بولی از چپ در زبان لوا استفاده شد. یعنی اینکه فقط اگر شرط n==0 برقرار نباشد محاسبه factorial2(n-1) انجام می‌شود.

عوض کردن تابع print تعریف شده در لوا به گونه‌ای که رفتار آن فقط به ازای حالت خاص ورودی "foo" تفاوت کند.

do
local oldprint = print -- Store current print function as oldprint
function print(s) -- Redefine print function
if s == "foo" then
oldprint("bar")
else
oldprint(s)
end
end
end

این مثال به خوبی نشان می‌دهد که توابع کتابخانه در لوا متغیرهای عمومی (یا سطح اول) هستند.

سیستم تایپ
لوا پویندگی تایپ دارد، یعنی نوع متغیرها در لوا در زمان
Please, ورود or عضویت to view URLs content!
مشخص نمی‌شود، بلکه هر متغیر در زمان اجرا نوعش تعیین می‌شود. در واقع در تعریف متغیر، نوع متغیر توسط برنامه‌نویس نوشته نمی‌شود. زمانی که برنامه‌نویس یک عمل
Please, ورود or عضویت to view URLs content!
به آن متغیر انجام می‌دهد، نوع متغیر بسته به چیزی که در متغیر ذخیره می‌شود تعیین می‌شود. نوع متغیرها می‌تواند در طول اجرا تغییر کند.

نوع داده‌های اولیه
در لوا ۸ نوع داده اولیه وجود دارد:

  • نوع صحت (Boolean): مقدار true یا false می‌تواند بگیرد.
  • عدد: عددی اعشاری با دقت دوگانی (double precision)
  • رشته: رشته‌ای از کاراکترهای یک بایتی. از تمام کاراکترهای ۰ تا ۲۵۵ می‌توان در رشته استفاده کرد.
  • تابع: با هر تابع هم مثل یک متغیر برخورد می‌شود. برای آن متغیر عملگر)(تعریف شده است.
  • جدول: جدول ساختارداده‌ای شبیه آرایه است، اما می‌توان از هر تایپی (عدد، رشته، ...) برای اندیس‌گذاری در آن استفاده کرد.
  • ریسه: ساختار داده مربوط به همروند سازی اجرا
  • کاربرداده (userdata): برای پیوند میان لوا و C باید اشاره‌گرها را بتوان در لوا استفاده کرد. کاربرداده همین کار را می‌کند.
  • Nil: یک نوع خاص که فقط یک مقدار هم دارد که آن مقدار با nil مشخص می‌شود
جدول‌ها
داده‌ساختار اولیه لوا، جدول است. جدول ساختارداده‌ای شبیه آرایه است، اما می‌توان از هر تایپی (عدد، رشته، ...) برای اندیس‌گذاری در آن استفاده کرد. مثلاً در کد زیر:

t = {}
t["mohsen"] = 1
t["ali"]=2
x = t["mohsen"] + t["ali"]
print(x) -- prints 3

با جای اندیس‌های عددی از اندیس "mohsen" و "ali" استفاده شده است. قبل از اینکه بتوان از عملگر [] استفاده کرد باید متغیر مربوطه را مقدار دهی اولیه به مقداری جدولی کرد. ساده‌ترین مقداردهی اولیه مقدار به {} دادن است. می‌توان از عبارات زیر هم استفاده کرد:

t = {mohsen = 1, ali = 2}

در کد بالا t مانند مثال قبلی مقداردهی می‌شود.

داده‌ساختار جدول (از دید برنامه‌نویس) شبیه جدولی است که دو ستون دارد: در ستون اول تعدادی صفت مشخص شده است (مثلاً رنگ، اندازه، ...). در ستون دوم جلوی هر سطر مقدار متناظر آن صفت آمده است. مثلاً روبروی سطر رنگ آمده است آبی. برنامه‌نویس می‌تواند یک سطر به جدول اضافه کند، یک سطر را حذف کند یا مقدار ستون دوم یک سطر را تغییر دهد. همهٔ این اعمال با این
Please, ورود or عضویت to view URLs content!
انجام می‌شود:

t[x] = a

که در آن t یک جدول است و x نام ستون است. اگر x مقداری بوده که قبلاً هم در جدول بوده (در ستون اول)، آنگاه مقدار روبروی آن x می‌شود. در حالت خاصی که a برابر nil باشد آن ستون حذف می‌شود. اگر x قبلاً در جدول نبوده آنگاه یک سطر جدید اضافه می‌شود که در ستون اول آن x و در ستون دوم a آمده است. پس یک جدول یک رشته را به یک مقدار متناظر می‌کند.

از جدول برای پیاده‌سازی مفاهیم مختلفی استفاده می‌شود: آرایه، شی و فضای نام

جدول به عنوان آرایه
در مثال زیر:

colors1 = {"blue", "green"}
colors2[1] = "blue"
colors2[2] = "green"

مقداردهی colors1 از نوع جدیدی است که با مقداردهی colors2 معادل است. به این ترتیب یک جدول که اندیس‌هایش اعداد صحیح ۱ تا n هستند می‌تواند بیانگر مفهوم یک آرایه یاشد.

جدول به عنوان داده ساختار شی
هر شی را می‌توان با یک جدول نمایش داد. مثلاً اگر می‌خواهیم اتاقی را توصیف کنیم، می‌توان از کد زیر استفاده کرد:

room = {color="blue",x=10,y=20}

در این مثال
Please, ورود or عضویت to view URLs content!
که برای توصیف به کار رفته‌اند، عبارتند از طول و عرض اتاق (x و y) و رنگ (color).

لوا از
Please, ورود or عضویت to view URLs content!
استفاده می‌کند. کلاس‌ها در لوا تعریف نمی‌شوند، فقط نمونه‌ها از اشیا تعریف می‌شوند. در تعریف هرنمونه باید تمامی صفات را معین کرد. وفتی روی هر نمونه‌ای عملیات انجام می‌شود، درجا امکان انجام عملیات بررسی می‌شود. اگر این امکان نباشد خطای زمان اجرا پیش می‌آید (البته می‌توان با فراجدول‌ها بعضی از این خطاها را مهار کرد) پس در صورتی که نمونه‌ای خصوصیات کافی داشته باشد، از نظر مفهومی به عنوان یک نمونه از یک کلاس خاص محسوب می‌شود.

برای سادگی لوا یک نحو ویژه برای اینگونه استفاده از جدول ایجاد کرده است. با نوشتن room.x در مثال بالا به مقدار x دست می‌یابیم، دقیقاً مانند اینکه نوشته باشیم room["x"]. این نمایش مفهوم شیء را می‌رساند و به کسانی که با نحو object.attribute عادت دارند هم کمک می‌کنند.

سازوکار تولید مثل
برای ساده‌سازی فرایند نمونه‌سازی لوا از سازوکار تولید مثل استفاده می‌کند. در این سازکار، یک نمونه ساخته می‌شود و سپس از تابعی کمکی استفاده می‌شود تا مانند آن نمونه به تعداد کافی ساخته شود. این تابع به صورت زیر قابل پیاده‌سازی است.

function clone(o)
local new_o = {}
local i,v = next(o,nil)
while i do
new_o = v
i, v = next(o, i)
end
return new_o
end

در این مثال از ابزارهای انعطاف پذبر استفاده شده است.

جدول به عنوان نام فضای نام
با استفاده از یک جدول می‌توان توابع مرتبط را در یک فضا نگهداری کرد:

Point = {}
Point.new = function (x, y)
return {x = x, y = y}
end

Point.set_x = function (point, x)
point.x = x
end

ابزارهای انعطاف‌پذیر
در لوا می‌توان روی عناصر یک جدول حرکت کرد. برای این منظور از تابع next استفاده می‌شود. این تابع یک متغیر می‌گیرد و اولین عضو بعد از آن در جدول را برمی‌گرداند (توجه کنید که اعضا در جدول با ترتیبی تعریف نشده نگهداری می‌شوند). next(nil) اولین عضو جدول را برمی‌گرداند. این قابلیت به لوا امکانات زیادی می‌دهد از جمله تولید مثل اشیا یا ذخیره‌سازی و بازیابی تمام متغیرهای عمومی.

حوزه متغیرها
حوزه متغیرها در لوا دو حالت دارد: عمومی و محلی. متغیرهای محلی با عبارت local در ابتدای آنها مشخص می‌شوند. متغیرهای عمومی در همه جا قابل دسترسی هستند اما متغیرهای محلی فقط در بدنه همان تابع یا توابع تعریف شده در درون آن تابع قابل دسترسی هستند. مثال زیر به خوبی حوزه متغیرها را نشان می‌دهد. در تابع print به جای مقادیری که در حوزه نیستند nil چاپ می‌شود.

y = 1
function f(x)
y = 2
local z = 3
local function g(r)
z = 4
end
g(z)
return z
end

print(f(x)) -- prints 4
print(y) -- prints 2
print(z) -- prints nil

فراجدول‌ها
لوا دارای سیستم تایپ پویا می‌باشد؛ بنابراین در زمان اجرا مشخص می‌شود که انجام یک عمل خاص ممکن است یا نه. مثلاً در کد زیر

a1 = {x=1,y=2}
a2 = {x=3,y=4}
c = a1 + a2

وقتی که کد مربوط به c=a+b تفسیر می‌شود امکان‌ناپذیر بودن آن مشخص می‌شود. برای اینکه احاطه برنامه‌نویس بر روند اجرا بیشتر شود، قابلیت فراجدول به زبان اضافه شد. این قابلیت اجازه می‌دهد که به جای رخ دادن خطاهای زمان اجرا تابعی از پیش تعیین شده توسط کاربر اجرا شود. این تابع وضعیت خطا را بررسی می‌کند و می‌تواند هم فعالیتی را در این زمان انجام دهد (مثلاً ضبط این موضوع که خطا رخ داده در یک فایل) یا اینکه یک مفهوم جدید برای عمل تعریف نشده تعریف کند. در مثال بالا جمع دو جدول را اینگونه تعریف کرد که مقادیر متناظر نام‌های یکسان را جمع می‌کنیم (اگر مقداری در جدول اول بود که متناظری در جدول دوم نداشت حاصل nil می‌شود). کد این فراجدول اینگونه است:

mt = { __add = function (a, b)
local ret={}
local i=next(a,nil)
while i do
v = a
if b==nil then
return nil
end
v_p = b
e, r = pcall(function() return v + v_p end)
if e then
ret = r
else
return nil
end
i = next(a,i)
end
return ret;
end
}
a1 = {x=1,y=2}
a2 = {x=3,y=4}
setmetatable(a1,mt)
c = a1 + a2
print(c.x,c.y)

این کد در lua نسخه ۵٫۱ به قبل قابل ترجمه نیست چون آن زمان به جای فراجدول‌ها سازوکار مشابهی به نام عقب‌گردان‌ها (Fallbacks) وچود داشت. عقب‌گردان‌ها به علت مشکلاتی که در خوانایی و قابلیت نگهداری و استفاده دوباره کد ایجاد می‌کردند از نسخه ۳٫۰ به بعد از زبان حذف شدند.

Please, ورود or عضویت to view URLs content!

شیءگرایی در لوا به طور مستقیم وارد نشده است. شیءگرایی از طریق سازوکار فراجدول‌ها قابل پیاده‌سازی است. نمونه‌ای ساده از پیاده‌سازی شیءگرایی:

a={x=100, y=200, color="red"}
b={x=300, y=400}
setmetatable(b,{ __index = a })
print(b.color) --> red

Please, ورود or عضویت to view URLs content!
(API)

زبان‌های پردازه‌نویسی درون یک زبان بزرگتر اجرا می‌شوند. این زبان باید با زبان پردازه‌نویسی داخلی از طریق یک لایه ارتباط برقرار کند، که آن رابط ربن (برنامه‌نویسی نرم‌افزار) است. در لوا از دو بخش هسته و کمکی تشکیل شده است. لایه ربن در لوا نسبتاً ساده است، چون برخلاف
Please, ورود or عضویت to view URLs content!
مدیریت
Please, ورود or عضویت to view URLs content!
در آن نیاز نیست. ربن لوا همچون خود زبان کمینه است: عملکرد پیشرفته‌تر توسط کتاب‌خانهٔ کمکی پشتیبانی می‌شود، که شامل
Please, ورود or عضویت to view URLs content!
تعریف شده زیادی است که عملیات پیچیده جدولی را آسان می‌کند.
 

برخی موضوعات مشابه

بالا