Lua – Встановлення Lua. Lua – Установка Lua Програма для роботи з lua

Головна / Налаштування
У цій серії уроків, яку я задумав, обговорюватиметься мова програмування Lua. Я постараюся зробити виклад якомога доступнішим для початківців, і саме на них орієнтуватимуся. Тобто, досвідчені Lua-кодери, швидше за все, не почерпнуть звідси нічого нового (впевнений, тут вони знайдуть лише простір для причіпок та зауважень, які, власне, з їхнього боку навіть вітається), але якщо у вас за плечима немає багатого досвіду програмування , то, думаю, дещо ви винесете.

Вся серія не підпорядковуватиметься якійсь системі. Уроки будуть послідовно вводити ряд конструкцій мови, щоб до третього чи четвертого уроку ви вже могли писати свої програми. Моя мета - підштовхнути вас до самостійного вивчення мови, допомогти відчути її, а не роз'яснити від А до Я - якщо хочете освоїти мову повністю, читайте довідкове керівництво (яке, хоч і погано, перекладено російською мовою: http://www.lua . ru/doc/). Чим раніше ви перейдете від уроків "для чайників" у Мережі до вивчення довідника, тим краще.

Якщо щось незрозуміло - обов'язково поставте питання в коментарях, і я та інші учасники постараємося вам допомогти.

Lua - популярна, нескладна для освоєння вбудовувана інтерпретована динамічно типізована мова програмування загального призначення. Ні, вам необов'язково розуміти і половини слів, сказаних у попередній пропозиції – головне знайте, що він популярний та нескладний. До речі, простотою, а також маленьким розміром дистрибутива (близько 150 кілобайт), він і заслужив на свою популярність. Скрипти на Lua підтримуються великою кількістю програм, у тому числі іграми. World of Warcraft та S.T.A.L.K.E.R. використовують мову Lua. Мій улюблений ігровий двигун дозволить вам за допомогою Lua з легкістю створювати різноманітні ігри. Як бачите, Lua відкриває вам чималі горизонти!

Перш ніж ми почнемо, вам слід облаштувати середовище для програмування: тобто знайти програму, яка б приймала написаний вами код на Lua і виконувала його: інтерпретатор. Тут є три варіанти:

1. Завантажити офіційний дистрибутив Lua з одного з сайтів, що їх поставляють.

З офіційного сайту Lua можна завантажити лише вихідні коди інтерпретатора. Однак, вивчивши http://lua.org/download.html у розділі Binaries, ви можете виявити посилання на сайти з виконуваними файлами для Windows. Один з них: . Завантажте звідти один з архівів (збігається з вашою платформою: Win32 або Win64) і розпакуйте його кудись, бажано в каталог з коротким шляхом: на кшталт C:\lua. Відтепер я вважатиму, що ви користуєтеся Windows, і ваш інтерпретатор лежить саме там.

Користувачам операційних систем на базі Linux у цьому сенсі простіше: їм достатньо скористатися пакетним менеджером та встановити Lua з репозиторіїв. У Debian і Ubuntu це робиться командою apt-get install lua, а Fedora, Red Hat і похідних дистрибутивах - yum install lua. Однак не довіряйте мені сліпо та зверніться до довідника вашої операційної системи, щоб дізнатися, як саме це робиться у вас.

2. Використовувати онлайн інтерпретатор.

Знаходиться за адресою http://www.lua.org/demo.html. Спочатку його може вистачити, проте надалі, коли ми торкнемося модулів, ви будете змушені використовувати офлайн-версію. Користуватися онлайн-інтерпретатором дуже просто: введіть у віконце з текстом вашу програму та натисніть кнопку Run. Програма буде виконана, у вікні Output з'явиться висновок вашої програми, а також звіти про помилки, якщо такі були допущені вами.

3. Використовувати IDE.

Наприклад, ZeroBrane Studio: http://studio.zerobrane.com/ . Є й інші – пошукайте в Інтернеті.

У ході сьогодні дві дещо різні версії Lua: 5.1 і 5.2. Я орієнтуватимуся на останню версію - версію 5.2, але обов'язково вкажу на важливі відмінності між нею і 5.1, оскільки остання теж досить поширена. До речі, Lua 5.1 виконує код у півтора рази швидше за Lua 5.2, щоб ви знали.

=== Урок №1 ===

Тож почнемо. Створіть в ізольованій від сторонніх файлів папці файл main.lua та напишіть у нього:

200?"200px":""+(this.scrollHeight+5)+"px");">
-- main.lua --
print("Hello world!")

Після чого запустіть у командному рядку (не забудьте переміститися в директорію з main.lua за допомогою cd):

200?"200px":""+(this.scrollHeight+5)+"px");">
> C:\lua\lua.exe main.lua

У відповідь інтерпретатор Lua видасть:

200?"200px":""+(this.scrollHeight+5)+"px");">
Hello world!

В принципі, цього слід було очікувати. У програмі ми викликали функцію print. Функція print приймає довільне число параметрів і виводить їх на екран. У цьому прикладі ми передали їй рядок (ланцюжок символів) "Hello world!". З таким же успіхом можна передати як параметр:

200?"200px":""+(this.scrollHeight+5)+"px");">
print(8) - якесь десяткове число
-- виведе: 8

Print(0xDEADBEEF) - шістнадцяткове число
-- виведе: 3735928559

Print("0xDEADBEEF") -- а це рядок, не число! Бачите лапки?
-- виведе: 0xDEADBEEF

Print(1.35e-4) -- число з плаваючою комою (дрібне число)
- Виведе 0.000135. 1.35e-4 слід розуміти як "1.35, помножене
- на десять в мінус четвертого ступеня, якщо хто не знає.

Print((198*99)-3*500 + 14/88) - вираз
-- Виведе значення виразу: 18102.159090909. Непогана альтернатива
- Настільному калькулятору!

Print(198/7, "fertilizer", 2^9) - кілька параметрів довільного
- Типу. Буде виведено значення кожного з них, розділені знаками
- Табуляції:
-- 28.285714285714 fertilizer 512
- Зверніть увагу, що лапки навколо fertilizer не виводяться!

Print(1,35) - два числа, а не десятковий дріб 1,35!
-- Кома використовується для розділення параметрів.
- Виведе:
-- 1 35

