প্যারাডাইম | বহু প্যারাডাইম: স্ক্রিপ্টিং, ইম্পারেটিভ (প্রচলিত, প্রোটোটাইপ-ভিত্তিক, অবজেক্ট কেন্দ্রীয়), ফাংশনভিত্তিক |
---|---|
নকশাকার | রোবার্টো ইয়েরোযালিমস ওয়ালডেমার সেলেস লুই হেনরিকে দে ফিগেইরিকো |
প্রথম প্রদর্শিত | ১৯৯৩ |
স্থিতিশীল সংস্করণ | ৫.৩.২ RC2
/ ৩০ নভেম্বর ২০১৫ |
পূর্বরূপ সংস্করণ | ৫.৩.২ RC2
/ ২৫ নভেম্বর ২০১৫ |
টাইপিং পদ্ধতি | গতিশীল, শক্তিশালী, ডাক |
বাস্তবায়ন ভাষা | এএনএসআই সি |
ওএস | ক্রস প্লাটফর্ম |
লাইসেন্স | এমআইটি লাইসেন্স |
ফাইলনেম এক্সটেনশন | .lua |
ওয়েবসাইট | www |
মুখ্য বাস্তবায়নসমূহ | |
লুয়া, লুয়াজেআইটি, লুয়া ভেলা লুয়াআরটি | |
উপভাষাসমূহ | |
মেটালুয়া, আইডেল, জিএসএল সেল, লুয়াউ | |
যার দ্বারা প্রভাবিত | |
সি++, সিএলইউ, মোডুলা, সিম, এননোবোল | |
যাকে প্রভাবিত করেছে | |
গেমমানকি, আইও, জাভাস্ক্রিপ্ট, হুলিয়া, মিনিডি, রেড, রিং,[১] রুবি, স্কুইরেল, মুনস্ক্রিপ্ট, সি-- |
লুয়া (/ˈluːə/ LOO-ə পর্তুগিজ: lua [ˈlu.(w)ɐ], অর্থ চাঁদ)[ক] হলো এক হালকা, উচ্চ পর্যায়ের বহু-প্যারাডাইম প্রোগ্রামিং ভাষা, যা অ্যাপ্লিকেশনে এম্বেডেড করে ব্যবহারের জন্য তৈরি করা হয়েছে।[২] লুয়ার কম্পাইলাই করা বাইটকোডের এর ইন্টারপ্রেটার এএনএসআই সি -তে লেখা হওয়ায় এটি ক্রস প্লাটফর্ম।[৩] এছাড়াও অ্যাপ্লিকেশনে এম্বডেড করার জন্য লুয়ার একটি সরল সি এপিআই রয়েছে।[৪]
১৯৯৩ সালে, বর্ধিত কাস্টমাইজেশনের চাহিদা মেটাতে এই প্রোগ্রামিং ভাষা সফটওয়্যার এপ্লিকেশনের পরিমাণ বৃদ্ধির লক্ষে আবিস্কৃত হয়। এতে অধিকাংশ ভাষার সাধারণ সুবিধাগুলো ছিল কিন্তু বেশি জটিল এবং ডোমেন নির্দিষ্ট বৈশিষ্ট্যগুলো ছিল না। তবে এতে ভাষাটিকে বর্ধিত করার পদ্ধতি রয়েছে, যাতে প্রোগ্রামাররা এ বৈশিষ্ট্যগুলো ব্যবহার করতে পারে। যেহেতু লুয়া একটি সাধারণ এম্বডেড করা প্রসারণ ভাষা হিসেবে তৈরি করা হয়েছে, তাই এটির প্রস্ততকারকেরা এটিকে তৈরির সময়ে এটির গতি, পোর্টেবিলিটি, প্রসারতা এবং ব্যবহারের স্বাচ্ছন্দ্যতার দিকে মনোযোগ দেন।
১৯৯৩ সালে, কম্পিউটার গ্রাফিক্স প্রযুক্তি গ্রুপেরে (টেকগ্রাফ) সদস্য, রোবার্টো ইয়েরোযালিমসি, লুই হেনরিকে দে ফিগেইরিকো, ওয়ালডেমার সেলেস লুয়া প্র্রোগ্রামিং ভাষা তৈরি করেন।
১৯৭৭ সাল খেকে ১৯৯২ সাল পর্যন্ত ব্রাজিলের কম্পিউটার হার্ডওয়ার এবং সফটওয়ারের জন্য একটি বড় বাণিজ্য বাধামূলক নীতি (যাকে এক ধরনের বাজার সংরক্ষণ বলা হতো) ছিল। সে অবস্থায় টেকগ্রায় এর খদ্দেররা বিদেশ থেকে কাস্টমাইজ করা সফটওয়ার রাজনৈতিক বা আর্থিকভাবে কিনতে পারত না। এ কারণে টেকগ্রাফ তাদের প্রথম থেকে প্রয়োজনীয় মৌলিক টুলগুলো তৈরি করে।[৫]
ডাটা ডিস্ক্রিপসন/কনফিগারেশন ভাষা, এসওএল (সাব্জেক্ট অবজেক্ট ভাষা) এবং ডিইএল (ডাটা এন্ট্রি ভাষা) থেকে এই লুয়া প্রোগ্রামিং ভাষা তৈরি করা হয়।[৬] ১৯৯২ থেকে ১৯৯৩ সালের মধ্যে এই দুটি প্রোগ্রামই তাদের দুটো ভিন্ন প্রকল্পে (দুটোই পেট্রোবাস কোম্পানীর জন্য প্রকৌশলী সফটওয়্যার এর প্রকল্প ছিল) নমনীয়তা যোগ করতে তৈরি করা হয়। এসওএল এবং ডিইএল দুটো ভাষাতেই কোনো ফ্লো-নিয়ন্ত্রণ গঠন ছিল না এবং পেট্রোবাস সম্পূর্ণ প্রোগ্রামিং ক্ষমতার প্রয়োজনীয়তা বৃদ্ধি পাচ্ছে মনে করে।
এই প্রোগ্রমিং ভাষার আবিস্কারক দ্য ইভোলিউশন অব লুয়া -তে লিখেছেন:[৫]
১৯৯৩ সালে, একমাত্র প্রতিযোগী ছিল টিসিএল, যা স্পষ্টভাবেই অ্যাপ্লিকেশরন এম্বডেড করার জন্য তৈরি করা হয়েছিল। টিসিএল এ ভিন্ন ধরনের সিন্টেক্স থাকলেও ডাটা ডিসক্রিপসনকে ভালো সাপোর্ট করতে পারতো না এবং শুধুমাত্র ইউনিক্স প্লাটফর্মগুলোতে চলতো। আমরা লিস্প বা স্কিম এর জটিল সিনটেক্সের কারণে সেগুলোর বিবেচনায় নেয়নি। পাইথন তখনও নতুন। তখন টেকগ্রাফ এ বিরাজমান মুক্ত নিজে কর পরিবেশে আমাদের নিজেদের একটি স্ক্রিপ্টিং ভাষা তৈরির চেষ্টা করা সাধারণ একটি ব্যাপার ছিল। যেহেতু ভাষাটির অনেক সম্ভাব্য ব্যবহারকারী পেশাদার প্রোগ্রামার ছিল না, তাই ভাষাটিতে ক্রিপ্টিক সিনটেক্স এবং সিমেনটিক্স এড়িয়ে যেতে হতো। টেকগ্রাফ এর গ্রাহকদের কাছে বিভিন্ন কম্পিউটার প্লাটফর্ম থাকায়, এই নতুন ভাষার ব্যবহার খুবই পোর্টেবল হতে হতো। যেহেতু আমরা ভেবে ছিলাম যে, অন্যান্য টেকগ্রাফ এর পণ্যগুলোতে কোনো স্ক্রিপ্টিং ভাষা এম্বডেড করার প্রয়োজন হতে পারে, তাই এ ভাষাটিকে এসওএল এর দৃষ্টান্ত অনুসরণ করতে হবে এবং এ ভাষাটিকে একটি সি-এপিআই এর একটি লাইব্রেরি হিসেবে প্রদান করতে হবে।
লুয়া ১.০ এমনভাবে তৈরি করা হয়েছিল যে এটির অবজেক্ট কন্সট্রাক্টরগুলো বর্তমানে সোল এর ডাটা ডিসক্রিপশন সিনটেক্স এ থাকা হালকা এবং নমনীয় ধরনের অবজেক্ট কন্সট্রাক্টরগুলো থেকে ভিন্ন (সোল হলো সূর্যের পর্তুগিজ প্রতিশব্দ এবং লুয়া অর্থ চাঁদ)। লুয়ার নিয়ন্ত্রণ গঠনের সিনটেক্সগুলো অধিকাংশই মডিউলা থেকে নেওয়া হয়েছে (যেমন: if, while, repeat/until)। এতে ক্লু (যেমন, এতে রেফারেন্স পেরামিটার অথবা স্পষ্ট পয়েন্টাগুলোর সরল বিকল্প হিসেবে ফাংশন কলগুলো থেকে থেকে বিভিন্ন কাজ বা ফিরতি ব্যবহার করা), সি++ (যেমন: কোনো স্থানীয় চলককে আমাদের যেখানে প্রয়োজন সেখানে বসাতে একটি ধারণা ধারণা প্রয়োজন হতো[৫]), স্নোবল এবং ওক (সহযোগি বিন্যাসের দিক থেকে সাদৃশ্যপূর্ণ) এর প্রভাবও লক্ষণীয়। ড. ডোব’স জার্নাল এ লুয়া এর আবিস্কারক লিখেছেন যে, লিস্প এবং স্কিম তাদের সর্বব্যাপী ডাটা গঠন পদ্ধাতির জন্য লুয়া প্রাথমিক ডাটা গঠনের সারণীটি তৈরি করতে ভূমিকা রাখে।[৭]
সময়ের সাথে সাথে এই প্রোগ্রামিং ভাষার স্কিম এর প্রভাব, বিশেষ করে, এনোনিমাস ফাংশন এবং সম্পূর্ণ লোক্সিকাল স্কোপিং যুক্ত করার মাধ্যমে।[৫] লুয়ার নতুন সংস্করণে আরো কিছু বৈশিষ্ট্য যোগ করা হয়।
লুয়ার ৫.০ সংস্করণের আগের সংস্করণগুলো বিএসডি লাইসেন্স এ সাথে সাদৃশ্যপূর্ণ লাইসেন্স ব্যবহার করত। ৫.০ সংস্করণ এবং পরের সংস্করণগুলো এমআইটি লাইসেন্স এর অধীনে লাইসেন্স করা। দুটি লাইসেন্সই মনোনীত মুক্ত সফটওয়্যার লাইসেন্স এবং অনেকটা পরস্পরের সাথে সাদৃশ্যপূর্ণ।
লুয়া সাধারনত একটি বহু-প্যারাডাইম ভাষা হিসেবে আখ্যায়িত করা হয়, যা সাধারন কিছু বৈশিষ্ট্য প্রদান করে এবং বিভিন্ন ক্ষেত্রে এর বৈশিষ্ট্যগুলো বর্ধিত করা যায়। লুয়া ইনহেরিটেন্স সাপোর্ট করে না বিন্তু এটিকে মেটাটেবিলের মাধ্যমে ব্যবহার করা যায়। এটির একক টেবিল ব্যবহারের মাধ্যমে নেমস্পেস, ক্লাশ এবং অন্যান্য সাদৃশ্যপূর্ণ বৈশিষ্ট্য ব্যবহার করা যায়। প্রথম শ্রেণির ফাংশনগুলো ফাংশনভিত্তিক প্রোগ্রামিং এর অনেক কৌশল ব্যবহার করা যায়। সম্পূর্ণ লেক্সিকাল স্কোপিং এর সাহায্যে স্বল্প অধিকার নীতি প্রযোজ্য করতে ভালোভাবে গ্রেইন করে তথ্য লুকানো যায়।
একটি প্রোগ্রামিং প্যারাডাইম এর কিছু বৈশিষ্ট্যের পরিবর্তে লুয়া সাধারন নমনীয় মেটা-ফিচার প্রদান করার চেষ্টা করে, যা প্রয়োজন অনুযায়ী বর্ধিত করা যায়। ফলস্বরূপ, লুয়া এর মূল ভাষাটি হালকা। এটির সম্পূর্ণ রেফারেন্স ইন্টারপ্রেটার মাত্র ২৪৭ কেবি আকারে সংকলিত এবং অনেক অ্যাপ্লিকেশনে ব্যবহারযোগ্য।[৩]
লুয়া একটি গতিশীলভাবে টাইপ করা ভাষা, যা একটি এক্সটেনশন বা স্ক্রিপ্টিং ভাষা হিসেবে তৈরি এবং এটি এত সংক্ষিপ্ত যে যেকোনো প্লাটফর্মের জন্য উপযোগী। বুলিয়ান মাণ, সংখ্যা (দ্বিগুণ নির্ভূল ফ্লোটিং পোয়েন্ট এবং প্রধানত ৬৪-বিট এর ইন্টেজার) এবং স্ট্রিং এর মতো কিছু পারমাণবিক উপাত্ত গঠন সাপোর্ট করে। বিন্যাস, সেট, তালিকা এবং রেকর্ড এর মতো সাধারণ উপাত্ত গঠনগুলো লুয়ার একক নিজস্ব গঠন তথা টেবিল ব্যবহার করে প্রদর্শন করা যায়, যা একটি ভিন্নধর্মী সহযোগী বিন্যাস।
প্রথম শ্রেণির বৈশিষ্ট্য, গার্বেজ কালেকশন, ক্লোজার, যথাযথ টেইল কল, করসোন (চলাকালীন সংখ্যা এবং স্ট্রিং এর মধ্যে সয়ংক্রিয় পরিবর্তন) এবং কোরোটিন (সমবায় মাল্টিটাস্কিং) ডাইনামিক মোডিউল লোডিং এর মতো অল্প কিছু উন্নত বৈশিষ্ট লুয়া ব্যবহার করে।
প্রচলিত "হ্যালো, ওয়ার্ল্ড!" প্রোগ্রাম এই প্রোগ্রমিং ভাষায় এভাবে লেখা যায়: [৮]
print("Hello World!")
অথবা এভাবে:
print 'Hello World!'
অ্যাডা, ভি এইচ ডি, এলহ্যাসকেল, এসকিউএল এবং আইফেল এর মতো এ ভাষায় কোনো কমেন্ট এর শুরুতে দুটো হাইপেন বসে এবং লাইনের শেষ পর্যন্ত তা বজায় থাকে। একাধিক লাইনের স্ট্রিং বা কমেন্টগুলোর ক্ষেত্রে দুটো বর্গ বন্ধনী বসে। এই গৌণিক ফাংশনটি নিচের উদাহরণটিতে একটি একটি ফাংশন হিসেবে ব্যবহৃত হয়েছে:
function factorial(n)
local x = 1
for i = 2, n do
x = x * i
end
return x
end
লুয়া ভাষাটির চার ধরনের লুপ রয়েছে: “যখন লুপ”, “পুনরায় লুপ” (একটি যখন লুপের সাথে সাদৃশ্যপূর্ণ লুপ), “সংখ্যাবাচক লুপ” এবং “শ্রেণিবাচক লুপ”।
--condition = true
while condition do
--statements
end
repeat
--statements
until condition
for i = first, last, delta do --delta may be negative, allowing the for loop to count down or up
--statements
--example: print(i)
end
শ্রেণিবাচক লুপ:
for key, value in pairs(_G) do
print(key, value)
end
পুনরুক্তি ফাংশন ব্যবহার করে _G
টেবিলটিকে পুনরুক্ত করা হয়।
লুপ নেস্ট (একটি লুপের ভিতর আরেকটি লুপ ঢোকানো) করা যেতে পারে।
local grid = {
{ 11, 12, 13 },
{ 21, 22, 23 },
{ 31, 32, 33 }
}
for y, row in ipairs(grid) do
for x, value in ipairs(row) do
print(x, y, grid[y][x])
end
end
নিচের উদাহরণে লুয়ার প্রথম শেণির মাণ হিসেবে ফাংশন ব্যবহার করা দেখানো হলো, প্রিন্ট ফাংশনটির কাজ পরিবর্তিত হয়েছে:
do
local oldprint = print
-- Store current print function as oldprint
function print(s)
--[[ Redefine print function. The usual print function can still be used
through oldprint. The new one has only one argument.]]
oldprint(s == "foo" and "bar" or s)
end
end
addto
নির্দেশনা যতবার দেওয়া হয়, চলক x
এর একটি নতুন ক্লোজার ততবার তৈরি হয়, যাতে ফিরে আসা প্রতিটি নতুন অজানা ফাংশন তাদের নিজেদের x
প্যারামিটারে প্রবেশ করতে পারে। অন্যান্য অবজেক্ট এর মতো ক্লোজারগুলোকেও লুয়ার গার্বেজ কালেক্টর পরিচালনা করে।
টেবিল হচ্ছে লুয়ার সবচেয়ে গুরুত্বপূর্ণ উপাত্ত গঠন এবং প্রতিটা ব্যবহারকারী-সৃষ্ট টাইপের মূল। টেবিল হলো প্রকৃতপক্ষে সংখ্যাবাচক কী এবং বিশেষ সিনটেক্স এর মতো সহযাগী বিন্যাস।
কোনো টেবিল হলো উপাত্ত এবং কী এর জোড়া, যেখানে উপাত্ত কী দ্বারা নির্দেশিত হয়। অন্য কথায়, এটি একটি হ্যাসড ভিন্নধর্মী সহযোগী বিন্যাস।
টেবিল {}
গঠনকারী সিনটেক্স দিয়ে তৈরি করা হয়।
a_table = {} -- Creates a new, empty table
টেবিলকে নির্দেশনার সাপেক্ষে পরিচালনা করা হয়।
কোনো কী (ইনডেক্স) এর মাণ nil
এবং NaN বাদে ফাংশন সহ যেকোনো কিছু হতে পারে।
কী এবং স্ট্রিং ব্যবহারের মাধ্যমে টেবিলকে অনেক সময় গঠন (অথবা রেকর্ড) হিসেবে ব্যবহার করা হয়। এ রকম ব্যবহার অনেক বেশি বিখ্যাত হওয়ায় লুয়ায় এ ধরনের ক্ষেত্রগুলোতে প্রবেশের জন্য বিশেষ সিনটেক্স আছে।[৯]
point = { x = 10, y = 20 } -- Create new table
print(point["x"]) -- Prints 10
print(point.x) -- Has exactly the same meaning as line above. The easier-to-read dot notation is just syntactic sugar.
সম্পর্কিত ফাংশনগুলো সংরক্ষিত রাখতে একটি টেবিল ব্যবহারের মাধ্যমে এটি একটি নেমস্পেস হিসেবে কাজ করে।
Point = {}
Point.new = function(x, y)
return {x = x, y = y} -- return {["x"] = x, ["y"] = y}
end
Point.set_x = function(point, x)
point.x = x -- point["x"] = x;
end
প্রতিটি টেবিল সয়ংক্রিয়ভাবে একটি সংখ্যাবাচক কী এর সাথে যুক্ত হয়ে যায়। অন্যান্য অনেক প্রোগ্রামিং ভাষার মতো লুয়ায় ০ এর পরিবর্তে ১ হচ্ছে প্রথম সয়ংক্রীয় ইনডেক্স (যদিও স্পষ্টভাবে ০ ইনডেক্স বিদ্যমান)।
কোনো সংখ্যাবাচক কী 1
এবং স্ট্রিং কী, "1"
এর মধ্যে পার্থক্য রয়েছে।
array = { "a", "b", "c", "d" } -- Indices are assigned automatically.
print(array[2]) -- Prints "b". Automatic indexing in Lua starts at 1.
print(#array) -- Prints 4. # is the length operator for tables and strings.
array[0] = "z" -- Zero is a legal index.
print(#array) -- Still prints 4, as Lua arrays are 1-based.
টেবিল t
এর দৈর্ঘ্যকে যেকোনো ইনডেক্স n
হিসেবে বর্ণনা করা যেতে পারে যেখানে t[n]
এর nil
নয় এবং t[n+1]
nil
হয়। এছাড়াও t[1]
যদি nil
হয়, n
তাহলে শূন্য হতে পারে। কোনো সাধারণ বিন্যাসের ক্ষেত্রে, ১ থেকে একটি প্রদত্ত n পর্যন্ত nil নয় এমন মানগুলোর দৈর্ঘ্য সেটির শেষ ইনডেক্স n পর্যন্ত। যদি সেই বিন্যাসে “হোল” থাকে, তাহলে #t
সরাসরিভাবে একটি nil মানের সামনে বসবে (যা বিন্যাসের সমাপ্তি হিসেবে কোনো nil মান নির্ধারন করতে পারে অথবা নিজেই একটি nil হয়ে যেতে পারে)।[১০]
ExampleTable =
{
{1, 2, 3, 4},
{5, 6, 7, 8}
}
print(ExampleTable[1][3]) -- Prints "3"
print(ExampleTable[2][4]) -- Prints "8"
কোনো টেবিল একটি অবজেক্ট এর বিন্যাস হতে পারে।
function Point(x, y) -- "Point" object constructor
return { x = x, y = y } -- Creates and returns a new object (table)
end
array = { Point(10, 20), Point(30, 40), Point(50, 60) } -- Creates array of points
-- array = { { x = 10, y = 20 }, { x = 30, y = 40 }, { x = 50, y = 60 } };
print(array[2].y) -- Prints 40
একটি হ্যাশ ম্যাপ দ্বারা কোনো বিন্যাস অনুকরণ করতে প্রকৃত কোনো বিন্যাস ব্যবহার করার চেয়ে বেশি সময় প্রয়োজন হয়। তাই, এ ধরনের সমস্যা এড়ানোর জন্য লুয়ার টেবিলগুলোকে বিন্যাস হিসেবে ব্যবহারের জন্য অনুকূলিত করা হয়েছে।[১১]
প্রসারণযোগ্য সিমেন্টিক্স লুয়ার একটি প্রধান বৈশিষ্ট্য এবং মেটাটেবিল এর বিষয়টির কারণের লুয়ার টেবিলগুলো শক্তিশালীভাবে পরিবর্তিত হতে পারে। নিচের উদাহরণে একটি অসীম সারণী দেখনো হলো। যেকোনো n
বা fibs[n]
এর জন্য ডাইনামিক প্রোগ্রামিং এবং মেমোইজেশন এর মাধ্যমে n
-তম ফিবোনাচ্চি সংখ্যা পাওয়া যাবে।
fibs = { 1, 1 } -- Initial values for fibs[1] and fibs[2].
setmetatable(fibs, {
__index = function(values, n) --[[__index is a function predefined by Lua,
it is called if key "n" does not exist.]]
values[n] = values[n - 1] + values[n - 2] -- Calculate and memorize fibs[n].
return values[n]
end
})
লুয়াতে কোনো অন্তর্নির্মিত ক্লাসের ধারণা না থাকায় প্রথম শ্রেণির ফাংশনগুলো এবং সারণী ব্যবহার করে অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং করা যায়। কোনো সারণীতে ফাংশনসমুহ এবং সম্পর্কিত উপাত্ত সারণীর মধ্যে অন্তর্ভুক্ত করার মাধ্যমে একটি অবজেক্ট তৈরি হয়। ইনহেরিটেন্স (এক বা একাধিক) অবজেক্টকে অস্তিত্বহীন পদ্ধতিগুলো অনুসন্ধান করার এবং উদ্ভাবক অবজেক্টগুলোকে ফিল্ড ইন করার নির্দেশনা দিয়ে মেটাটেবিল পদ্ধতিতে কাজ করতে পারে।
এই পদ্ধতিতে ক্লাশ বলে কিছু নাই, বরং এতে সেল্ফ এবং জাভাস্ক্রিপ্টের মতো প্রোটোটাইপ ব্যবহার করা হয়। কোনো উৎপাদক পদ্ধতিতে (যা নতুন অবজেক্টকে শুরু থেকে তৈরি করে) অথবা ইতোমধ্যে বিদ্যমান অবজেক্টের কপি করে নতুন অবজেক্ট তৈরি করা যায়।
একটি সাধারণ ভেক্টর অবজেক্ট তৈরি করা:
local Vector = {}
local VectorMeta = { __index = Vector}
function Vector.new(x, y, z) -- The constructor
return setmetatable({x = x, y = y, z = z}, VectorMeta)
end
function Vector.magnitude(self) -- Another method
return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end
local vec = Vector.new(0, 1, 0) -- Create a vector
print(vec.magnitude(vec)) -- Call a method (output: 1)
print(vec.x) -- Access a member variable (output: 0)
এখানে setmetatable
কোডটি লুয়াকে নির্দেশ দিচ্ছে যে, যদি vec
টেবিলে না থাকে, তাহলে সেটির জন্য Vector
টেবিলে অনুসন্ধান করতে। vec
টেবিলে কোনো magnitude
উপাদান থাকে না। কিন্তু যখন এটি vec
টেবিলে তা খুজে পায় না তখন লুয়ার মেটাটেবিল তাকে Vector
টেবিলে অনুসন্ধান করার নির্দেশ দেয়।
অবজেক্ট অরিয়েন্টেশনকে সহজ করার জন্য লুয়াত কিছু সিনটেটেক সুগার রয়েছে। কোনো প্রোটোটাইপ সারণীতে সদস্য ফাংশনসমুহ স্থাপন করতে কেউ function table:func(args)
কোডটি ব্যবহার করতে পারে, যা function table.func(self, args)
কোডের সমতুল্য। ক্লাশ পদ্ধতিগেুলোকে নির্দেশ করতে কোলন ব্যবহার করতে হয়: object:func(args)
, যা object.func(object, args)
কোডের সমতুল্য।
এখানে এই নিয়মে একটি সাদৃশ্যপূর্ণ সিনটেটিক :
সুগার যুক্ত একটি ক্লাশ দেখানো হলো:
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y, z) -- The constructor
-- Since the function definition uses a colon,
-- its first argument is "self" which refers
-- to "Vector"
return setmetatable({x = x, y = y, z = z}, self)
end
function Vector:magnitude() -- Another method
-- Reference the implicit object using self
return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end
local vec = Vector:new(0, 1, 0) -- Create a vector
print(vec:magnitude()) -- Call a method (output: 1)
print(vec.x) -- Access a member variable (output: 0)
লুয়া ক্লাশকে ইনহেরিটেন্স দেওয়ার জন্য লুয়া মেটাসারণীর ব্যবহার সাপোর্ট করে।[১২] নিচের উদাহরণে একটি প্রাপ্ত ক্লাশে ভেক্টরগুলোর মাণকে একটি ধ্রুবকের সাথে গুণ করা হয়েছে।
local Vector = {}
Vector.__index = Vector
function Vector:new(x, y, z) -- The constructor
-- Here, self refers to whatever class's "new"
-- method we call. In a derived class, self will
-- be the derived class; in the Vector class, self
-- will be Vector
return setmetatable({x = x, y = y, z = z}, self)
end
function Vector:magnitude() -- Another method
-- Reference the implicit object using self
return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end
-- Example of class inheritance
local VectorMult = {}
VectorMult.__index = VectorMult
setmetatable(VectorMult, Vector) -- Make VectorMult a child of Vector
function VectorMult:multiply(value)
self.x = self.x * value
self.y = self.y * value
self.z = self.z * value
return self
end
local vec = VectorMult:new(0, 1, 0) -- Create a vector
print(vec:magnitude()) -- Call a method (output: 1)
print(vec.y) -- Access a member variable (output: 1)
vec:multiply(2) -- Multiply all components of vector by 2
print(vec.y) -- Access member again (output: 2)
লুয়া একাধিক ইনহেরিটেন্স সাপোর্ট করে। __index
কোনো ফাংশন অথবা কোনো সারণী হতে পারে। লুয়াতে অপারেটর ওভারলোডিং -ও করা যায়। মেটাসারণীতে __add
এবং __sub
ইত্যাদি উপাদানসমুহ থাকতে পারে।
লুয়ার প্রোগ্রামগুলোকে সরাসরি লুয়ার টেক্সুয়াল ফাইল থেকে ইন্টারপ্রেট করা হয় না, বরং সেগুলোকে বাইটকোডে কম্পাইল করা হয়, যা পরে লুয়ার ভার্চুয়াল মেশিনে চলে। এই প্রক্রিয়াটি রান-টাইমে ব্যবহারকারীর আড়ালে সম্পাদিত হয়, বিশেষ করে যখন কোনো জেআইটি কম্পাইলার ব্যবহার করা হয়। কিন্তু কম্পাইলায় বাদ দিয়ে হোস্ট পরিবেশের লোড পারফারমেন্স বৃদ্ধি করতে এবং মেমোরি ফুটপ্রিন্ট কমানোর জন্য অফলাইনেও এই প্রক্রিয়াটি সম্পাদিত হতে পারে। লুয়ার স্ট্রিং লাইব্রেরি থেকে dump
ফাংশন এবং load/loadstring/loadfile
ফাংশনগুলো ব্যবহার করে লুয়া বাইটকোড লুয়ার মধ্য থেকেই তৈরি এবং কার্য সম্পাদন করতে পারে। প্রায় ২৪,০০০ লাইনের সি-কোডে লুয়া ৫..৩.৪ ব্যবহার হয়েছে।[২][৩]
অধিকাংশ সিপিইউ এর মতো লুয়ার ভার্চুয়াল মেশিন নিবন্ধন-ভিত্তিক, যা অধিকাংশ ভার্চুয়াল মেশিনের থেকে এটিকে আলাদা করে। এই নিবন্ধন পদ্ধতি মাণের অতিরিক্ত অনুলিপি হতে দেয় না এবং প্রতি ফাংশনের জন্য নির্দেশনা হ্রাস করে। প্রথম বহুল ব্যবহৃত নিবন্ধন ভিত্তিক ভার্চুয়াল মেশিনগুলোর একটি হলো লুয়ার ভার্চুয়াল মেশিন।[১৩] অ্যান্ড্রয়েড এর ডালভিক এবং প্যারেট হলো আরো দুটো বিখ্যাত নিবন্ধন-ভিত্তিক ভার্চুয়াল মেশিন।[১৪]
উপরে বর্ণিত উৎপাদক ফাংশনটি নিচের উদাহরণে দেখানো হলো (luac
৫.১ কম্পাইলার এ দেখানো হলো):[১৫]
function <factorial.lua:1,7> (9 instructions, 36 bytes at 0x8063c60)
1 param, 6 slots, 0 upvalues, 6 locals, 2 constants, 0 functions 1 [2] LOADK 1 -1 ; 1 2 [3] LOADK 2 -2 ; 2 3 [3] MOVE 3 0 4 [3] LOADK 4 -1 ; 1 5 [3] FORPREP 2 1 ; to 7 6 [4] MUL 1 1 5 7 [3] FORLOOP 2 -2 ; to 6 8 [6] RETURN 1 2 9 [7] RETURN 0 1
লুয়াকে অন্যান্য অ্যাপ্লিকেশনে এম্বডেড করার জন্য তৈরি করা হয় এবং তাই একটি সি এপিআই প্রদান করা হয়। এই এপিআই দুটো অংশে বিভক্ত, যার একটি হলো লুয়া কোর এবং অন্যটি হলো লুয়া সহায়ক লাইব্রেরি।[১৬] লুয়ার এপিআই এর কাঠামোর জন্য সি-কোডে পাইথোনের এপিআই এর মতো ম্যানুয়াল রেফারেন্স ম্যানেজমেন্ট এর প্রয়োজন হয় না। লুয়ার এপিআই ভাষাটির মতোই সংক্ষিপ্ত। সহায়ক লাইব্রেরি থেকে লুয়া উন্নত ফাংশনগুলো পায়। সহায়ক লাইব্রেরিতে মূলত প্রিপ্রসেসর মেকরো থাকে যেগুলো সারণীর জটিল কাজগুলো সম্পাদনে সাহায্য করে।
লুয়ার সি-এপিআই হলো স্ট্যাক-ভিত্তিক। অধিকাংশ সাধারন সি উপাত্ত টাইপকে স্ট্যাক এর স্ট্যাকে বা স্ট্যাক থেকে পুশ এবং পোপ করতে এবং স্ট্যাকের মধ্যে সারণী লুকাতে ফাংশন প্রদান করে। লুয়া স্ট্যাক প্রচলিত স্ট্যাক এর চেয়ে কিছুটা ভিন্ন। লুয়ার স্ট্যাক সরাসরিভাবে ইনডেক্স হতে পারে। না বোধক সূচকগুলো স্ট্যাকের শীর্ষের থেকে অফসেটকে নির্দেশ করে, যেমন: -১ হলো শীর্ষ (সবচেয়ে সাম্প্রতিক পুশ করা মান)। আবার, হ্যা বোধক সূচকগুলো স্ট্যাকের নিচের দিকের অফসেটগুলোকে নির্দেশ করে। সি এবং লুয়া ফাংশনের মধ্যে উপাত্ত মার্শেল করার কাজটিও স্ট্যাকের মাধ্যমে করা হয়। কোনো লুয়া ফাংশনকে নির্দেশ দিতে স্ট্যাকের উপর যুক্তি প্রযুক্ত হয় এবং তারপর ফাংশনটিকে নির্দেশ করতে lua_call
কোডটি ব্যবহৃত হয়। লুয়ায় সরাসরি নির্দেশ করার জন্য সি ফাংশন লেখার সময়ে স্ট্যাক থেকে এই যুক্তিগুলো পড়া হয়।
নিচে সি -তে কোনো লুয়া ফাংশনকে নির্দেশ দেওয়ার একটি উদাহরণ দেওয়া হলো:
#include <stdio.h>
#include <lua.h> // Lua main library (lua_*)
#include <lauxlib.h> // Lua auxiliary library (luaL_*)
int main(void)
{
// create a Lua state
lua_State *L = luaL_newstate();
// load and execute a string
if (luaL_dostring(L, "function foo (x,y) return x+y end")) {
lua_close(L);
return -1;
}
// push value of global "foo" (the function defined above)
// to the stack, followed by integers 5 and 3
lua_getglobal(L, "foo");
lua_pushinteger(L, 5);
lua_pushinteger(L, 3);
lua_call(L, 2, 1); // call a function with two arguments and one return value
printf("Result: %d\n", lua_tointeger(L, -1)); // print integer value of item at stack top
lua_pop(L, 1); // return stack to original state
lua_close(L); // close Lua state
return 0;
}
এই উদাহরণটি চালনা করলে নিচের ফলাফলটি পাওয়া যাবে:
$ cc -o example example.c -llua $ ./example Result: 8
এই সি এপিআই আরো কিছু বিশেষ সারণী প্রদান করে। এগুলো লুয়ার স্ট্যাকের বিভিন্ন “ছদ্ম সূচকে” রয়েছে। লুয়া ৫.২ এর আহে = LUA_GLOBALSINDEX
ছিল লুয়ার অন্তর্ভুক্ত একটি সার্বজনীন সারণী, _G
, যা ছিল প্রধান নেমস্পেস। পরবর্তীকালে লুয়ার মানগুলো পুনরুদ্ধারের জন্য LUA_REGISTRYINDEX
-এ একটি রেজিস্ট্রি রয়েছে।ref name="Changes in the API, Lua 5.2 manual">"Changes in the API"। Lua 5.2 Reference Manual। Lua.org। সংগ্রহের তারিখ ২০১৪-০৫-০৯।</ref>
লুয়ার এপিআই ব্যবহার করে প্রসারণ মডিউল তৈরি করা সম্ভব। প্রসারণ মডিউলগুলো হলো যৌথ অবজেক্ট, যা লুয়ার স্ক্রিপ্টে নিজস্ব সুবিধাগুলো প্রদান করে ইন্টারপ্রেটারের কাজের প্রসারণ ঘটায়। লুয়ার পক্ষ থেকে এ ধরনের একটি মডিউল নেমস্পেস সারণী হিসেবে আবির্ভূত হয়, যাতে ফাংশন এবং চলকগুলো থাকে। লুয়া সেটির মধ্যে লিখিত মডিউলের মতো প্রয়োজন অনুসারে প্রসারণ মডিউল লোড করতে পারে।[১৬] রকস নামে পরিচিত একটি বাড়তে থাকা মডিউলের সংগ্রহ লুয়ারকস নামক একটি প্যাকেজ ম্যানেজম্যান্ট পদ্ধতির মাধ্যমে সিস্প্যান, রুবিজেমস এবং পাইথন এগস অংশে পাওয়া যায়।[১৭] আগে থেকে লেখা লুয়া বাইন্ডিং অন্যান্য স্ক্রিপ্টিং ভাষাসহ সবচেয়ে জনপ্রিয় পোগ্রামিং ভাষাগুলোর জন্য বিদ্যমান রয়েছে।[১৮] সি++ এর জন্য টেমপ্লেট-ভিত্তিক পন্থা এবং কিছু সয়ংক্রিয় বাইন্ডিং জেনারেটর রয়েছে।
লুয়ার এম্বডেড করার সরলতা, কার্য সম্পাদনে দ্রুততা এবং ছোট লিনিং কার্ভ এর জন্য প্রোগ্রাররা প্রচলিতভাবে এটিকে ভিডিও গেমসে একটি স্ক্রিপ্টিং ভাষা হিসেবে ব্যবহার করেন।[১৯] এগুলোর মধ্যে একটি উল্লেখযোগ্য গেমিং প্লাটফর্ম হচ্ছে রবলক্স। এটিতে দ্রুত গেম তৈরির স্ক্রিপ্টের জন্য তাদের নিজস্ব ভাষা, লুয়াউ ব্যবহার করা হয়েছে।[২০] এছাড়াও, ওয়ার্ল্ড অব ওয়ারক্রাফ্ট -এ লুয়ার আরেকটি নিম্ন সংস্করণ ব্যবহার করা হয়েছে।[২১]
২০০৩ সালে, গেমডেভ.নেট -এ একটি ভোটগ্রহণে দেখা যায় যে, লুয়া তখন গেম তৈরির জন্য সবচেয়ে জনপ্রিয় ভাষা।[২২] ২০১২ সালের ১২ই জানুয়ারি, গেম ডেভেলপার ম্যাগাজিন কর্তৃক প্রোগ্রামিং টুল শ্রেণিতে ফ্রন্ট লাইন পুরস্কার, ২০১১ অর্জণ করে।[২৩]
লুয়াটেক্ম (এখানে টেক্ম টাইপ-সেটিং হিসেবে ব্যবহার হয়েছে), রেডিস (একটি কী-মাণ ডাটাবেজ), নেওভিম (একটি টেক্স এডিটর) এনজিনিক্ম (একটি ওয়েব সার্ভার) এর মতো গেমের সাথে অসম্পর্কিত অ্যাপ্লিকেশনগুলোতেও লুয়া ব্যবহার করা হয়েছে।
স্ক্রিবানতো এক্সটেনশনের মাধ্যমে লুয়া একটি বিকল্প সার্ভার ভাষা হিসেব মিডিয়াউইকি সফটওয়্যারে রয়েছে, যার মধ্যে উইকিপিডিয়া এবং অন্যান্য উইকি অন্তর্ভুক্ত।[২৪] এর ব্যবহারগুলোর মধ্যে রয়েছে নিবন্ধের সাথে উইকিডাটার উপাত্ত যুক্ত করা এবং স্বয়ংক্রিয় টেক্সোবক্স সিস্টেমকে ক্ষমাত দেওয়া।[২৫]
do
এবং end
(অথবা {
ও }
) ব্যবহারের পরিবর্তে লাইন ব্রেক এবং ইন্ডেন্টেশন স্টাইল ব্যবহার করে।[২৬][২৭][২৮] এর একটি উল্লেখযোগ্য ব্যবহার দেখা যায় Itch.io ওয়েবসাইটটিতে, যা একটি ভিডিও গেম বন্টনের ওয়েবসাইট।উন্নয়নকারী | মাইক পোল |
---|---|
স্থিতিশীল সংস্করণ | ২.০.৫
/ ১ মে ২০১৭ |
রিপজিটরি | repo |
যে ভাষায় লিখিত | সি, লুয়া |
অপারেটিং সিস্টেম | তালিকা দেখুন |
ধরন | জাস্ট ইন টাইম কম্পাইলার |
লাইসেন্স | এমআইটি লাইসেন্স[৩১] |
ওয়েবসাইট | luajit |
লুয়াজেআইটি হচ্ছে লুয়ার জন্য একটি জাস্ট-ইন-টাইম কম্পাইলার। এটি সাধারণ উদ্দেশ্যে বা এম্বডেড করার জন্য ব্যবহার করা হয়েছে। লুয়াজেইটি এর ২.০ সংস্করণে আরো ভালো অপ্টিমাইজেশন এবং পারফারমেন্স এর জন্য এটিকে আবারো তৈরি করা হয়।[৩২]
২০০৫ সালে, ডেভেলপার মাইক পোল লুয়াজেআইটি প্রকল্প শুরু করেন, এমআইটি ওপেন সোর্স লাইসেন্স এর অধীনে প্রকাশিত হয়।[৩৩] ২০১৭ সালে সর্বশেষ সংস্করণ ২.০.৫ প্রকাশিত হয়। তারপর থেকে এই প্রকল্পটি ডেভেরপার এবং অন্য কোনো অবদানকারীরা আর পরিচালনা করছে না।[৩৪]
লুয়া একটি ওপেন সোর্স এর অধীনে আছে এবং ব্যবহারের জন্য এটিকে কম্পাইল করতে হয়। গিট বা অন্য কোনো রেপোজেটারি ডাউনলোডের পদ্ধতিতে এই রেপোজেটারি ডাউনলোড করতে হয়।[৩৪] তারপর এটি সি কম্পিইলার (সাধারণত জিএনইউ ম্যাক) এর সাথে কম্পাইল হয়ে যায়, যদিও অন্যান্য অপশনগুলো বিদ্যমান থাকে।[৩৫] সর্বোপরি লুয়াজেআইটি কম্পাইলার ব্যবহারের জন্য লুয়াজেআইটি এর এক্সেকিউটেবল এবং লুয়া ৫.১ ডিএলএল একই ডাইরেক্টরিতে থাকতে হবে।
লুয়াজেআইটি কম্পাইলার এর ব্যবহারের উপর একটি নির্দেশনা দেওয়া আছে, যেখানে কমান্ড লাইন অপশনগুলো দেওয়া হয়েছে।[৩৬]
অন্যান্য লুয়া রান-টাইমের সাথে তুলনা করে দেখা যায় যে, এটি লুয়ার সবচেয়ে বেশি গতিসম্পন্ন কম্পাইলার।[৩৭]
লুয়াজেআইটি নিচের প্লাটফর্মগুলোতে ব্যবহার করা যায়।:[৩৮]
এটিকে জিসিসি, ক্লাং অথবা এমএসভিসি ব্যবহার করে কম্পাইল করা যায়।[৩৮]
এফএফআই লাইব্রেরি সি ফাংশনকে নির্দেশ করতে এবং লুয়া কোড থেকে সি ডাটা গঠন ব্যবহার করতে ব্যবহার করা যেতে পারে। [৩৯] লুয়াজেআইটি লাইব্রেরি ব্যবহার সম্পর্কে একটি নির্দেশনা প্রদান করে।[৪০] অনুরূপভাবে সি লাইব্রেরি বেশ কিছু লুয়াজেআইটি বাইন্ডিং রয়েছে, যা এফএফআই লাইব্রেরি ব্যবহার করে। এটি শুদ্ধ লুয়া কোড থেকে সি ফাংশন, printf -কে নির্দেশ করে এবং হ্যালো ওয়ার্ল্ড আউটপুট পাওয়া যাবে।
local ffi = require("ffi")
ffi.cdef[[
int printf(const char *fmt, ...);
]]
ffi.C.printf("Hello world!\n")
লুয়াজেআইটি কম্পাইলার লুয়ার সি এপিআই-তে কিছু অতিরিক্ত বৈশিষ্ট্য যোগ করেছে।[৪১] সি++ -এ লেখা নিচের উদাহরণটি ডিবাগিং প্রক্রিয়ায় ব্যবহার করা হয়।
#include <exception>
#include "lua.hpp"
// Catch C++ exceptions and convert them to Lua error messages.
// Customize as needed for your own exception classes.
static int wrap_exceptions(lua_State *L, lua_CFunction f)
{
try {
return f(L); // Call wrapped function and return result.
} catch (const char *s) { // Catch and convert exceptions.
lua_pushstring(L, s);
} catch (std::exception& e) {
lua_pushstring(L, e.what());
} catch (...) {
lua_pushliteral(L, "caught (...)");
}
return lua_error(L); // Rethrow as a Lua error.
}
static int myinit(lua_State *L)
{
...
// Define wrapper function and enable it.
lua_pushlightuserdata(L, (void *)wrap_exceptions);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);
lua_pop(L, 1);
...
}