Содержание


Для чего нужен Lua

Часть 1.Первый взгляд

Comments

Серия контента:

Этот контент является частью # из серии # статей: Для чего нужен Lua

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Для чего нужен Lua

Следите за выходом новых статей этой серии.

Восход «Луны» (краткая история)

В 1993 году Роберто Иерусалимши (Roberto Ierusalimschy), Луис Энрике де Фигуэйредо (Luiz Henrique de Figueiredo) и Вальдемар Селес (Waldemar Celes), члены группы разработки технологий компьютерной графики (Tecgraf) Епископального католического университета Рио-де-Жанейро (Pontifical Catholic University of Rio de Janeiro) в Бразилии создали скриптовый язык, сочетающий свойства императивных и функциональных языков и обладающий объектно-ориентированными свойствами. Назвали его португальским словом Lua (произносится "лууэ" [ˈluː.ə]), что в переводе означает "луна". "Новолунию" способствовали такие языки программирования, как Scheme, SNOBOL, JavaScript, C/C++ и некоторые другие. Авторы поставили перед собой задачу: разработать встраиваемый, легко расширяемый скриптовый язык с простым синтаксисом, не ограниченный какой-либо одной платформой, а кроме того, обладающий так называемой "мультипарадигмностью" (комбинирование императивной и функциональной парадигм).

В чём сила Lua (функциональные возможности)

Сам язык Lua предоставляет небольшой набор функциональных возможностей, которые могут быть расширены для решения разнообразных типов задач. Например, в Lua нет прямой реализации механизма поддержки наследования, но её без труда можно реализовать с помощью метатаблиц. Аналогичным образом программист может реализовать пространства имён и классы.

Lua является языком с динамической типизацией. В нём поддерживается минимальный набор элементарных типов данных: логические (boolean) значения, числа с плавающей точкой двойной точности (по умолчанию) и строки. Единственным составным типом данных в Lua является таблица (table), с помощью которой могут быть представлены массивы, списки, записи и прочие структуры данных. Собственно говоря, таблица – это гетерогенный ассоциативный массив или, другими словами, хэш, где могут храниться различные типы данных.

Поддержка ламбда-функций позволяет воспользоваться многими преимуществами функционального подхода к программированию, а полноценная реализация лексических областей видимости (scope) объектов обеспечивает регулируемое сокрытие информации в соответствии с принципом "минимальных привилегий".

Кроме того, в Lua имеется расширенный набор функциональных возможностей: механизм сборки мусора, автоматическое преобразование между числовыми и строковыми значениями во время выполнения, механизм кооперативной многозадачности (сопрограммы) и динамическая загрузка модулей.

Базовые элементы языка Lua и пример кода

На момент написания статьи я использовал версию Lua 5.1.4 (Lua выпускается по лицензии MIT License). Авторы постоянно продолжают усовершенствовать язык, поэтому между версиями могут существовать определённые различия.

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

print( "Простейший калькулятор" )
-- Принимает два числа, затем знак операции и вычисляет арифметическое выражение
--[[ Допустимые символы – знаки операций:
     + сложение
     - вычитание
     * умножение
     / деление ]]
while true do
 io.write( "Введите первое число (или q – выход из программы): " )
 n1 = io.read()     -- числовое значение принимается как строковое
 if n1 == "q" then
  break
 end
 io.write( "Введите второе число: " )
 n2 = io.read()
 io.write( "Введите знак операции (+ - * /): " )
 oper = io.read()
 if oper == "+" then
 -- при вычислениях выполняется автоматическое преобразование строк в числа
  print( "Сумма равна " .. n1+n2 )
 else
  if oper == "-" then
    print( "Разность равна " .. n1-n2 )
  else
    if oper == "*" then
     print( "Произведение равно " .. n1*n2 )
    else
     if oper == "/" then
      if n2 == "0" then print( "Нуль в знаменателе!" )
      else              print( "Частное равно " .. n1/n2 )
      end
     else
      print( "Неизвестный символ операции: " .. oper )
     end
    end
  end
 end
end