Знак "--" – не просто імітація знака тире, яка вставлена ​​для краси. Знаком "--" у Lua відзначаються коментарі: підказки для програміста, які ігноруються інтерпретатором, та призначені для того, щоб у коді було легше розібратися. Можете спробувати написати у програмі:

200?"200px":""+(this.scrollHeight+5)+"px");">
- print("nothing")

Інтерпретатор подумає, що це коментар, і не виконуватиме інструкцію.

Господині на замітку: якщо ви бажаєте надрукувати лише один рядок, можна написати виклик print так, без дужок:

200?"200px":""+(this.scrollHeight+5)+"px");">
print "Just one string"

Зручність, безперечно, сумнівна: просто майте на увазі, що так можна. Водночас такі виклики неприпустимі:

200?"200px":""+(this.scrollHeight+5)+"px");">
print 2 - не спрацює, 2 - не рядок.
print 2*2 + 6 - тим більше не спрацює

Str = "string!!" -- надали змінної str значення "string!!"
-- про змінні читайте нижче
print str - теж не спрацює.

У кожному з перелічених випадків програма просто відмовиться працювати. Таким чином, у "безскобковому" виклику за назвою функції може стояти лише рядковий літерал (тобто послідовність символів, укладена в лапки), і більше нічого. У майбутньому я розповім про цю особливість трохи докладніше, але зараз із вас вистачить і цього.

У будь-якій хорошій мові програмування можна оголошувати змінні: невеликі контейнери, які можуть містити будь-які дані. У Lua це робиться таким чином:

200?"200px":""+(this.scrollHeight+5)+"px");">
<имя_переменной> = <выражение>

Наприклад:

200?"200px":""+(this.scrollHeight+5)+"px");">
star = 8 -- Тепер у змінній star зберігається число 8
wars = "owl" - У змінній wars - рядок "owl"
jedi = 42/2 - У змінній jedi - число 21
luke = star * jedi -- У змінній luke - число 168 (так, 21 помножити на 8)

Значення змінних та виразів з ними також можна вивести на екран:

200?"200px":""+(this.scrollHeight+5)+"px");">
print(star, wars, jedi, jedi-star+luke)
- Виведе:
-- 8 owl 21 181

Тільки не намагайтеся скласти змінні star і wars - спробувавши додати 8 до "owl", ви нічого хорошого не досягнете!

Як ви мали помітити, ім'я у змінної може бути практично будь-яким: головне, щоб воно не починалося з цифри. Серйозно, ви навіть можете оголосити змінну з назвою print, і тоді функція print перестане працювати, тому що ім'я print посилатиметься на оголошену змінну. Але є група слів, які заборонено використовувати як назви змінних - це ключові слова мови, з якими ми поки що не познайомилися, але на які варто подивитися:

200?"200px":""+(this.scrollHeight+5)+"px");">
and break do else elseif end
false for function goto if in
local nil not or repeat return
then true until while

Створивши змінну з однією з цих назв, ви викличете помилку у програмі, і працювати вона точно не буде. Зверніть увагу: у Lua 5.1 ключового слова goto немає, і змінну так назвати можна, але ви краще не робіть так.
Також врахуйте, що імена змінних чутливі до регістру. Це означає, що foo, fOo, fOO і FOO - чотири різні змінні, тому якщо ви написали ім'я якоїсь змінної малими літерами, а пізніше написали його великими, то, швидше за все, програма не буде працювати коректно.

А тепер один важливий момент: що буде якщо ви випадково чи навмисно звернетеся до неіснуючої змінної? У більшості інших мов це викликає помилку, але в Lua така ситуація припустима. Вона трактується так, ніби неіснуюча змінна насправді існує, але її значення одно nil. nil- Запам'ятайте це слово! - особливий тип значення Lua, який означає "ніщо". Чи не нуль і не порожній рядок (рядок виду "" - спробуйте його вивести на екран), а просто ніщо. Порівняйте це з такою моделлю: є дві людини, одна з них має банківський рахунок, але на ньому немає грошей, а інший банківський рахунок немає взагалі. У термінах Lua буде вважатися, що на рахунку у першого – 0 доларів, а на рахунку у другого – nil. І навіть не доларів, а просто nil. Сподіваюся, я вас не заплутав.

Спробуйте, наприклад, запустити таку програму:

200?"200px":""+(this.scrollHeight+5)+"px");">
-- main.lua --
foo = "bar"
print(foo, baz)
- Виведе:
-- bar nil

Таким чином, у змінної baz якої немає, але вважається, ніби вона є, значення nil, і функція print розуміє це і виводить його на екран у вигляді рядка "nil". У Lua є хороший метод перевірки існування змінної: якщо значення змінної не дорівнює nil, вона принаймні оголошена. З іншого боку, можна явно оголосити змінну, рівну nil:

200?"200px":""+(this.scrollHeight+5)+"px");">
cool_var=nil

Так можна робити, і хоча це на перший погляд і здається дурним, так іноді роблять. У наступних уроках ви дізнаєтеся, хто і навіщо, і, напевно, почнете робити так само. Іноді, звичайно.
Будьте обережні з nil"ом: надрукувати nil можна, але робити з ним арифметичні операції не можна! Тобто, якщо print(nil) зійде вам з рук, то конструкція на кшталт 99+nil викличе помилку, навіть якщо вам хотілося б, щоб 99+ nil дорівнював 99. Повірте, я теж засмутився, коли дізнався.

Резюме:
1. Ми дізналися про функцію print, що вона вміє і як правильно викликати її без дужок.
2. Дізналися, як оголошувати змінні, як обчислювати вирази (щоправда, дуже трішки), які можуть бути імена у змінних.
3. Дізналися про nil, перейнялися його містичною загадковістю і здобули впевненість у тому, що в майбутньому багато буде пов'язано з ним.

Для допитливих і охочих зміцнити свої знання пропоную прості вправи,які можна не виконувати, якщо ви почуваєтеся і так достатньо компетентним:
1. Напишіть програму, яка виводить приспів вашої улюбленої пісні.
2. Спробуйте вивести наступні вирази. Спробуйте зрозуміти, чому деякі з них працюють, а деякі – ні. Подивіться, які помилки викликають вислови, що не спрацювали.

200?"200px":""+(this.scrollHeight+5)+"px");">
2 + "string";
6 + "14";
"box" - "vox";
1 * "11b"
"148" * "1e6";


3. Напишіть програму, яка обмінює дві змінні значення. Тобто:

200?"200px":""+(this.scrollHeight+5)+"px");">
a = 6502
b = 8086


Зробіть так, щоб a дорівнювала 8086, а b - 6502. Для цього створіть третю змінну і здійсніть нехитрі перестановки. Переконайтеся, що завдання вирішено правильно, викликавши print(a,b) до обміну та print(a,b) після.

Lua for Windows (LfW) – інтерпретована мова програмування, розроблена підрозділом Tecgraf Католицького університету Ріо-де-Жанейро. Розроблений інтерпретатор вільно розповсюджується, з відкритими вихідними текстами мовою Сі.

За можливостями, ідеології та реалізації мова найближча до JavaScript, проте Lua відрізняється більш потужними та набагато гнучкішими конструкціями. Хоча Lua не містить поняття класу та об'єкта у явному вигляді, механізми об'єктно-орієнтованого програмування, включаючи множинне успадкування, легко реалізуються з використанням метатаблиць, які також відповідають за перевантаження операцій тощо. Реалізована модель об'єктно-орієнтованого програмування – прототипна та в JavaScript).

Мова широко використовується для створення програмного забезпечення, що тиражується – зокрема, на ньому написаний графічний інтерфейс пакету Adobe Photoshop Lightroom. Також здобув популярність як мову програмування рівнів та розширень у багатьох іграх (наприклад, World of Warcraft) через зручність вбудовування, швидкість виконання коду та легкість навчання.

Lua зазвичай називають мультипарадигменною мовою. Він забезпечує невеликий набір базових механізмів, які можуть бути розширені для вирішення різних завдань, а не набір складних жорстких специфікацій, що забезпечують програмування єдиної парадигми.

Так, у Lua відсутня явна підтримка спадкування, проте воно легко реалізується за допомогою метатаблиць.

Це питання, яке виникає досить часто. Що, взагалі-то, досить дивно, тому що установка насправді вкрай проста і зрозуміла. Можна навіть сказати, що там взагалі нема чого робити. Але, якщо такі питання виникають, давайте трохи поговоримо про встановлення .

Встановлення Луа. Завантажуємо

Перше, що нам потрібно буде зробити перед встановленням, це завантажити вихідні записи з її офіційного сайту: . Для установки, звичайно, нам знадобиться остання версія, на даний момент це lua 5.1.4. Після скачування, звичайно, треба розархівувати вихідники lua в окрему папку.

Встановлення Луа. Компіляція.

Є два варіанти компіляції, які, в принципі, нічим не відрізняються))) Перший це компіляція з Visual Studio Command Prompt:

  1. Запускаємо Visual Studio
  2. Виконуємо Tools->Visual Studio Command Prompt
  3. Переходимо в папку з Луа, в директорію etc. Ось так: cd D:/mylibs/lua-5.1.4
  4. запускаємо скрипт компіляції Луа: etc/luavs.bat
  5. Ми отримали потрібні нам файли lua.exeі luac.exe

Другий спосіб без запуску Visual Studio:

  1. У будь-якому файл-мендежі (я особисто працюю в ) заходимо до папки де_луа/etc/
  2. Редагуємо файл, першим рядком ставимо: call “шлях_к_віжуалстудіо/VC/bin/vcvars32.bat”
  3. Додаємо другий рядок: cd.. та зберігаємо файл
  4. Запускаємо, отримуємо шукані екешники

Встановлення Луа. Доступ

Щоб ви могли запускати луа звідки завгодно – вам треба додати їх (шлях до них) у змінну оточення %PATH%. Думаю, Ви самі чудово знаєте, як це зробити. У будь-якому випадку нам не потрібні ці файли, т.к. ми плануємо використовувати луа внтрі наших програм, а не як окрему програму. Після цього вважайте, що сама установка Luaзавершена, вам лише залишається прописати в Visual Studio шляху в liba.

Встановлення Луа. Статична лінковка.

Мене особисто виводить із себе те, що з кожним проектом, який використовує Луа, доводиться тягати і lua.dll, оскільки без неї програми працювати не будуть. А що б вони працювали – треба що б луа лінкувалася з нашою програмою статично. Робиться це теж дуже легко:

  1. Робимо у Visual Studio новий проект, Win32Project, назвемо його "LuaLib"
  2. Тип проекту вказуємо "Static Library", відключаємо використання Precompiled Header, натискаємо Finish
  3. Додаємо в проект усі файли.h і.c, крім lua.c та luac.c
  4. Щоб компілятор не видавав нам варнінгів, в налаштування проекту (Protec/Propreties/Preprocessor) додаємо;_CRT_SECURE_NO_WARNINGS (не забудьте зробити це і для реліз, і для дебаг-версії!!!)
  5. У налаштуваннях лінківки (Project/Properties/Librarian/General/OutputFile) вказуємо які імена бібліотек ми хочемо. Я вказав lua.lib для релізу та lua-debug.lib для дебага.
  6. Компілюємо дебаг та реліз-версії. Отримуємо потрібні нам ліби
  7. Прописуємо шляхи до них у Visual Studio

Встановлення Луа. Перевірка.

Перевіримо, чи все працює. Створюємо новий проект (я зробив консольний проект Win32). Дописуємо інклюди Луа:

і доробляємо сам main():