Всё начинается с вывода строки (своего рода заголовка программы), выполняемого функцией print. Особенность этой функции – автоматический переход на новую строку после завершения вывода. Далее следует комментарий, начало которого обозначено двумя дефисами (без пробела между ними). Если необходим многострочный комментарий, то можно воспользоваться вариантом --[[ ... ]], как в следующих нескольких строках (опять же, без пробелов в открывающей и закрывающей частях).

В условии цикла while записано логическое значение true, т. е. теоретически этот цикл должен выполняться бесконечно. На практике в теле подобного цикла создаются возможности для его завершения, и мы создадим такую возможность несколькими строками ниже.

После этого в работу включается стандартный модуль (библиотека) io, по имени которой можно понять, что она предоставляет функции ввода-вывода. Как уже было отмечено ранее, модули подгружаются динамически при обращении к ним. Функция write из этого модуля выводит всё, что ей передано, как аргумент, но не выполняет переход на новую строку в отличие от функции print.

Переменной n1 сразу присваивается результат считывания из стандартного устройства ввода (за это отвечает функция read из того же модуля io) без каких-либо предварительных объявлений и без указания типа данных. Мы уже говорили о том, что Lua – это язык с динамической типизацией, поэтому тип переменной определяется из контекста её использования. В данном случае функция read возвращает любые вводимые значения как строковые, и в переменной n1 будет сохранена строка символов (даже если введён один символ, ведь символьного типа в Lua нет). При записи имён и других синтаксических элементов языка учитывается регистр букв, т. е. переменные n1 и N1 представляют абсолютно разные объекты, а Io – это уже не имя модуля ввода/вывода, а определённый пользователем идентификатор.

Поскольку пользователю предлагается ввести либо числовое значение, либо символ "q" для выхода из программы, необходимо проверить содержимое переменной n1, и если оно действительно совпадает со строкой "q", то по команде break происходит выход из цикла, следовательно, программа заканчивает свою работу. Если была введена любая другая строка, то выполнение программы продолжается.

После завершения всех операций ввода начинается часть анализа и обработки введённых данных. Конструкция проверки условия и выбора ветви выполнения на основании результата этой проверки выглядит вполне привычно: if <условие> then <ветвь 1> else <ветвь 2> end. Допускается организация нескольких уровней вложенности, что и продемонстрировано в данном примере.

А вот строки, в которых выполняется вывод результатов, выглядят немного необычно. Оператор .. позволяет объединять ("склеивать") две строки или строку и числовое значение, как в нашем случае. Обратите внимание на то, что здесь выполняется арифметическая операция с участием переменных n1 и n2, хотя ранее говорилось о присваивании этим переменным строковых значений вне зависимости от фактического ввода. Проблему решает механизм автоматического преобразования типов. Перед выполнением вычислений строки в n1 и n2 преобразуются в числовые значения, а результат операции снова превращается в строку перед объединением.

Обратите внимание на отсутствие разделителей команд. В Lua допускается запись точки с запятой в конце команды, как в C-подобных языках, но это не является обязательным требованием. Отступы от начала строки с помощью пробелов и табуляций не играют никакой синтаксической роли (в отличие от Python), т. е. формат записи свободный.

Сохраним приведённую выше программу в файле с именем my_calc.lua, запустим наш калькулятор:

lua my_calc.lua

и проверим его функционирование. А если вспомнить, что Lua представляет собой интерпретируемый или скриптовый язык, то по аналогии с shell, Perl, Python и проч. можно в самом начале файла my_calc.lua добавить строку идентификации

#!/usr/bin/lua

и сделать этот файл выполняемым

chmod 755 my_calc.lua

После этого команда запуска будет выглядеть следующим образом:

./my_calc.lua

Заключение

В данной статье рассматривались общие характеристики и базовые элементы языка программирования Lua. В следующих статьях цикла мы расскажем о практическом применении более сложных компонентов Lua и его интеграции с другими языками программирования.


Ресурсы для скачивания


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=465956
ArticleTitle=Для чего нужен Lua: Часть 1.Первый взгляд
publish-date=02022010