int _tmain(int argc, _TCHAR* argv ) ( lua_State * L; L = lua_open() ; // Створюємо стек luaL_openlibs(L) ; //підключити стандартні бібліотеки int status = luaL_loadfile(L, "test.lua"); //завантажити файл /* Стан стtка: [-1]main<--top of the stack */ if (status) ((void) fprintf (stderr, "file not found \n "); return 1; ) int result = lua_pcall(L, 0, LUA_MULTRET, 0); _getch(); return 0; )

У налаштування лінковника (Project/Properties/Linker/Input/Addition Dependencies) не забуваємо додати нашу бібліотеку (lua.lib для релізу та lua-debug.lib для дебага). Компілюємо. Створюємо тестовий файл з луа-скриптом.

Скрипти мовою Lua

Написаний на Lua скрипт немає жодної спеціальної функції, з якої починалося б його виконання. Скрипт можна розглядати просто як набір команд (інструкцій), який виконується починаючи з першої інструкції.

Скрипт може бути дуже простим, що складається всього з однієї команди, так і дуже складним, що містить десятки, сотні і навіть тисячі інструкцій. Наступні один за одним інструкції можуть розділятися крапкою з комою (;). Однак ця вимога не є обов'язковою, тому весь наведений нижче код є коректним з погляду синтаксису:

Робота зі змінними в Lua

Змінні використовуються зберігання значень у процесі виконання скрипта.

Імена змінних у Lua

Іменами (ідентифікаторами) змінних Lua можуть бути будь-які послідовності з букв, цифр і символу підкреслення, що починаються не з цифри.

Зверніть увагу

Мова Lua розрізняє регістр символів, тому abc, Abc, ABC є різними іменами.

У нижченаведеній таблиці наведено слова, які зарезервовані мовою Lua і не можуть використовуватися в іменах змінних:

and break do else elseif

end false for function if

in local nil not or

repeat return then true until

Крім того, всі імена, що починаються з символу підкреслення, за яким йдуть великі літери (наприклад, _VERSION), також є зарезервованими.

Які змінні бувають у Lua?

Змінні в Lua можуть бути глобальними та локальними. Якщо змінна не оголошена як локальна, вона вважається глобальної.

Глобальні змінні Lua

Глобальна змінна з'являється в момент надання їй першого значення. До надання першого значення звернення до глобальної змінної дає nil.

MsgBox(tostring(g)) --> nil

MsgBox(tostring(g)) --> 1

Глобальна змінна існує до тих пір, поки існує середовище виконання скрипту і доступна будь-якому Lua-коду, що виконується в цьому середовищі.

При необхідності видалити глобальну змінну можна явно, просто надавши їй значення nil.

g = 1 - створюємо глобальну змінну g зі значенням 1

g = nil - видаляємо глобальну змінну g

MsgBox(tostring(g)) --> nil

Усі глобальні змінні є полями звичайної таблиці, яка називається глобальним оточенням. Ця таблиця доступна через глобальну змінну _G. Оскільки полями глобального оточення є всі глобальні змінні (включаючи _G), то _G._G == _G.

Локальні змінні Lua

Будь-які локальні змінні повинні бути оголошені з використанням ключового слова local. Оголосити локальну змінну можна будь-де скрипта. Оголошення може включати присвоювання змінної початкового значення. Якщо значення не надано, змінна містить nil.

local a - оголошуємо локальну змінну a

local b = 1 - оголошуємо локальну змінну b, присвоюємо їй значення 1

local c, d = 2, 3 - оголошуємо локальні змінні c і d, надають їм значення 2 і 3

Область видимості локальної змінної починається після оголошення і триває остаточно блоку.

Примітка

Областью видимості змінної називається ділянку коду програми, у якого можна отримати доступом до значення, що зберігається у цій змінної.

Під блоком розуміється:

тіло керуючої конструкції (if-then, else, for, while, repeat);

тіло функції;

фрагмент коду, укладений ключові слова do...end.

Якщо локальна змінна визначена поза будь-яким блоком, її область видимості поширюється остаточно скрипта.

local i = 1 – змінна i локальна в межах скрипту

while i<= a do - цикл от 1 до 5

local a = i^2 - змінна а локальна всередині циклу while

MsgBox(a) --> 1, 4, 9, 16, 25

MsgBox(a) -->

if i > 5 then

local a - змінна а локальна всередині then

MsgBox(a) --> 10

MsgBox(a) --> 5 (тут звернення до глобальної a)

local a = 20 - змінна, а локальна всередині do-end

MsgBox(a) --> 20

MsgBox(a) --> 5 (тут звернення до глобальної a)

Зверніть увагу

Якщо можливо, рекомендується використовувати локальні змінні замість глобальних. Це дозволить уникнути «засмічення» глобального простору імен та забезпечить кращу продуктивність (оскільки доступ до локальних змінних у Lua виконується дещо швидше, ніж до глобальних).

Типи даних Lua

Які типи даних підтримує мова Lua?

Lua підтримує такі типи даних:

1. Nil (нічого). Відповідає відсутності змінної значення. Цей тип представлений єдиним значенням – nil.

2. Boolean (логічний). До цього типу відносяться значення false (брехня) та true (істина).

За виконання логічних операцій значення nil розглядається як false. Всі інші значення, включаючи число 0 та порожній рядок, розглядаються як true.

3. Number (числовий). Служить уявлення числових значень.

У числових константах можна вказувати необов'язкову дробову частину та необов'язковий десятковий порядок, що задається символами "e" або "E". Цілочисельні числові константи можна задавати в шістнадцятковій системі, використовуючи префікс 0x.

Приклади допустимих числових констант: 3, 3.0, 3.1415926, 314.16e-2, 0xff.

4. String (рядковий). Служить для подання рядків.

Строкові значення задаються у вигляді послідовності символів, укладеної в одинарні або подвійні лапки:

a = «це рядок»

b = "це другий рядок"

Рядки, укладені в подвійні лапки, можуть інтерпретувати C-подібні послідовності, що управляють (escape-послідовності), що починаються з символу «\» (зворотний слеш):

\b (пробіл),

\n (переклад рядка),

\r (повернення каретки);

\t (горизонтальна табуляція),

(зворотний сліш);

"" (подвійна лапка);

(одинарна лапка).

Зверніть увагу

Символ у рядку також може бути представлений своїм кодом за допомогою escape-послідовності:

де ddd - послідовність не більше трьох цифр.

Крім лапок для визначення рядка можуть також використовуватися подвійні квадратні дужки:

Визначення рядка за допомогою подвійних квадратних дужок дозволяє ігнорувати всі escape-послідовності, тобто рядок створюється повністю так, як описано:

local a = [] у Lua]=]

Буде терміну: «визначення рядка [] у Lua»

5. Function (функція). Функції Lua можуть бути записані в змінні, передані як параметри в інші функції і повернуті як результат виконання функцій.

6. Table (таблиця). Таблиця є набором пар «ключ» - «значення», які називають полями або елементами таблиці. Як ключі, і значення полів таблиці може мати будь-який тип, крім nil. Таблиці не мають фіксованого розміру: у будь-який момент часу в них можна додати довільну кількість елементів.

Докладніше - у статті «Створення таблиць у Lua»

7. Userdata (користувацькі дані). Є спеціальним типом даних. Значення цього не можуть бути створені або змінені безпосередньо в Lua-скрипті.

Userdata використовується для представлення нових типів, створених у програмі, що викликає, або в бібліотеках, написаних мовою С. Наприклад, бібліотеки розширень Lua для «CronosPRO» використовують цей тип для представлення таких об'єктів, як:

банки даних (клас Bank);

бази даних (клас Base);

записи (клас Record) тощо.

8. Thread (потік). Відповідає потоку виконання. Ці потоки аж ніяк не пов'язані з операційною системою та підтримуються виключно засобами самого Lua.

Як у Lua задати тип змінної?

Lua не передбачає явного завдання типу змінної. Тип змінної встановлюється на момент присвоєння змінної значення. Будь-якій змінної може бути присвоєно значення будь-якого типу (незалежно від того, значення якого типу вона містила раніше).

a = 123 – змінна a має тип number

a = "123" - тепер змінна a має тип string

a = true – тепер змінна a має тип boolean

a = () - тепер змінна a має тип table

Зверніть увагу

Змінні типу table, function, thread і userdata не містять самих даних, а зберігають посилання на відповідні об'єкти. При наданні, передачі в функцію як аргумент і повернення з функції як результат копіювання об'єктів не відбувається, копіюються тільки посилання на них.

a = () – створюємо таблицю. У змінну a міститься посилання таблицю

b = a - змінна b посилається ту саму таблицю, як і a

a = 10 - елемент таблиці з індексом 1 присвоєно значення 10

MsgBox(b) --> "10"

MsgBox(a) --> "20"

Інші дані є безпосередніми значеннями.

MsgBox(a) --> "20"

MsgBox(b) --> "10"

Як у Lua отримати тип змінної?

Тип значення, збереженого змінної, можна з'ясувати за допомогою стандартної функції type. Ця функція повертає рядок, що містить назву типу ("nil", "number", "string", "boolean", "table", "function", "thread", "userdata").

t = type («це рядок») - t і «string»

t = type (123) - t дорівнює "number"

t = type (type) - t дорівнює "function"

t = type (true) - t дорівнює "boolean"

t = type (nil) - t дорівнює "nil"

t = type (CroApp.GetBank()) - t дорівнює "userdata"

Як у Lua перетворити тип змінної?

Lua за потреби автоматично перетворює числа в рядки і навпаки. Наприклад, якщо рядкове значення є операндом в арифметичній операції, воно перетворюється на число. Аналогічно числове значення, що зустрілося там, де очікується рядкове, буде перетворено на рядок.

a = "10" + 2 - a дорівнює 12

a = "10" + 2 - a дорівнює "10 + 2"

a = "-5.3e-10"*«2» - a дорівнює -1.06e-09

a = «рядок» + 2 – Помилка! Неможливо перетворити «рядок» на число

Значення будь-якого типу можна явно перетворити на рядок за допомогою стандартної функції tostring.

a = tostring(10) - a дорівнює «10»

a = tostring (true) - a дорівнює "true"

a = tostring (nil) - a так само «nil»

a = tostring (( = "це поле 1")) - a дорівнює "table: 06DB1058"

З попереднього прикладу видно, що вміст таблиць функцією доstring не перетворюється. Виконати це перетворення можна за допомогою функції render.

a = render (10) - a дорівнює "10"

a = render (true) - a дорівнює "true"

a = render (nil) - a так само «nil»

a = render (( = «це поле 1»)) - a одно "( = «це поле 1»)"

Для явного перетворення значення число можна використовувати стандартну функцію tonumber. Якщо значення є рядком, який можна перетворити на число (або вже є числом), функція повертає результат перетворення, інакше повертає nil.

a = tonumber («10») - a дорівнює «10»

a = tonumber («10»..".5") - a дорівнює 10.5

a = tonumber (true) - a дорівнює "nil"

a = tonumber (nil) - a дорівнює "nil"

Розміщення коментарів у Lua

Коментар Lua починається двома знаками «мінус» (--) і триває до кінця рядка.

local a = 1 - однорядковий коментар

Якщо безпосередньо після символів «--» йдуть дві квадратні дужки, що відкривають ([[), коментар є багаторядковим і триває до двох закриваючих квадратних дужок (]]).

local a = 1 - [[ багаторядковий

коментар ]]

Подвійні дужки у коментарях можуть бути вкладеними. Для того, щоб їх не переплутати, між дужками вставляється знак рівності (=):

local a = [[Компанія «Кронос»]] - [=[

local a = [[Компанія «Кронос»]]

Кількість символів "=" визначає вкладеність:

local a = [=[визначення деякого рядка [] у мові Lua]=] --[==[

local a = [=[визначення деякого рядка [] у мові Lua]=]

Операції, що застосовуються у Lua

У виразах, написаних на Lua, можна застосовувати такі види операцій:

1. Арифметичні операції.

Lua підтримує такі арифметичні операції:

+ (додавання);

- (віднімання);

* (множення);

/ (Поділ);

^ (зведення у ступінь);

% (залишок від ділення).

Зверніть увагу

Арифметичні операції застосовні як до чисел, і до рядків, які у разі перетворюються на числа.

2. Операції порівняння.

У Lua допустимі наступні операції порівняння величин:

== (Рівно);

~= (Не дорівнює);

< (меньше);

> (Більше);

<= (меньше или равно);

>= (більше чи одно).

Зверніть увагу

Операції порівняння завжди повертають логічне значення true чи false.

Правила перетворення чисел у рядки (і навпаки) при порівняннях не працюють, тобто вираз "0" == 0 дає в результаті false.

3. Логічні операції.

До логічних операцій належать:

and (логічне І).

Операція and повертає свій перший операнд, якщо вона має значення false чи nil. В іншому випадку операція повертає другий операнд (причому цей операнд може бути довільного типу).

a = (nil and 5) - a дорівнює nil

a == (false and 5) - a дорівнює false

a == (4 and 5) - a дорівнює 5

or (логічне АБО).

Операція or повертає перший операнд, якщо він не false і не nil, інакше він повертає другий операнд.

a == (4 або 5) - a дорівнює 4

a == (false or 5) - a дорівнює 5

Зверніть увагу

Логічні операції and та or можуть повертати значення будь-яких типів.

Логічні операції and і or обчислюють значення другого операнда лише тому випадку, якщо його повернути. Якщо це не потрібно, другий операнд не обчислюється. Наприклад:

a == (4 or f()) - виклику функції f() не відбудеться

not (логічне НЕ).

Операція не завжди повертає true або false.

4. Операція конкатенації.

Для конкатенації (об'єднання) рядків служить операція (дві точки).

a = «Кронос».."-"..«Інформ» - змінна a отримає значення «Кронос-Інформ»

Зверніть увагу

Якщо один або обидва операнди є числами, виконується їх перетворення на рядки.

a = 0..1 – змінна a отримає значення «01»

5. Операція отримання довжини.

Lua визначена операція довжини #, яку можна використовувати для отримання довжини рядка.

a = «рядок»

len = #a - len дорівнює 6

len = #«ще рядок» - len 10

Зверніть увагу

За допомогою операції # можна дізнатися максимальний індекс (або розмір) масиву. Докладніше - у статті «Робота з масивами в Lua».

Пріоритет операцій у Lua

У мові Lua виконання операцій здійснюється відповідно до наступного пріоритету (у порядку зменшення):

2. not # - (унарний)

6. < > <= >= ~= ==

Виклик скриптів із форм

З кожною формою (включаючи вкладені форми) пов'язаний окремий скрипт, який зазвичай містить функції, що виконують обробку подій форми та її елементів.

Коли форма запускається, її скрипт завантажується у світове оточення. У разі події форми чи її елемента система викликає зіставлену цієї події функцію-обработчик.

Скрипт форми, хоча і не містить виклику функції module, фактично є модулем. Це означає, що змінні, оголошені у скрипті форми без ключового слова local, не виносяться у глобальне оточення і доступні лише усередині цього скрипта. Якщо необхідно зробити якесь значення доступним для скриптів інших форм, його слід явно визначити у глобальній таблиці _G:

local a = _G.var

Блоки операторів (інструкцій)

До основних операторів Lua відносяться:

привласнення;

умовний оператор;

оператори в організацію циклів.

Група операторів може бути об'єднана в блок (складовий оператор) за допомогою конструкції do…end.

do - початок блоку

<оператор1>- тіло блоку

<оператор2>

<операторN>

end - кінець блоку

Блок відкриває нову область видимості, де можна визначати локальні змінні.

a = 5 - глобальна змінна a

local a = 20 - всередині do-end визначається локальна змінна

MsgBox(a) --> 20

MsgBox(a) --> 5 (тут звернення вже до глобальної a)

Оператор присвоєння в Lua

Надання змінює значення змінної або поля таблиці. У найпростішому вигляді привласнення може виглядати так:

a = 1 - змінною a надано значення 1

a = b + c - змінною a присвоєно суму значень змінних b і с

a = f(x) - змінною a присвоєно значення, повернене функцією f(x)

У Lua допускається так зване множинне присвоювання, коли кілька змінних, що знаходяться зліва від оператора присвоювання, отримують значення кількох виразів, записаних праворуч від оператора присвоювання:

a, b = 1, 5 * c - a дорівнює 1; b дорівнює 5*c

Якщо змінних більше ніж значень, «зайвим» змінним надається nil.

a, b, c = 1, 2 - a дорівнює 1; b дорівнює 2; c одно nil

Якщо значень більше, ніж змінних, «зайві» значення ігноруються.

a, b = 1, 2, 3 - a дорівнює 1; b дорівнює 2; значення 3 не використане

Множинне присвоєння можна використовувати для обміну значеннями між змінними:

a = 10; b = 20 - a дорівнює 10, b дорівнює 20

a, b = b, a - тепер a дорівнює 20, b дорівнює 10

Умовний оператор (if) у Lua

Оператор if перевіряє істинність заданої умови. Якщо умова є істинною, виконується частина коду, яка йде за ключовим словом then (секція then). В іншому випадку, виконується код, який слідує за ключовим словом else (секція else).

if a > b then

return a – якщо a більше b, повернути a

return b - інакше - повернути b

Секція else є необов'язковою.

if a< 0 then

a = 0 - якщо a менше 0, присвоїти a значення 0

Замість вкладених операторів if можна використовувати конструкцію elseif. Наприклад, наведений код:

буде простіше для сприйняття, якщо замінити його наступним:

return «Іван» - якщо a дорівнює 1

elseif a == 2 then

return «Петро» - якщо a дорівнює 2

elseif a == 3 then

return «Сергій» - якщо a дорівнює 3

return «Немає такого гравця» - якщо a - жодне з перерахованих

Цикл з передумовою (while) у Lua

Оператор while призначений для організації циклів з передумовою і має такий вигляд:

while do

… - тіло циклу

Перед кожною ітерацією циклу перевіряється умова :

якщо умова хибна, цикл завершується і керування передається першому оператору, що йде за оператором while;

якщо умова є істинною, виконується тіло циклу, після чого всі дії повторюються.

while i > 0 do - цикл від 10 до 1

t[i] = «поле» ..i

a = (3, 5, 8, -6, 5)

while i > 0 do - шукаємо у масиві негативне значення

if a[i]< 0 then break end - если найдено, прерываем цикл

i = i - 1 - інакше переходимо до наступного елементу

if i > 0 then

MsgBox («Індекс негативного значення: »..i)

MsgBox ("Масив не містить негативних значень")

Примітка

Цикл з постумовою (repeat) у Lua

Оператор repeat призначений для організації циклів з постумовою і має такий вигляд:

… - тіло циклу

until

Тіло циклу виконується доти, доки умова не стане справжнім. Перевірка умови здійснюється після виконання тіла циклу, тому в будь-якому випадку тіло циклу виконається хоча б один раз.

Підсумовуємо значення масиву a, доки сума не перевищить 10

a = (3, 2, 5, 7, 9)

sum = sum + a[i]

until sum > 10

MsgBox («Складено»..i.." елементів. Сума дорівнює "..sum)

Для виходу з циклу до завершення можна використовувати оператор break.

Примітка

Докладніше про особливості використання оператора break - у статті «Оператори break та return»

Цикли з оператором for Lua

Оператор for призначений для організації циклів та допускає дві форми запису:

просту (числовий for);

розширену (універсальний for).

Проста форма оператора for

Проста форма оператора має такий вигляд:

for var = exp1, exp2, exp3 do

… - тіло циклу

Тіло циклу виконується для кожного значення змінної циклу (лічильника) var в інтервалі від exp1 до exp2, з кроком exp3.

Примітка

Крок може не задаватися. І тут він приймається рівним 1.

for i = 1, 10 do - цикл від 1 до 10 з кроком 1

MsgBox («i одно»..i)

for i = 10, 1, -1 do - цикл від 10 до 1 з кроком -1

MsgBox («i одно»..i)

Зверніть увагу

Вирази exp1, exp2 і exp3 обчислюються лише один раз, перед початком циклу. Так, у прикладі нижче, функція f(x) буде викликана для обчислення верхньої межі циклу лише один раз:

for i = 1, f(x) do - цикл від 1 до значення, повернутий функцією f()

MsgBox («i одно»..i)

Змінна циклу є локальною для оператора циклу і після закінчення не визначена.

for i = 1, 10 do - цикл від 1 до значення, поверненого функцією f()

MsgBox («i одно»..i)

MsgBox («Після виходу з циклу i одно»..i) - Невірно! i одно nil

Зверніть увагу

Значення змінної циклу не можна змінювати всередині циклу: наслідки такої зміни непередбачувані.

Для виходу з циклу до завершення використовується оператор break.

a = (3, 5, 8, -6, 5)

for i = 1,#a do - шукаємо в масиві негативне значення

if a[i]< 0 then - если найдено...

index = i - зберігаємо індекс знайденого значення.

break - і перериваємо цикл

MsgBox («Індекс негативного значення: »..index)

Примітка

Докладніше про особливості використання оператора break - у статті «Оператори break та return»)

За Lua міцно закріпилася слава напівмови - інструмента, який при нагоді можна вбудувати, щоб заскриптувати додаток, написаний компілюваною мовою на кшталт С++. Тим не менш, Lua є цілком самостійною мовою, що має свій інтерпретатор, можливість створення модулів, велика кількість бібліотек, і при цьому даний ЯП має мінімальний розмір серед аналогів. Простіше кажучи, у нас є все, щоб створювати такі ж програми як на perl, python, і взагалі будь-якій іншій поширеній мові програмування.

Я можу запропонувати вам наступні аргументи на користь Lua:

  • - програми будуть легко переноситися між Windows і Linux (не факт, що код буде працювати без змін, але портування правда пройде безболісно, ​​якщо не були використані платформоспецифічні бібліотеки)
  • - малий оверхід створюваних програм
  • - висока швидкість роботи та завантаження додатків
  • - можливість оперативно «приклеїти» до вашої програми будь-яку С-бібліотеку - кращого «клею» для бібліотек ви не знайдете
  • - приємний мінімалістичний синтаксис мови, з можливістю реалізації на ньому сучасних парадигм програмування
  • - програми на Lua дуже легко розгортати
  • - мале споживання пам'яті

Щоб продемонструвати можливості Lua, я покажу, як з його використанням створити невелику програму для побудови графіків по точках з можливістю збереження графіка у вигляді файлу зображення.

Як графічний тулкіт будемо використовувати iup - кросплатформенну бібліотеку, спочатку створену з розрахунком використання з Lua.

Установка Lua SDK
В рамках ідеї використання Lua як самостійного ЯП, була створена збірка Lua for Windows, яка містить бібліотеки, необхідні в повсякденних завданнях, що виникають при програмуванні під зазначену ОС: роботи з БД, GUI, парсинг XML і т.д. Нехай вас не бентежить, що версія Lua у збірці 5.1, а не 5.2 – особливої ​​різниці в нашому випадку між ними немає.

Завантажте та встановіть складання.

Короткий опис концепції iup
Я довго думав, як розписати процес створення програми, не вдаючись докладно в пристрій iup. І вирішив коротко описати його основні засади:
  • - iup.dialog є кореневим елементом інтерфейсу програми – у цьому контейнері розміщуються всі елементи
  • - позиціонування елементів у контейнері здійснюється за допомогою layout-ів: завдання правил розміщення елемента у контейнері. Iup сам розташує та відобразить елемент згідно з правилами. Основні контейнери – кадр, вертикальний сайзер, горизонтальний сайзер.
  • - обробники подій задаються у вигляді функцій, прикріплених до віджету
  • - після створення діалогу запускається цикл обробки подій
Якщо ви раніше писали для GUI за допомогою Tk, WxWidgets або WinAPI, все це здасться знайомим. Якщо ні, то програма досить докладно вкрита коментарями.
Код програми

Підключення бібліотек iup require("iuplua") require("iupluacontrols") require("iuplua_pplot") - бібліотека для роботи з Canvas, щоб зберігати графік у файл require("cdlua") require("iupluacd") require("string ") -- глобальні змінні для віджетів і налаштувань програми -- максимальна кількість графіків plots_number = 5 -- віджети вкладок, де будуть розміщуватися віджеи введення даних для кожного графіка tabs = () -- контейнери для віджетів вибору того, які графіки будувати checkboxes = () -- тут зберігаємо віджети з текстом даних про точках coords = () -- віджети підпису для кожного графіка в Lua немає стандартної функції split function string:split(sep) local sep, fields = sep or ":", () local pattern = string.format("([^%s]+)", sep) self:gsub (pattern, function(c) fields[#fields+1] = c end) return fields end -- функція малює на плоттері графік за вказаними точками function draw_plot(pwidget, pnum, data) x = data.value:split(", ") y = data.value:split(",") if checkboxes.value == "OFF" then return end if not (#x == #y) or #x == 0 then iup.Message("Ошибка", "Задано неверное число точек для графика " .. pnum) return end iup.PPlotBegin(pwidget, 0) iup.PPlotAdd(pwidget, 0, 0) for i = 1,#x do iup.PPlotAdd(pwidget, x[i], y[i]) end iup.PPlotEnd(pwidget) end -- виджет отвечающий за кнопку построения графика plot_btn = iup.button{ title = "Побудувати"} -- колбэк для кнопки "построить график" function plot_btn:action() -- создать виджет графопостроителя plot = iup.pplot { expand="YES", TITLE = "Simple Line", MARGINBOTTOM="65", MARGINLEFT="65", AXS_XLABEL = global_legend.value, AXS_YLABEL = global_legend.value, LEGENDSHOW="YES", LEGENDPOS="TOPLEFT", size = "400x300" } -- этот блок для обхода бага - без него подпись к первому графику отображаться не будет iup.PPlotBegin(plot, 0) iup.PPlotAdd(plot,0,0) plot.DS_LEGEND = "" iup.PPlotEnd(plot) -- обходим виджеты с данными for i = 1, plots_number do -- чтобы свеженарисованный графи отобразился с правильной подписью print(legends[i].value) plot.DS_LEGEND = legends[i].value -- рисуем график draw_plot(plot, i, coords[i]) end -- кнопка сохранения графика в картинку на диске save_btn = iup.button{ title = "Зберегти" } -- теперь создаем само окно, где будет отображаться график plot_dg = iup.dialog { iup.vbox -- это вертикальный сайзер, помести в него графопостроитель и кнопку { plot, save_btn }, } -- обработчик кнопки сохранения графика function save_btn:action() -- создаем диалог выбора имени файла ля сохранения -- в связи с ограничениями библиотеки сохранять можно только в EMF fs_dlg = iup.filedlg{DIALOGTYPE = "SAVE", FILTER = "*.emf" } iup.Popup(fs_dlg) -- если файл выбран if tonumber(fs_dlg.STATUS) >= 0 then -- дописать при необходимости нужное расширение pic = fs_dlg.value if not (string.sub(pic, string.len(pic)-3) == ".emf") then pic = pic .. ".emf" end -- создаем псевдо-холст, ассоциированный с файлом tmp_cv = cd.CreateCanvas(cd.EMF, pic .. " 400x300") -- выводим график на холст iup.PPlotPaintTo(plot, tmp_cv) -- сохраняем данные в файл cd.KillCanvas(tmp_cv) end end -- отображаем диалог с графиком plot_dg:showxy(iup.CENTER, iup.CENTER) -- запускаем петлю обработки событий для диалога if (iup.MainLoopLevel()==0) then iup.MainLoop() end end -- в цикле создаем вкладки, в которых мы будем размещать виджеты -- для сбора данных for i=1,plots_number do -- создание текстовых виджетов, куда будут вводиться координаты точек coords[i] = {} for j = 1,2 do coords[i][j] = iup.text { expand="HORIZONTAL", multiline = "YES", VISIBLELINES = 5 } end -- виджет для редактирования подписи к графику legends[i] = iup.text{ expand = "HORIZONTAL" } -- создаем контейнер вкладки и заполняем его элементами vboxes[i] = iup.vbox { iup.hbox { iup.label { title = "Підпис графіка:" }, legends[i] }, iup.hbox { iup.label { title="X:", }, coords[i] }, iup.hbox { iup.label { title="Y:", }, coords[i] }; expand="YES", } -- меняем заголовк вкладки vboxes[i].tabtitle = "Графік" .. i -- создаем чекбокс, который будет указывать на то, нужно ли строить -- график по данным из указанной вкладки checkboxes[i] = iup.toggle{ title= "Графік" .. i, value = "ON" } end -- теперь из заполненных нами контейнеров создаем вкладки tabs = iup.tabs{unpack(vboxes)} -- создаем текстовые виджеты для редактирования подписей осей global_legend = iup.text{} global_legend = iup.text{} -- создаем фрейм для общих настроек графика frame = iup.frame { iup.vbox { iup.label{ title="Використати дані:", expand="HORIZONTAL" }, iup.vbox { unpack(checkboxes) }, iup.label{}, -- пустую подпись можно использовать как распорку iup.label{title = "Підписи"}, iup.hbox { iup.label{ title = "Вісь X"}, global_legend }, iup.hbox { iup.label{ title = "Вісь Y"}, global_legend }, iup.label{}, plot_btn }; expand = "VERTICAL", } -- создаем главное окно программы и наносим на него настройки и табы dg = iup.dialog { iup.hbox { frame, tabs }, title="Будуємо графік", size = "HALF" } -- показываем главное окно и запускаем обработку событий dg:showxy(iup.CENTER, iup.CENTER) if (iup.MainLoopLevel()==0) then iup.MainLoop() end !}

Пара слів про розгортання
Скрипт можна запустити за допомогою команди:

Lua plotter.exe

У цьому випадку бібліотеки підключатимуться з піддиректорії clibs/, яка знаходиться в директорії, куди було встановлено Lua for Windows. Щоб максимально компактно запакувати скрипт та бібліотеки для перенесення на іншу машину, достатньо скопіювати в одну папку наступні файли (вказані з відносними шляхами від директорії установки Lua):

Lua.exe lib/lua5.1.dll clibs/cd.dll clibs/cdlua51.dll clibs/iup.dll clibs/iup_pplot.dll clibs/iupcd.dll clibs/iupcontrols.dll clibs/iupgl.dll clibs/iuplua51.dll clibs/iuplua_pplot51.dll clibs/iupluacd51.dll clibs/iupluacontrols51.dll clibs/freetype6.dll

Не забудьте помістити в цю папку сам скрипт з програмою. Тепер ви можете перенести цю папку на іншу машину і запустити вашу програму командою, вказаною вище. При цьому жодні інші дії щодо встановлення бібліотек та рантайму не потрібні.

На жаль, файли cd.dll, cdluad51.dll і iupcd.dll в даній версії Lua for Windows можуть працювати некоректно, тому рекомендую взяти їх з архіву за посиланням нижче.

Підсумки
Архів з робочою версією для зручності додана пускалка app.bat.

Скріншоти:

В результаті отримали, хай і непоказну, утиліту, що має такий же функціонал, як і якби вона була написана «серйозною» мовою програмування. При цьому просту у розгортанні та сумарною вагою менше 2 мб. Споживання пам'яті – близько 7 мб. Вихідний код доступний для редагування, сам Lua інтерактивно зрозумілий, що спрощує доопрацювання такого софту на місцях.

На мою думку, це чудовий вибір для написання навчального софту для шкіл та інститутів, а також для внутрішнього використання на підприємствах. Так як слабкі машини досі удосталь присутні в подібних місцях по всій СНД, то використання Luа подібним чином доцільно, особливо у світлі поступового приходу Linux на робочі столи. До того ж тенденцію втрати вихідних самописного софту при моторошній його ж забагаваності можна прирівняти до національного лиха.

Теги: Додати теги

© 2024 androidas.ru - Все про Android