1 – Getting Started
To keep with the tradition, our first program in Lua just prints «Hello World» : If you are using the stand-alone Lua interpreter, all you have to do to run your first program is to call the interpreter (usually named lua ) with the name of the text file that contains your program. For instance, if you write the above program in a file hello.lua , the following command should run it:
As a slightly more complex example, the following program defines a function to compute the factorial of a given number, asks the user for a number, and prints its factorial:
Информация Гайд [LUA] Запускаем скрипты на своем ПК.
Все ниже перечисленное я тестировал на Windows 10, поэтому я не гарантирую, что все ниже написанное будет работать на других ОС.
Первое, что нам нужно сделать, так это скачать LuaJIT компилятор.
Для того, чтобы запустить это чудо, нам необходимо открыть командную строку (WIN+R->cmd) и ввести в нее следующую команду:
Проверяем и создаем скрипт, который будет отправлять сообщение в телеграм при запуске скрипта:
Теперь устанавливаем его и в списке расширений находим его и нажимаем на значок шестриренки. В появившемся окошке выбираем пункт "Параметры расширения".
Далее ставим галочки у "Clear Previous", "Run In Terminal", "Save File Before Run". Как мы видим, в верхней панельке, рядом с открытыми файлами появился значок запуска скрипта (скрипт можно также запустить комбинацией клавиш CTRL+ALT+N).
Думаю на этом можно заканчить.
Простой гайд: как настроить Visual Studio Code для запуска Lua файлов
Visual Studio Code (VS Code) — это популярный текстовый редактор, который обладает множеством возможностей и предоставляет удобную среду разработки для многих языков программирования, включая Lua. В данной статье мы расскажем, как настроить VS Code для запуска Lua файлов.
Шаг 1: Установка Visual Studio Code
Первым шагом является установка Visual Studio Code. Вы можете скачать его с официального веб-сайта https://code.visualstudio.com/ и установить на свой компьютер, следуя инструкциям, предоставляемым установщиком.
Шаг 2: Установка расширения для поддержки языка Lua
После установки IDE Visual Studio Code необходимо установить расширение для поддержки языка программирования Lua. Для этого следуйте инструкциям ниже:
- Откройте IDE Visual Studio Code.
- Нажмите на значок "Extensions" в боковой панели слева (или используйте комбинацию клавиш Ctrl+Shift+X ).
- Введите "Lua" в строке поиска и выберите расширение "Lua" от компании "sumneko".
- Нажмите кнопку "Install", чтобы установить расширение.
Шаг 3: Создание и настройка конфигурации запуска
Теперь, когда у нас есть установленное расширение Lua, мы можем настроить конфигурацию запуска Lua файлов. Это позволит нам запускать и отлаживать Lua-приложения из состава Visual Studio Code. Следуйте инструкциям ниже:
- Откройте панель "Run and Debug" в Visual Studio Code (или используйте комбинацию клавиш Ctrl+Shift+D ).
- Нажмите на значок с шестеренкой "Create a launch.json file". Если файл конфигурации уже создан, пропустите этот шаг.
- В появившемся выпадающем меню выберите тип "Lua".
- В открывшемся файле launch.json укажите путь к своему Lua-файлу в секции "program".
Шаг 4: Запуск и отладка Lua-файлов
Теперь, когда все настройки завершены, мы готовы запускать и отлаживать Lua-файлы. Следуйте инструкциям ниже:
- Откройте Lua-файл, который вы хотите запустить или отладить.
- Нажмите клавишу F5 или выберите "Start Debugging" в меню "Run and Debug".
- Ваш Lua-файл будет запущен, и вы сможете отслеживать выполнение кода, устанавливать точки останова и использовать другие инструменты отладки.
Заключение
Поздравляем! Вы успешно настроили Visual Studio Code для запуска и отладки Lua-файлов. Теперь вы можете наслаждаться удобством разработки на языке Lua в одной из самых популярных сред разработки.
Lua 5.3 Руководство
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
перевел Ведерников Николай, Лысьва.
1 – Введение
Lua — язык программирования расширений, разработан для поддержки общего процедурного программирования с возможностью описания данных. Lua также предлагает хорошую поддержку объектно-ориентированного, функционального и управляемого данными (data-driven) программирования. Lua предлагается как мощный и лёгкий встраиваемый скриптовый язык для любой программы, которая в этом нуждается. Lua реализован как библиотека, написан на чистом C, общее подмножетво стандартного C и C++.
Как язык расширений, Lua не имеет понятия «главной» программы: он работает только как встроенный в основную программу клиент, встраивающая программа называется хост (host). Встраивающая программа может вызывать функции для запуска кусочков Lua кода, может писать и читать Lua переменные, может регистрировать C-функции чтобы вызывать их из Lua кода. Через использование С-функций Lua может быть расширен для решения различных задач, таким образом созданные адаптированные языки программирования имеют общую синтаксическую базу. Дистрибутив Lua включает простую хост-программу lua , которая использует библиотеку Lua для реализации полного независимого Lua интерпретатора, для интерактивного или пакетного использования.
Lua бесплатное программное обеспечение и предоставляется безо всяких гарантий. Официальный сайт www.lua.org .
Как и любое другое руководство, это руководство местами сухо. Описание решений принятых в основе дизайна Lua есть на технических страницах официального сайта. Детальное введение в программирование на Lua представлено в книге Роберто Иерусалимского Programming in Lua.
2 – Базовые концепции
Этот раздел описывает базовые концепции языка.
2.1 – Значения и типы
Lua динамически типизированный язык. Это означает, что значения не имеют типов; только значения. Язык не имеет определений типов. Все значения несут свой собственный тип.
Все значения в Lua первоклассные. Это означает что все значения могут быть сохранены в переменных, переданы как аргументы другим функциям, и возвращены как результаты.
В Lua существует восемь базовых типов: nil, boolean, number, string, function, userdata, thread и table.
Тип nil (нуль) имеет одно единственное значение, nil, его главное свойство это отличаться от любых других значений; обычно это означает отсутствие используемого значения.
Тип boolean (логический) имеет два значения: false (ложь) и true (истина). Оба nil и false означают false; любое другое значение означает true.
Тип number (число) представляет целые (integer) и вещественные (float) числа.
Тип string (строка) представляет неизменные последовательности байт. Строки в Lua могут содержать любое 8-битное значение, включая нули (‘ \0 ‘). Также Lua противник кодировок; никаких предположений о содержимом строки не делается.
Тип number использует два внутренних представления, или два подтипа, один называется integer (целое), второй float (число с плавающей запятой). Lua имеет явные правила о том, когда какое представление использовать, но при необходимости автоматически конвертирует значение между ними (см. §3.4.3). Следовательно, в большистве случаев программист может игнорировать разницу между целыми и реальными числами, или получить полный контроль над представлением каждого числа. Стандартный Lua использует 64-битные целые (integer) и вещественные числа двойной точности (double 64-bit), но также возможно скомпилировать Lua так, чтобы использовались 32-битные целые и/или вещественные числа одинарной точности (float 32-bit). Эта опция с 32 битами для целых и вещественных чисел особенно актуальна для малых машин и встроенных систем. (Смотри макрос LUA_32BITS в файле luaconf.h .)
Lua может вызывать и манипулировать функциями написанными на Lua и на С (см. §3.4.10). Оба типа функций в Lua представлены типом function (функция).
Тип userdata (пользовательские данные) предназначен для хранения произвольных С данных в Lua переменных. Значение userdata представляет блок памяти (raw memory). Существуют два типа пользовательских данных: full userdata (полные пользовательские данные) — объект с блоком памяти, которым управляет Lua, и light userdata (лёгкие пользовательские данные) — простой С указатель. Пользовательские данные не имеют предопределенных операторов в Lua, кроме оператора присвоения и сравнения на идентичность. Используя метатаблицы, программист может определить операции для значений full userdata (см. §2.4). Значения userdata не могут быть созданы или изменены в Lua, это возможно только через C API. Это гарантирует целостность данных, которыми владеет хост-программа.
Тип thread (поток) представляет независимый поток выполнения и используется для реализации сопрограмм (coroutine) (см. §2.6). Lua потоки это не реальные потоки операционной системы. Lua поддерживает сопрограммы на всех системах, даже на тех, где это не поддерживается операционной системой.
Тип table (таблица) реализует ассоциативные массивы, это значит, что массив может быть проиндексирован не только числами, но и любым Lua значением, кроме nil и NaN. (Not a Number специальное значение для представления неопределенных и непредставимых числовых результатов, таких как 0/0 .) Таблицы могут быть гетерогенными (разнородными); т.е. могут содержать значения всех типов (кроме nil). Любой ключ со значением nil не считается частью таблицы. И наоборот, любой ключ, не являющийся частью таблицы, имеет ассоциированное значение nil.
Таблицы единственный механизм структурирования данных в Lua; они могут использоваться для представления обычных массивов, последовательностей, таблиц символов, множеств, записей, графов, деревьев и т.п. Для представления записей, Lua использует имена полей как индекс. Язык поддерживает представление a.name , как синтаксическое украшение a[«name»] . Существуют различные пути создания таблиц в Lua (см. §3.4.9).
Мы используем термин последовательность (sequence) чтобы обозначить таблицу, где все ключи это натуральные числа <1..n> (1,2,3. ), где n — длина последовательности (см. §3.4.7).
Как и индексы, значения полей в таблице могут быть любого типа. В частности, т.к. функции это первоклассные значения, поля таблицы могут содержать функции. Такие таблицы также могут содержать методы (см. §3.4.11).
Индексирование в таблицах следует принципу «сырого» (raw) равенства в языке. Выражения a[i] и a[j] определяют один и тот же элемент таблицы, если и только если i и j равны (raw equal) (значит, равны без метаметодов). В частности, вещественные числа (float) с целыми значениями равны соответствующим целым (integer), т.е., 1.0 == 1 . Во избежание неоднозначностей, любое реальное число с целым значением, которое испльзуется как ключ, конвертируется в соответствующее ему целое число. Например, если написать a[2.0] = true , фактически в таблицу будет вставлен целочисленный (integer) ключ 2 . С другой стороны, 2 and » 2 » разные Lua значения и следовательно обозначают разные данные в таблице.
Таблицы, функции, потоки и пользовательские данные (userdata) — это объекты: переменные фактически не содержат их значений, только ссылки на них. Присвоение, передача параметров и возврат из функций всегда манипулируют ссылками на эти значения; эти операции не подразумевают никакого типа копирования.
Библиотечная функция type возвращает строку с названием переданного ей типа (см. §6.1).
2.2 – Окружения и глобальное окружение
Как будет описано в §3.2 и §3.3.3, любая ссылка на свободное имя (т.е., имя не связанное ни с каким определением) var синтаксически транслируется в _ENV.var . Кроме того, каждый кусок (chunk) компилируется в области внешней локальной переменной, называемой _ENV (см. §3.3.2), таким образом _ENV само никогда не бывает свободным именем в куске.
Несмотря на существование этой внешней переменной _ENV и трансляцию свободных имен, _ENV полностью регулярное имя. В частности, вы можете определить новые переменные и параметры с этим именем. Каждая ссылка на свободное имя использует _ENV , которая видима в данной точке программы, следуя обычным правилам видимости Lua (см. §3.5).
Любая таблица, используемая как значение переменной _ENV , называется окружение (environment).
Lua хранит особое окружение, называемое глобальное окружение. Это значение хранится по специальному индексу в С реестре (см. §4.5). В Lua, глобальная переменная _G инициализируется тем же значением. ( _G никогда не используется непосредственно.)
Когда Lua загружает кусок (chunk), по умолчанию его _ENV upvalue присваивается значение глобального окружения (см. load ). Следовательно, по умолчанию, свободные имена в Lua коде ссылаются на элементы в глобальном окружении (и, следовательно, они также называются глобальными переменными). Кроме того, все стандартные библиотеки загружаются в глобальное окружение и некоторые их функции действуют в этом окружении. Вы можете использовать load (или loadfile ) для загрузки куска с другим окружением. (В C, вы загружаете кусок и затем изменяете его первое upvalue.)
2.3 – Обработка ошибок
Так как Lua встроенный язык расширений, все Lua действия начинаются с C кода; код в хостовой программе вызывает функцию в Lua библиотеке. (При использовании автономного интерпретатора Lua, программа lua выступает в качестве хоста.) Всякий раз, когда происходит ошибка компиляции или выполнения куска Lua кода, управление возвращается хостовой программе, которая может предпринять соответствующие меры (такие как печать сообщения об ошибке).
Lua код может явно сгенерировать ошибку, вызвав функцию error . Если вы нуждаетесь в перехвате ошибок в Lua, вы можете использовать pcall или xpcall для вызова функции в защищенном режиме.
При каждой ошибке, создается объект ошибки (также называемый сообщением об ошибке) с информацией об ошибке. Самостоятельно Lua генерирует только те ошибки, где объект ошибки содержит строку, но программы могут генерировать ошибки с любым значением в объекте ошибки. Объекты ошибки (исключения) пробрасываются вверх в Lua или в хост для обработки.
Когда вы используете xpcall или lua_pcall , вы можете определить обработчик сообщений, который будет вызываться в случае ошибок. Эта функция вызывается с оригинальным сообщением об ошибке и возвращает новое сообщение об ошибке. Она вызывается до раскрутки стека, так она сможет получить больше информации об ошибке, например, проверяя стек и создавая историю стека (stack traceback). Этот обработчик сообщений остается защищенным в защищенном вызове; так, ошибка в обработчике сообщений лишь вызовет его снова. Если этот цикл будет достаточно длинным, Lua прервет его и вернет соответствующее сообщение.
2.4 – Метатаблицы и метаметоды
Каждое значение в Lua может иметь метатаблицу. Эта метатаблица обычная Lua таблица, которая определяет поведение оригинального значения в определенных специальных операциях. Вы можете изменять различные аспекты поведения в операциях со значением, изменяя специфические поля в метатаблице. Например, когда не цифровое значение является операндом в сложении, Lua проверяет есть ли в его метатаблице поле » __add » с функцией. И, если оно существует, Lua вызывает эту функцию для выполнения сложения.
Ключи в метатаблице это производные от имен событий; соответствующие им значения называются метаметоды. В предыдущем примере, событие — «add» (добавить) и метаметод — функция, которая выполняет сложение.
Вы можете запросить метатаблицу любого значения, используя функцию getmetatable .
Вы можете заменить метатаблицу таблицы, используя setmetatable . Нельзя изменять метатаблицы других типов из Lua кода (кроме, как используя библиотеку отладки (§6.10)); для этого вы должны использовать C API.
Таблицы и полные пользовательские данные (full userdata) имеют индивидуальные метатаблицы (хотя таблицы и пользовательские данные могут совместно использовать свои метатаблицы). Значения остальных типов используют одну метатаблицу на тип; т.е, существует одна метатаблица для всех чисел, одна для всех строк и т.д. По умолчанию, значения не имеют метатаблицу, но строковая библиотека создает метатаблицу для строкового типа (см. §6.4).
Метатаблица контролирует, как объект ведет себя в арифметических и битовых операциях, сравнениях при сортировке, конкатенации, определении длины, вызовах и индексировании. Метатаблица также может определять функцию, которая будет вызвана для таблицы или пользовательских данных при уничтожении сборщиком мусора (§2.5).
Детальное описание событий, контролируемых метатаблицами, представлено ниже. Каждая операция идентифицируется соответсвующим именем события. Ключ для каждого события это строка начинающаяся с двух подчеркиваний, ‘ __ ‘; например, ключ для операции «add» строка » __add «. Имейте ввиду, что запросы метаметодов всегда прямые; доступ к метаметоду не запускает других метаметодов
- «add»: + операция. Если любой операнд при сложении не число (и не строка, которую можно преобразовать в число), Lua попробует вызвать метаметод. Сначала, Lua проверит первый операнд (даже если он правильный). Если этот операнд не определяет метаметод для события » __add «, Lua проверит второй операнд. Если Lua найдет метаметод, он будет вызван с двумя операндами в качестве аргументов, и результат вызова (скорректированный до одного значения) будет результатом операции. Иначе будет сгенерирована ошибка.
- «sub»: — операция (вычитание). Аналогично операции «add».
- «mul»: * операция (умножение). Аналогично операции «add».
- «div»: / операция (деление). Аналогично операции «add».
- «mod»: % операция (остаток от деления). Аналогично операции «add».
- «pow»: ^ операция (возведение в степень). Аналогично операции «add».
- «unm»: — операция (одноместный минус). Аналогично операции «add».
- «idiv»: // операция (целочисленное деление). Аналогично операции «add».
- «band»: & операция (битовое И). Аналогично операции «add», за исключением того, что Lua будет использовать метаметод, если любой из операндов не целое и не значение приводимое к целому (см. §3.4.3).
- «bor»: | операция (битовое ИЛИ). Аналогично операции «band».
- «bxor»:
Как и для индексированного доступа, метаметод для этого события может быть функцией или таблицей. Если это функция, то она вызывается с table , key и value в качестве аргументов. Если таблица, Lua производит индексированное присваивание для этой таблицы с тем же ключом и значением. Это присваивание регулярное, не прямое, и оно также может вызывать срабатывание другого метаметода.
Хорошая практика, добавлять все необходимые метаметоды в таблицу перед тем, как назначить её метатаблицей какого-то объекта. В частности, метаметод » __gc » работает только если была соблюдена эта последовательность (см. §2.5.1).
2.5 – Сборка мусора
Lua выполняет автоматическое управление памятью. Это означает, что вы не должны беспокоиться о выделении памяти новым объектам или об освобождении памяти, когда объекты больше не нужны. Lua управляет памятью, запуская сборщик мусора для сборки всех мёртвых объектов (т.е., объектов более не доступных из Lua). Вся память, используемая Lua, подлежит автоматическому управлению: строки, таблицы, пользовательские данные, функции, потоки, внутренние структуры и т.д.
Lua реализует пошаговый отмечающий-и-очищающий сборщик. Для контроля циклов очистки мусора используются два числа: пауза сборщика мусора и множитель шагов сборщика мусора. Оба числа используют процентные пункты как единицы (т.е., значение 100 означает внутреннее значение 1).
Пауза сборщика мусора контролирует, как долго сборщик ждет перед началом нового цикла. Чем больше значение, тем менее агрессивен сборщик. Значения меньше 100 означают, что сборщик не останавливается перед началом нового цикла. Значение 200 означает, что сборщик, перед тем как начать новый цикл, ждет повышения использования общей памяти в два раза.
Множитель шагов сборщика мусора контролирует относительную скорость сборщика по отношению к скорости выделения памяти. Большие значения делают сборщик более агрессивным, но также увеличивают размер каждого шага. Вы не должны использовать значения меньше 100, т.к. они сделают сборщик настолько медленным, что он никогда не завершит цикл. По умолчанию, используется значение 200, которое означает, что сборщик выполняется в два раза быстрее скорости выделения памяти.
Если вы установите множитель шагов очень большым (больше чем 10% от максимального числа байт, которые может использовать программа), сборщик поведет себя как останавливающий мир. Если вы установите паузу 200, сборщик будет вести себя как в старых версиях Lua, производя полную очистку каждый раз, когда Lua удваивает использование памяти.
Вы можете изменять эти числа, вызывая lua_gc в C или collectgarbage в Lua. Вы также можете использовать эти функции для прямого контроля сборщика (т.е., его остановки и перезапуска).
2.5.1 – Метаметоды сборки мусора
Вы можете установить метаметоды сборки мусора для таблиц и, используя C API, для полных пользовательских данных (см. §2.4). Эти метаметоды также называются деструкторы (finalizers). Деструкторы позволяют координировать сборку мусора в Lua с внешним управлением ресурсами (таким как закрытие файлов, сетевый подключения, подключения к базам данных или освобождение вашей памяти).
Для объекта (таблицы или пользовательских данных) чтобы быть уничтоженным при сборке мусора, вы должны отметить его на уничтожение. Вы отмечаете объект на уничтожение, когда устанавливаете для него метатаблицу, содержащую поле » __gc «. Имейте ввиду, что если вы установите метатаблицу без поля __gc и затем создадите это поле в метатаблице, то объект не будет отмечен на уничтожение.
Когда отмеченный объект становится мусором, он не уничтожается напрямую сборщиком мусора. Вместо этого, Lua ложит его в список. После завершения сборки, Lua проходит по этому списку. Для каждого объекта в списке проверяется метаметод __gc : если это функция, Lua вызывает её с объектом в качестве единственного аргумента; если метаметод не функция, Lua просто игнорирует его.
В конце каждого цикла сборки мусора, деструкторы объектов вызываются в порядке обратном порядку их отметки на уничтожение; т.е., первым деструктор будет вызван для последнего отмеченного на уничтожение объекта. Выполнение каждого деструктора может произойти в любое время при выполнении основного кода.
Так как объект подлежащий уничтожению должен быть использован в деструкторе, этот объект (и остальные объекты доступные через него) должны быть воскрешены Lua. Обычно, это воскрешение нерезидентно, и память объекта освобождается при следующем цикле сборки мусора. Тем не менее, если деструктор сохраняет объект в каком-то глобальном месте (т.е. глобальной переменной), воскрешение постоянно. Более того, если деструктор отмечает уничтожаемый объект для уничтожения снова, его деструктор будет вызван снова в следующем цикле, где объект не доступен. В любом случае, память объекта освобождается только в цикле сборки мусора, где объект недоступен и не отмечен на уничтожение через деструктор.
Когда вы закрываете контекст (см. lua_close ), Lua вызывает деструкторы всех объектов отмеченных на уничтожение, следуя порядку обратному порядку их отметки на уничтожение. Если любой деструктор отмечает объекты для уничтожения в этой фазе, эти отметки не имеют никакого эффекта.
2.5.2 – Слабые таблицы
Слабая таблица (weak table) — это таблица, элементы которой это слабые ссылки (weak references). Слабая ссылка игнорируется сборщиком мусора. Другими словами, если на объект существуют только слабые ссылки, то объект будет уничтожен сборщиком мусора.
Слабая таблица может иметь слабые ключи, слабые значения или и то и другое. Таблица со слабыми значениями позволяет уничтожать её значения, но препятствует уничтожению её ключей. Таблица со слабыми значениями и ключами позволяет уничтожать и ключи и значения. В любом случае, если ключ или значение уничтожены, эта пара удаляется из таблицы. Слабость таблицы контролируется полем __mode в её метатаблице. Если поле __mode это строка содержащая символ ‘ k ‘, в таблице слабые ключи. Если поле __mode содержит ‘ v ‘, в таблице слабые значения.
Таблица со слабыми ключами и сильными значениями называется эфемерной таблицей (ephemeron table). В эфемерной таблице, значение достижимо только если его ключ достижим. В частности, если ссылка на ключ приходит через его значение, пара удаляется.
Любое изменение слабости таблицы будет иметь эффект только в следующем цикле сборки мусора. В частности, если вы сменили слабый на сильный режим, Lua может продолжить сбор некоторых элементов из этой таблицы, пока изменения не будут иметь эффект.
Только объекты, имеющие явную конструкцию, удаляются из слабых таблиц. Значения, такие как числа и легкие C функции, не являются субъектами для сборки мусора, и следовательно не удаляются из слабых таблиц (пока их ассоциированные значения не удалены). Хотя строки субъекты для сборки мусора, они не имеют явную конструкцию, и следовательно не удаляются из слабых таблиц.
Воскрешенные объекты (т.е., объекты подлежащие уничтожению и объекты достпупные через них) имеют специальное поведение в слабых таблицах. Они удаляются из слабых значений перед запуском их деструкторов, но удаляются из слабых ключей только в следующем цикле сборки, после запуска их деструкторов, когда эти объекты действительно освобождены. Это поведение позволяет деструктору получить доступ к свойствам, ассоциированным с объектом через слабые таблицы.
Если слабая таблица среди воскрешенных объектов в цикле сборки, она не может быть правильно очищена до следующего цикла сборки.
2.6 – Сопрограммы
Lua поддерживает сопрограммы, так называемую совместную многопоточность. Сопрограмма в Lua представляет независимый поток выполнения. В отличе от потоков в многопоточных системах, сопрограммма прерывает свое исполнение только явным вызовом функции yield (уступить).
Сопрограмма создается функцией coroutine.create . Единственный аргумент функции это главная функция сопрограммы. Функция create только создает сопрограмму и возвращает её описатель (объект типа thread — поток); она не запускает сопрограмму.
Сопрограмма запускается вызовом coroutine.resume . При первом вызове coroutine.resume , в качестве первого аргумента передается поток, возвращенный функцией coroutine.create , сопрограмма начинает свое исполнение с вызова своей главной функции. Дополнительные аргументы, переданные в coroutine.resume , передаются как аргументы этой функции. После запуска сопрограммы, она выполняется пока не будет завершена или не уступит (yield).
Сопрограмма может завершить свое исполнение двумя путями: нормально, когда её главная функция вернет управление (явно или не явно, после последней инструкции); и ненормально, если произойдет незащищенная ошибка. В случае нормального завершения, coroutine.resume вернет true и значения, возвращенные главной фунцией сопрограммы. В случае ошибок, coroutine.resume вернет false и сообщение об ошибке.
Сопрограмма уступает, вызывая coroutine.yield . Когда сопрограмма уступает, соответсвующая coroutine.resume немедленно возвращает управление, даже если уступка случилась внутри вложенной функции (т.е., не в главной функции, а в функции прямо или косвенно вызванной из главной функции). В случае уступки, coroutine.resume также возвращает true и значения, переданные в coroutine.yield . В следующий раз, возобновление этой же сопрограммы продолжает её выполнение с точки, где она уступила вызовом coroutine.yield , возвращающим дополнительные аргументы, переданные в coroutine.resume .
Как и coroutine.create , функция coroutine.wrap создает сопрограмму, но вместо сопрограммы возвращает функцию, вызов которой возобновляет сопрограмму. Аргументы, переданные этой функции, идут как дополнительные аргументы в coroutine.resume . coroutine.wrap возвращает все значения полученные от coroutine.resume , кроме первого (логический код ошибки). В отличие от coroutine.resume , coroutine.wrap не перехватывает ошибки; все ошибки передаются вызывающей стороне.
Для примера работы сопрограммы, рассмотрите следующий код:
Запустив его, вы получите следующий результат:
Вы также можете создавать и манипулировать сопрограммами через C API: см. функции lua_newthread , lua_resume и lua_yield .
3 – Язык
Этот раздел описывает лексику, синтаксис и семантику Lua. Другими словами, этот раздел описывает какие лексемы (tokens) правильны, как они могут быть скомбинированы, и что их комбинации означают.
Языковые конструкции будут объясняться используя обычную расширенную БНФ нотацию, в которой <a> означает 0 или больше a, и [a] означает опциональную a. Нетерминалы показаны как non-terminal, ключевые слова показаны как kword, и другие терминальные символы показаны как ‘=’. Полный синтасис Lua описан в §9 в конце руководства.
3.1 – Лексические соглашения
Lua — это язык свободной формы. Он игнорирует пробелы (включая переходы на новую строку) и комментарии между лексическими элементами, кроме разделителей между именами и ключевыми словами.
Имена (также называемые идентификаторами) в Lua могут быть любой строкой из букв, цифр и подчеркиваний, не начинающейся с цифры. Идентификаторы используются для именования значений, полей таблиц и меток (labels).
Следующие ключевые слова зарезервированы и не могут использоваться как имена:
Язык Lua чувствителен к регистру символов: and — зарезервированное слово, но And и AND — два разных, допустимых имени. Как соглашение, программы должны избегать создания имен, которые начинаются с подчеркивания и следующими за ним одной или несколькими прописными буквами (например, _VERSION ).
Следующие строки разделяют другие лексемы:
Литеральные строки могут быть ограничены сочетающимися одинарными или двойными кавычками, и могут содержать С-подобные управляющие последовательности: ‘ \a ‘ (bell), ‘ \b ‘ (backspace), ‘ \f ‘ (form feed), ‘ \n ‘ (newline), ‘ \r ‘ (carriage return), ‘ \t ‘ (horizontal tab), ‘ \v ‘ (vertical tab), ‘ \\ ‘ (backslash), ‘ \» ‘ (двойная кавычка) и ‘ \’ ‘ (апостроф [одинарная кавычка]). Обратный слеш, сопровождаемый реальным переходом на новую строку (newline), формирует переход строки (newline) в строке (string). Управляющая последовательность ‘ \z ‘ пропускает следующий за ней диапазон пробелов, включая переходы строки; это особенно полезно, чтобы разбить и отступить длинную литеральную строку на несколько линий без добавления переводов строки и пробелов в содержимое строки.
Строки в Lua могут содержать любое 8-битное значение, влючая встроенные нули, которые могут быть записаны как ‘ \0 ‘. Более того, возможно описать любой байт в литеральной строке его числовым значением. Это может быть сделано с помощью управляющей последовательности \xXX , где XX — это пара шестнадцатиричных цифр, или с помощью \ddd , где ddd — последовательность до трех десятичных цифр. (Обратите внимание, что если десятичная управляющая последовательность сопровождается цифрой, то она должна содержать ровно три цифры.)
Unicode-символ в кодировке UTF-8 может быть вставлен в литеральную строку с помощью последовательности \u<XXX> (обратите внимание на обязательные фигурные скобки), где XXX — это одна или больше шестнадцатиричных цифр описывающих код символа.
Литеральные строки также могут быть определены используя длинные скобки. Мы определяем открывающую длинную скобку уровня n, как открывающую квадратную скобку, следующие за ней n знаков = и ещё одну открывающую квадратную скобку. Так, открывающая длинная скобка уровня 0 запишется так: [[ , для уровня 1 — [=[ , и так далее. Закрывающая длинная скобка определяется аналогично; например, закрывающая длинная скобка уровня 4 запишется так: ]====] . Длинный литерал начинается с открывающей длинной скобки любого уровня и завершается на первой закрывающей длинной скобке того же уровня. Это позволяет содержать любой текст, кроме закрывающей скобки того же уровня. Литералы в такой скобочной форме могут занимать несколько линий (строк), управляющие последовательности в таких строках не работают, длинные скобки других уровней игнорируются. Любой вид последовательности завершения строки (\r, \n, \r\n или \n\r) конвертируется в простой перевод строки \n.
Любой байт в литеральной строке не подвержен влиянию правил своего представления. Тем не менее, Lua открывает файлы для парсинга в текстовом режиме, и функции системы могут иметь проблемы с некоторыми управляющими символами. Поэтому, для безопасного представления не текстовых данных в строке, следует использовать управляющие последовательности.
Для удобства, когда открывается длинная скобка с непосредственным переводом строки за ней, перевод строки не включается в результирующую строку. Например, в системе использующей ASCII (в которой ‘ a ‘ кодируется как 97, newline кодируется как 10 и ‘ 1 ‘ кодируется как 49), пять литеральных строк ниже кодируют одинаковые строки:
Числовая константа (или цифра) может быть записана с опциональной дробной частью и опциональной десятичной экспонентой, обозначенной буквой ‘ e ‘ или ‘ E ‘. Lua также поддерживает шестнадцатиричные константы, которые начинаются с 0x или 0X . Шестнадцатиричные константы также допускают использование дробной части и бинарной экспоненты, обозначеной буквой ‘ p ‘ или ‘ P ‘. Цифровая константа с разделительной точкой или экспонентой означает вещественное число; иначе она означает целое. Примеры допустимых целых чисел:
Примеры допустимых вещественных чисел:
Комментарии начинаются с двойного тире ( — ) в любом месте за пределами литеральной строки. Если текст, непосредственно следующий за — , не открывающая длинная скобка, то это короткий комментарий, который продолжается до конца строки. Иначе, это длинный комментарий, который продолжается до соответствующей закрывающей длинной скобки. Длинные комментарии часто используются для временного отключения кода.
3.2 – Переменные
Переменные — это место где хранятся значения. Существует три вида переменных: глобальные переменные, локальные переменные и поля таблиц.
Одно имя может означать глобальную или локальную переменную (или формальный параметр функции, который является частным случаем локальной переменной):
Name означает идентификаторы, как описано в §3.1.
Любое имя переменной предполагается глобальным, пока явно не определено локальным (см. §3.3.7). Локальные переменные лексически ограниченные: локальные переменные свободно доступны функциям, определенным внутри их области видимости (см. §3.5).
Перед первым присваиванием переменной, её значение равно nil.
Квадратные скобки используются для индексирования в таблице:
Значение доступа к полям таблицы может быть изменено через метатаблицы. Доступ к индексированной переменной t[i] эквивалентно вызову gettable_event(t,i) . (См. §2.4 для полного описания функции gettable_event . Эта функция не определена и не используется в Lua. Мы используем её только для пояснения.)
Синтаксис var.Name — это лишь семантическое украшение для var[«Name»] :
Доступ к глобальной переменной x эквивалентен _ENV.x . в силу того, что блоки компилируются, _ENV никогда не является глобальным именем (см. §2.2).
3.3 – Выражения
Lua поддерживает почти стандартный набор выражений, подобный наборам в Pascal или C. Этот набор включает в себя присваивания, управляющие структуры, вызовы функций и определения переменных.
3.3.1 – Блоки
Блок — это список выражений, которые выполняются последовательно:
Lua допускает пустые выражения, что позволяет вам разделять выражения с помощью точки с запятой (;), начинать блок с точки с запятой или писать две точки с запятой подряд:
Вызовы функций и присваивания могут начинаться с открывающейся скобки. Эта возможность ведет к неоднозначности в грамматике Lua. Рассмотрим следующий фрагмент:
Грамматика может рассматривать это двумя путями:
Текущий парсер всегда рассматривает такие констркции первым путем, интерпретируя открывающуюся скобку, как начало аргументов для вызова. Для избежания этой неоднозначности, лучше всегда ставить точку с запятой (;) перед выражениями начинающимися со скобок:
Блок может быть явно выделен для создания единственного выражения:
Явные блоки полезны для контроля за областью видимости переменных. Явные блоки также иногда используются для добавления выражения return в середину другого блока (см. §3.3.4).
3.3.2 – Куски
Единица компиляции в Lua называется куском (chunk). Синтаксически, кусок это простой блок:
Lua обрабатывает кусок, как тело анонимной функции с переменным числом аргументов (см. §3.4.11). Как таковой, кусок может определять локальные переменные, получать аргументы и возвращать значения. Более того, такая анонимная функция компилируется в области видимости внешней локальной переменной _ENV (см. §2.2). Результирующая функция всегда имеет _ENV , как только свою upvalue, даже если не использует эту переменную.
Кусок может храниться в файле или в строке внутри хостовой программы. Для запуска куска, Lua сперва загружает его (load), прекомпилируя код куска в инструкции виртуальной машины, и затем запускает скомпилированный код.
Кусок также может быть прекомпилирован в бинарную форму; смотри программу luac и функцию string.dump . Программы в исходном коде и в скомпилированной форме взаимозаменяемы; Lua автоматически определяет тип файла и действует соответственно (см. load ).
3.3.3 – Присваивание
Lua позволяет множественные присваивания. Синтаксис присваивания определяет список переменных с левой строны и список выражений с правой стороны. Элементы в обоих списках разделяются запятыми:
Выражения обсуждаются в §3.4.
Перед присваиванием, список значений корректируется до длины списка переменных. Если значений больше чем нужно, лишние значения отбрасываются. Если значений меньше чем нужно, список расширяется добавлением необходимого числа значений nil. Если список выражений заканчивается вызовом функции, все значения, возвращенные этой функцией, попадают в список значений перед присваиванием. (кроме вызова заключенного в скобки; см. §3.4).
Оператор присваивания сперва вычисляет все свои выражения и лишь затем выполняет присваивание. Таким образом код
устанавливает a[3] равным 20, не изменяя a[4] , т.к. i в a[i] вычисляется (= 3) до присваивания ему 4. Аналогично, строка
меняет местами значения x и y , и
циклически переставляет значения x , y и z .
Значение присваиваний глобальным переменным и полям таблиц может быть изменено через метатаблицы. Присваивание индексированной переменной t[i] = val эквивалентно settable_event(t,i,val) . (См. §2.4 для полного описания функции settable_event . Эта функция не определена и не используется в Lua. Мы используем её только для пояснения.)
Присванивание глобальной переменной x = val эквивалентно присваиванию _ENV.x = val (см. §2.2).
3.3.4 – Управляющие конструкции
Управляющие конструкции if, while и repeat имеют обычное значение и знакомый синтаксис:
Lua также имеет две формы оператора for (см. §3.3.5).
Условное выражение в управляющей конструкции может возвращать любое значение. False и nil рассматриваются как false. Все значения, отличные от nil и false, рассматриваются как true (в частности, число 0 и пустая строка это тоже true).
В цикле repeat–until, внутренний блок заканчивается после всего условия, а не на ключевом слове until. Так, условие может ссылаться на локальные переменные объявленные внутри цикла.
Оператор goto передает управление на метку. По синтаксическим причинам, метки в Lua тоже считаются выражениями:
Метка видна в блоке где объявлена, за исключением вложенных блоков, где определена метка с таким же именем и вложенных функций. Goto может переходить на любую видимую метку, так далеко, пока не войдет в область видимости локальной переменной.
Метки и пустые выражения называются пустыми выражениями, так как они не производят дейтсвий.
Выражение break завершает исполнение цикла while, repeat или for, пропуская оставшиеся команды цикла:
break завершает самый внутренний цикл.
Выражение return используется для возврата значений из функции или куска (который является анонимной функцией). Функции могут возвращать несколько значений, поэтому синтаксис для выражения return следующий:
Выражение return может быть написано только, как последнее в блоке. Если действительно необходимо иметь return в середине блока, тогда можно использовать явный внутренний блок, как идиома do return end , теперь return это последнее выражение в его (внутреннем) блоке.
3.3.5 – Конструкция For
Конструкция for имеет две формы: цифровую и общую.
Цифровой цикл for повторяет блок кода, пока управляющая переменная изменяется в арифметической прогрессии. Он имеет следующий синтаксис:
block повторяется для name начиная с первого значения exp, пока не достигнет значения втрого exp, шагами равными третьему exp. Более точно, выражение for
эквивалентно следующему коду:
- Все три управляющие выражения вычисляются только один раз, перед тем как начнется цикл. Их результаты должны быть числами.
- var , limit и step — невидимые переменные. Имена показаны здесь только для пояснения.
- Если третье выражение (шаг) отсутствует, тогда используется шаг 1.
- Для выхода из цикла for вы можете использовать break и goto.
- Переменная цикла v является локальной для тела цикла. Если необходимо использовать её значение после цикла, сохраните его в другой переменной перед выходом из цикла.
Общий for работает через функции, называемые итераторами. На каждой итерации, функция-итератор вызывается чтобы выдать новое значение, остановка происходит, когда новое значение равно nil. Общий цикл for имеет следующий синтаксис:
Выражение for
эквивалентно следующему коду:
- explist вычисляется только один раз. Его результат это функция итератор, состояние и начальное значение для первой итерируемой переменной.
- f , s и var — невидимые переменные. Имена показаны здесь только для пояснения.
- Для выхода из цикла for вы можете использовать break.
- Переменная цикла var_i является локальной для тела цикла. Если необходимо использовать её значение после цикла, сохраните его в другой переменной перед выходом из цикла.
3.3.6 – Вызовы функций как выражения
Чтобы позволить побочные эффекты, вызовы функций могут запускаться как выражения:
В этом случае все возвращенные значения отбрасываются. Вызовы функций рассматриваются в §3.4.10.
3.3.7 – Локальные определения
Локальные переменные могут быть объявлены в любой части блока. Определение может содержать начальное присваивание (инициализацию):
Если есть начальное присваивание, то оно имеет семантику схожую с множественным присваиванием (см. §3.3.3). Иначе, все переменные инициализируются значением nil.
Кусок также является блоком (см. §3.3.2), и следовательно локальные переменные могут быть объявлены в куске вне всякого явного блока.
Правила видимости локальных переменных рассматриваются в §3.5.
3.4 – Выражения
Базовые выражения в Lua следующие:
Числа и литеральные строки рассматриваются в §3.1; переменные рассматриваются в §3.2; определения функций рассматриваются в §3.4.11; вызовы функций рассматриваются в §3.4.10; конструкторы таблиц описаны в §3.4.9. Выражения с переменными аргументами, обозначенными тремя точками (‘ . ‘), могут быть использованы только внутри функции с переменным числом аргументов; они описываются в §3.4.11.
Бинарные операторы, включая арифметические (см. §3.4.1), битовые операторы (см. §3.4.2), операторы сравнения (см. §3.4.4), логические операторы (см. §3.4.5), и оператор конкатенации (см. §3.4.6). Одноместные операторы, включая одноместный минус (см. §3.4.1), одноместный битовый НЕ (см. §3.4.2), одноместный логический not (см. §3.4.5), и одноместный оператор длины (см. §3.4.7).
Функции и выражения с переменным числом аргументов могут возвращать несколько значений. Если вызов функции используется как выражение (см. §3.3.6), он возвращает список скорректированный до нуля элементов, т.е. отброшены все возвращенные значения. Если выражение используется последним элементом в списке выражений (или оно только одно), то корректировка не производится (если выражение не заключено в скобки). Во всех остальных случаях Lua корректирует список результатов до одного элемента, отбрасывая все значения кроме первого, или добавляя один nil, если значений нет.
Здесь несколько примеров:
Любое выражение, заключенное в скобки, всегда возвращает только одно значение. Т.е., (f(x,y,z)) всегда одно значение, даже если f возвращает несколько значений. (Значение (f(x,y,z)) это первое из значений возвращенных f или nil, если f не вернет ни одного значения.)
3.4.1 – Арифметические операторы
- + : сложение
- — : вычитание
- * : умножение
- / : деление
- // : целочисленное деление
- % : модуль
- ^ : возведение в степень
- — : одноместный минус
За исключением возведения в степень и деления, арифметические операторы работают следующим образом: Если оба операнда целые, операция производится над целыми и результатом является целое. Иначе, если оба операнда числа или строки, которые могут быть сконвертированы в числа (см. §3.4.3), они конвертируются в числа с плавающей запятой (float), операции производятся согласно обычным правилам арифметики вещественных чисел (обычно стандарт IEEE 754), и результатом будет число с плавающей запятой.
Возведение в степень и деление ( / ) всегда конвертирует операнды в вещественные числа и результат вещественное число. Возведение в степень использует функцию pow из ISO C, она работает и для не целых экспонент тоже.
Целочисленное деление ( // ) — это деление, которое округляет частное по отношению к минус беспонечности, т.е. нижнее от деления операндов.
Модуль определено как остаток от деления, которое округляет частное по отношению к минус беспонечности (целочисленное деление).
В случае переполнения целочисленной арифметики, все операции циклически переходят, в соответствии с обычными правилами арифметики двоичного дополнения. (Другими словами, они возвращают уникальное представимое целое, которое равно по модулю 2 64 математическому результату.)
3.4.2 – Битовые операторы
- & : битовое И
- | : битовое ИЛИ
Все битовые операторы преобразуют свои операнды в целые (см. §3.4.3), оперируют всеми битами этих целых и результат тоже целое.
Правый и левый сдвиги заполняют свободные биты нулями. Отрицательное смещение сдвигает в противоположном направлении; смещения с абсолютными значениями большими (или равными), чем число бит в целом, дают результат ноль (все биты сдвинуты наружу).
3.4.3 – Приведения и преобразования
Lua производит некоторые автоматические преобразования между типами и представлениями во время выполнения. Битовые операторы всегда конвертируют вещественные операнды в целые. Возведение в степень и деление всегда конвертируют целые операнды в вещественные. Все остальные арифметические операции, примененные к смешанным числам (целые и вещественные), преобразуют целые цисла в вещественные; это называется обычное правило. C API также конвертирует целые в вещественные и вещественные в целые, при необходимости. Более того, конкатенация строк принимает числа, как аргументы между строками.
Lua также конвертирует строки в числа, когда ожидается число.
В преобразовании целого в вещественное, если целое значение имеет точное представление как вещественное, это представление и будет результатом. Иначе, преобразование получает ближайшее большее или ближайшее меньшее представимое значение. Этот тип преобразования всегда успешен.
Преобразование вещественного в целое проверяет, что вещественное имеет точное представление как целое (т.е., вещественное имеет целое значение и в диапазоне представления целых). Если это так, то это представление будет результатом. Иначе, преобразование терпит неудачу.
Преобразование строк в числа идет следующим образом: Первое, строка преобразуется в целое или вещественное, следуя синтаксису и правилам лексера Lua. (Строка может содержать начальные и конечные пробелы и знак.) Затем, получившееся число (целое или вещественное) преобразуется в тип (целое или вещественное), требуемый в данном контексте (т.е., требуемый операцией которая конвертирует принудительно).
Преобразование чисел в строки использует не определенный читабельный формат. Для полного контроля над тем, как числа конвертируются в строки, используйте функцию format из строковой библиотеки (см. string.format ).
3.4.4 – Операторы сравнения
- == : равенство
Эти операторы всегда возвращают false или true.
Равенство ( == ) сперва сравнивает типы операндов. Если типы разные, то результат false. Иначе, сравниваются значения операндов. Строки сравниваются очевидным способом. Числа равны, если они обозначают одинаковые математические значения.
Таблицы, пользовательские данные и потоки сравниваются по ссылке: два объекта считаются равными только, если это один и тот же объект. Всегда, когда вы создаете новый объект (таблицу, пользовательские данные или поток), этот новый объект отличен от любого существующего объекта. Замыкания (closure) с одинаковыми ссылками всегда равны. Замыкания с любыми обнаруживаемыми различиями (разное поведение, разное определение) всегда различны.
Используя метаметод «eq», вы можете изменить способ, которым Lua сравнивает таблицы и пользовательские данные (см. §2.4).
Проверка на равенство не конвертирует строки в числа и наоборот. Так, «0»==0 вернет false, t[0] и t[«0»] означают разные элементы в таблице.
= это явное отрицание равенства ( == ).
Операторы упорядочения работают следующим образом. Если оба аргумента числа, то они сравниваются согласно их математическим значениям. (независимо от их подтипов). Иначе, если оба аргумента строки, то их значения сравниваются согласно текущей локали. Иначе, Lua пытается вызвать метаметоды «lt» или «le» (см. §2.4). Сравнение a > b транслируется в b < a и a >= b транслируется в b <= a .
Следуя стандарту IEEE 754, NaN рассматривается как никакой: не меньший, не больший, не равный ни одному значению (включая себя самого).
3.4.5 – Логические операторы
В Lua существуют следующие логические операторы: and (И), or (ИЛИ) и not (НЕ). Как и управляющие структуры (см. §3.3.4), все логические операторы считают false и nil как false, а все остальное как true.
Оператор отрицания not всегда возвращает false или true. Оператор конъюнкции and возвращает свой первый аргумент, если его значение false или nil; иначе, and возвращает второй аргумент. Оператор дизъюнкции or возвращает свой первый аргумент, если его значение отлично от nil и false; иначе, or возвращает второй аргумент. Оба and и or используют ленивое вычисление; т.е., второй операнд вычисляется только если необходимо. Несколько примеров:
(В этом руководстве, —> означает результат предыдущего выражения.)
3.4.6 – Конкатенация
Конкатенация строк в Lua обозначается двумя точками (‘ .. ‘). Если оба операнда строки или числа, они конвертируются в строки согласно правилам, описанным в §3.4.3. Иначе, вызывается метаметод __concat (см. §2.4).
3.4.7 – Оператор длины
Оператор длины обозначается одноместным префиксом # . Длина строки это число байт в ней (т.е., обычное значение длины строки, когда каждый символ размером 1 байт).
Программа может модифицировать поведение оператора длины для любого значения, кроме строк, используя метаметод __len (см. §2.4).
Пока метаметод __len не определен, длина таблицы t определена только, если таблица t последовательность, т.е., набор её положительных числовых ключей равен для какого-то положительного целого n. В этом случае, n это длина. Имейте ввиду, таблица как
это не последовательность, т.к. она имеет ключ 4 , но не имеет ключ 3 . (Так, там нет n, который в множестве равен набору положительных числовых ключей этой таблицы.) Тем не менее, эти не числовые ключи не создают помех с независимой последовательностью в таблице.
3.4.8 – Приоритет
Приоритет операторов в Lua представлен далее, с меньшего к большему приоритету:
Как обычно, чтобы изменить приоритет в выражении, вы можете использовать скобки. Операторы конкатенации (‘ .. ‘) и возведения в степень (‘ ^ ‘) имеют правую ассоциативность. Все остальные бинарные операторы имеют левую ассоциативность.
3.4.9 – Конструкторы таблиц
Конструкторы таблиц — это выражения, которые создают таблицы. При каждом запуске конструктора создается новая таблица. Конструктор может использоваться для создания пустой таблицы или для создания таблицы с инициализацией некоторых её полей. Общий синтаксис конструкторов следующий:
Каждое поле вида [exp1] = exp2 добавляет новый элемент таблицы с ключем exp1 и значением exp2 . Поле вида name = exp эквивалентно записи [«name»] = exp . Поля вида exp эквивалентны [i] = exp , где i последовательные целые, начинающиеся с 1; поля в других форматах не влияют на этот счет. Например,
Порядок присваиваний в конструкторе не определен. (Этот порядок важен только для повторяющихся ключей.)
Если последнее поле в списке имеет вид exp и выражение это вызов функции или обозначение множества аргументов (. ), то все значения, возвращенные этим выражением, последовательно включаются в список (см. §3.4.10).
Список полей может иметь опциональный конечный разделитель, для удобства машинно-сгенерированного кода.
3.4.10 – Вызовы функций
Вызов функции в Lua имеет следующий синтаксис:
При вызове функции, сперва вычисляются prefixexp и args. Если значение prefixexp имеет тип function, то вызывается эта функция с данными аргументами. Иначе, для объекта prefixexp вызывается метаметод «call», в качестве первого параметра передается значение prefixexp, затем остальные аргументы вызова. (см. §2.4).
может быть использована для вызова «методов». Вызов v:name(args) это синтаксическое украшение для v.name(v,args) , за исключением того, что v вычисляется только один раз.
Аргументы имеют следующий синтаксис:
Все выражения в аргументах вычисляются перед вызовом.
Вызов вида f<fields> это синтаксическое украшение для f(<fields>) ; т.е. в качестве аргумента передается одна новая таблица.
Вызов вида f’string‘ (или f»string» или f[[string]] ) это синтаксическое украшение для f(‘string‘) ; т.е. в качестве аргумента передается одна литеральная строка.
Вызов вида return functioncall называется хвостовым вызовом (tail call). Lua реализует соответствующие хвостовые вызовы (proper tail call) (или соответствующую хвостовую рекурсию): в хвостовом вызове, вызванная функция повторно использует элементы стека вызывающей функции. Следовательно, не существует лимита на число вложенных хвостовых вызовов, выполняемых программой. Тем не менее, хвостовой вызов затирает любую отладочную информацию о вызывающей функции. Имейте ввиду, что хвостовой вызов происходит только с конкретным синтаксисом, где return имеет только один вызов функции в качестве аргумента; при таком синтаксисе вызывающая функция возвращает тоже, что и вызванная функция. Так, в следующих примерах хвостовой вызов не происходит:
3.4.11 – Определения функций
Синтаксис для определения функции:
Следующее синтаксическое украшение упрощает определение функций:
(Это имеет значение, когда тело функции содержит ссылки на f .)
Определение функции — это исполняемое выражение, значение которого имеет тип function. Когда Lua предкомпилирует кусок, все тела функций в нем прекомпилируются тоже. Затем, всякий раз, когда Lua запускает определение функции, функция инстанцируется (или замыкается). Этот экземпляр функции (или замыкание [closure]) будет финальным значением выражения.
Параметры действуют как локальные переменные, инициализированные значениями аргументов:
Когда функция вызывается, список аргументов корректируется до длины списка параметров, пока функция это не функция с переменным числом аргументов (vararg function); переменные аргументы указываются тремя точками (‘ . ‘) в конце списка параметров. Функция с переменным числом аргументов не корректирует свой список аргументов; взамен, она коллекционирует все дополнительные аргументы и передает их в функцию через vararg-выражение, которое также обозначается тремя точками. Значение этого выражения это список всех фактических дополнительных аргументов, подобно функции с множественными возвращаемыми значениями. Если vararg-выражение используется внутри другого выражения или в середине списка выражений, то его результат корректируется до одного элемента. Если vararg-выражение используется как последний элемент в списке выражений, то корректировка не производится (если последнее выражение не заключено в скобки).
Например, рассмотрим следующие определения:
Мы получим следующее соответствие аргументов параметрам и vararg-выражению:
Результаты возвращаются выражением return (см. §3.3.4). Если управление достигает конца функции без выражения return, то функция не возвращает результатов.
Существует системозависимый предел числа значений, которые может вернуть функция. Этот предел гарантированно больше 1000.
Синтаксис двоеточия используется для определения методов, т.е. функций, которые имеют явный дополнительный параметр self . Таким образом, выражение
это синтаксическое украшение для
3.5 – Правила видимости
Lua — язык с лексическими областями видимости. Область видимости локальной переменной начинается с первого выражения после её определения и продолжается до последнего не пустого выражения внутреннего блока, включающего определение. Рассмотрим следующий пример:
Учтите, что в определении вида local x = x , новый x пока вне зоны видимости и, таким образом, второй x ссылается на внешнюю переменную.
Согласно правилам видимости, локальные переменные могут быть свободно доступны функциям, определенным в их зоне видимости. Локальная переменная, которая используется внутренней функцией, внутри данной функции называется upvalue или внешняя локальная переменная.
Обратите внимание, каждое выполнение выражения local определяет новую локальную переменную. Рассмотрим следующий пример:
Цикл создает 10 замыканий (т.е., 10 экземпляров анонимной функции). Каждое из этих замыканий использует разные переменные y и общую для всех x .
4 – Программный интерфейс (API)
Этот раздел описывает C API для Lua, т.е. набор C функций, доступный хостовой программе для взаимодействия с Lua. Все API функции и связанные типы и константы определены в заголовочном файле lua.h .
Каждый раз, когда мы используем термин «функция», любая возможность в API может быть реализована как макрос. Везде, где не оговорено обратное, все такие макросы используют каждый свой аргумент только один раз (исключая первый аргумент, который всегда является контекстом Lua) и не генерируют ни каких скрытых побочных эффектов.
Как и в большинстве C библиотек, функции Lua API не проверяют свои аргументы на корректность и согласованность. Тем не менее, вы можете изменить это поведение, скомпилировав Lua с включенным определением LUA_USE_APICHECK .
4.1 – Стек
Чтобы передавать значения из и в С Lua использует виртуальный стек. Каждый элемент этого стека представляет Lua значение (nil, number, string и др.).
Кажды раз, когда Lua вызывает C, вызванная функция получает новый стек, который независим от предыдущих стеков и стеков активных в данный момент C функций. Этот стек изначально содержит все аргументы для C функции, туда же C функция ложит свои результаты, чтобы вернуть вызывающей стороне (см. lua_CFunction ).
Для удобства, большинство операций запроса в API не следуют строгой стековой дисциплине. Напротив, они могут ссылаться на любой элемент в стеке, используя его индекс: Положительный индекс представляет абсолютную позицию в стеке (начиная с 1); отрицательный индекс представляет смещение относительно вершины стека. Точнее, если стек имеет n элементов, индекс 1 представляет первый элемент (т.е., элемент, который был положен на стек первым) и индекс n представляет последний элемент; индекс -1 также представляет последний элемент (т.е., элемент на вершине стека) и индекс -n представляет первый элемент.
4.2 – Размер стека
Когда вы работаете с Lua API, вы ответственны за гарантирование согласованности. В частности, вы ответственны за контроль над переполнением стека. Вы можете использовать функцию lua_checkstack чтобы проверять, что стек имеет достаточно места для новых элементов.
Каждый раз, когда Lua вызывает C, он убеждается, что стек имеет место для как минимум LUA_MINSTACK дополнительных слотов. LUA_MINSTACK определен равным 20, так обычно вы не должны беспокоиться о размере стека, пока ваш код не содержит циклы, помещающие элементы в стек.
Когда вы вызываете Lua функцию без определенного числа результатов (см. lua_call ), Lua гарантирует, что стек имеет достаточно места для помещения всех результатов, но не гарантирует любое дополнительное пространство. Так, перед тем как положить что-либо на стек после вызова функции, вы должны использовать lua_checkstack .
4.3 – Правильные и допустимые индексы
Любая API функция, получающая стековые индексы, работает только с правильными индексами или допустимыми индексами.
Правильный индекс — это индекс, который ссылается на позицию, содержащую модифицируемое Lua значение. Допустимый диапазон включает стековые индексы между 1 и вершиной стека ( 1 ≤ abs(index) ≤ top ) плюс псевдоиндексы, которые представляют некоторые позиции, доступные для C кода, но не находящиеся в стеке. Псевдоиндексы используются для доступа к реестру (см. §4.5) и к внешним локальным переменным (upvalue) C функции (см. §4.4).
Функции, не нуждающиеся в специфической изменяемой позиции, а нуждающиеся только в значении (т.е., функции запросов), могут быть вызваны с допустимыми индексами. Допустимым индексом может быть любой правильный индекс, но это также может быть любой положительный индекс после вершины стека внутри пространства, выделенного для стека, т.е., индексы выше размера стека. (Учтите, что 0 это всегда недопустимый индекс.) Если не оговорено иное, API функции работают с допустимыми индексами.
Допустимые индексы служат для избежания дополнительных тестов вершины стека при запросах. Например, C функция может запросить свой третий аргумент без проверки его существования, т.е., без проверки того, что индекс 3 является правильным.
Для функций, которые могут быть вызваны с допустимыми индексами, любой не правильный индекс, трактуется как индекс к значению виртуального типа LUA_TNONE , которое ведет себя как значение nil.
4.4 – C замыкания
Когда C функция создана, можно ассоциировать с ней несколько значений, таким образом создав C замыкание (closure) (см. lua_pushcclosure ); эти значения называются upvalue и доступны функции во время вызова.
При каждом вызове C функции, её upvalue располагаются по специфическим псевдоиндексам. Псевдоиндексы создаются макросом lua_upvalueindex . Первое upvalue, ассоциированное с функцией, располагается по индексу lua_upvalueindex(1) , и так далее. Любое обращение к lua_upvalueindex(n) , где n больше количества upvalue текущей функции (но не больше 256), создает допустимый, но не правильный индекс.
4.5 – Реестр
Lua предоставляет реестр, предопределенную таблицу, которая доступна C коду для хранения любых Lua значений. Таблица рееста всегда расположена по псевдоидексу LUA_REGISTRYINDEX . Любая C библиотека может хранить данные в этой таблице, но она должна заботиться о выборе уникальных ключей, чтобы избежать коллизий с другими библиотеками. Обычно, вы должны использовать в качестве ключа строку содержащую имя библиотеки, или легкие пользовательские данные (light userdata) с адресом C объекта в вашем коде, или любой Lua объект созданный вашим кодом. Как и имена переменных, ключи, начинающиеся с подчеркивания со следующими за ним прописными буквами, зарезервированы для Lua.
Целочисленные ключи в реестре используются механизмом ссылок (см. luaL_ref ) и некоторыми предопределенными значениями. Следовательно, целочисленные ключи не должны использоваться для других целей.
- LUA_RIDX_MAINTHREAD : По этому индексу в реестре расположен главный поток контекста. (Главный поток создается при создании контекста.)
- LUA_RIDX_GLOBALS : По этому индексу в реестре расположено глобальное окружение.
4.6 – Обработка ошибок в C
Внутри, для обработки ошибок Lua использует C longjmp . (Lua будет использовать исключения, если вы скомпилируете его как C++; для подробностей ищите LUAI_THROW в исходном коде.) Когда Lua сталкивается с любой ошибкой (такой как ошибка выделения памяти, ошибки типов, синтаксические ошибки и ошибки времени выполнения), он возбуждает ошибку; т.е., делает длинный переход (long jump). Защищенное окружение использует setjmp для установки точки восстановления; любая ошибка переходит к самой последней точке восстановления.
Если ошибка случается за пределами защищенного окружения, Lua вызывает функцию паники (см. lua_atpanic ) и затем вызывает abort , завершая хостовое приложение. Ваша функция паники может избежать завершения приложения, если не вернет управление (т.е., сделает длинный переход [long jump] на вашу точку восстановления вне Lua).
Функция паники запускается как обработчик сообщений (см. §2.3); в частности, сообщение об ошибке лежит на вершине стека. Тем не менее, это не гарантирует стековое пространство. Чтобы положить что-либо на стек, функция паники должна сперва проверить доступное место (см. §4.2).
Большинство API функций могут возбуждать ошибки, например при выделении памяти. Описание для каждой функции предупреждает, что она может возбуждать ошибки.
Внутри C функции вы можете сгенерировать ошибку вызовом lua_error .
4.7 – Обработка уступок в C
Внутри, для приостановки сопрограммы Lua использует C longjmp . Следовательно, если C функция foo вызывает функцию API и эта API функция уступает (прямо или опосредованно, вызывая другую функцию, которая уступает), Lua больше не может вернуться к foo , потому что longjmp удаляет свой фрейм из C стека.
Чтобы избежать такой тип проблем, Lua возбуждает ошибку каждый раз, когда происходит уступка через вызов API, за исключением трех функций: lua_yieldk , lua_callk и lua_pcallk . Все эти функции получают функцию продолжения (как параметр k ) чтобы продолжить исполнение после уступки.
Чтобы рассмотреть продолжения установим некоторую терминологию. Мы имеем C функцию вызванную из Lua, назовем её оригинальной функцией. Эта оригинальная функция затем вызывает одну из этих трех API функций, которые мы будем называть вызываемой функцией, которая затем уступает текущий поток. (Это может случиться, когда вызываемая функция это lua_yieldk , или когда вызываемая функция любая из lua_callk или lua_pcallk и вызванная ими функция уступает.)
Допустим, выполняющийся поток уступает во время выполнения вызываемой функции. Затем поток продолжается, это в конечном счете завершит вызываемую функцию. Тем не менее, вызываемая функция не может вернуться в оригинальную, т.к. её фрейм в C стеке был уничтожен уступкой. Взамен, Lua вызывает функцию продолжения, которая передается как аргумент вызываемой функции. Как подразумевается, продолжающая функция должна продолжить выполнение задачи оригинальной функции.
Как иллюстрацию, рассмотрим следующую функцию:
Сейчас мы хотим позволить Lua коду, запущенному через lua_pcall , уступать. Сначала, перепишем нашу функцию как показано ниже:
В этом коде, новая функция k это функция продолжения (с типом lua_KFunction ), которая должна делать всю работу, которую оригинальная функция делала после вызова lua_pcall . Мы должны проинформировать Lua о том, что если Lua код, запущенный lua_pcall , будет прерван (ошибки или уступка), то необходимо вызвать k ; переписываем код, заменяя lua_pcall на lua_pcallk :
Обратите внимание на внешний явный вызов продолжения: Lua будет вызывать продолжение только при необходимости, т.е. в случае ошибок или возобновления после уступки. Если вызванная функция возвратится нормально, без уступок, lua_pcallk (и lua_callk ) также возвратятся нормально. (Конечно, в этом случае вместо вызова продолжения, вы можете выполнить эквивалентную работу прямо внутри оригинальной функции.)
Рядом с Lua состоянием, функция продолжения имеет два других параметра: конечный статус вызова и контекстное значение ( ctx ), которое изначально передается в lua_pcallk . (Lua не использует это контекстное значение; только передает его из оригинальной функции в функцию продолжения.) Для lua_pcallk , статус это тоже значение, которое будет возвращено функцией lua_pcallk , за исключением того, что после выполнения уступки это будет LUA_YIELD , (взамен LUA_OK ). Для lua_yieldk и lua_callk , когда Lua вызывает продолжение, статус всегда будет равен LUA_YIELD . (Для этих двух функций в случае ошибок Lua не вызовет продолжение, т.к. они не обрабатывают ошибки.) Аналогично, когда используется lua_callk , вы должны вызывать функцию продолжения со статусом LUA_OK . (Для lua_yieldk , нет смысла в прямом вызове функции продолжения, т.к. lua_yieldk обычно не возвращается.)
Lua обрабатывает функцию продолжения так, как будто это оригинальная функция. Функция продолжения получает тот же Lua стек из оригинальной функции, в том же состоянии, как если бы вызываемая функция вернулась. (Например, после lua_callk функция и её аргументы удалены из стека и заменены результатами вызова.) Она также будет иметь те же upvalue. Результаты, которые она вернет, будут обработаны Lua так, как будто их вернула оригинальная функция.
4.8 – Функции и типы
Здесь представлен список всех функций и типов из C API в алфавитном порядке. Каждая функция имеет индикатор вида: [-o, +p, x]
Первое поле, o , показывает сколько элементов функция снимает со стека. Второе поле, p , показывает сколько элементов функция ложит на стек. (Функции всегда ложат свои результаты после того, как снимут аргументы со стека.) Поле вида x|y означает, что функция может ложить (или снимать) x или y элементов, в зависимости от ситуации; знак вопроса ‘ ? ‘ означает, что по аргументам функции невозможно определить сколько элементов функция ложит/снимает (т.е. функция может зависеть от того, что лежит в стеке). Третье поле, x , показыает может ли функция генерировать ошибки: ‘ — ‘ означает, что функция никогда не генерирует ошибки; ‘ e ‘ означает, что функция может генерировать ошибки; ‘ v ‘ означает, что фунция предназначена для генерации ошибки.
lua_absindex
Конвертирует допустимый индекс idx в эквивалентный абсолютный индекс (который не зависит от вершины стека).
lua_Alloc
Тип функции выделения памяти, которая используется состоянием Lua. Функция выделения памяти должна предоставлять функциональность подобную функции realloc , но не точно такую же. Её аргументы ud — непрозрачный указатель, передаваемый в lua_newstate ; ptr — указатель на блок для выделения/перераспределения/освобождения; osize — оригинальный размер блока или код, определяющий под что выделяется память; nsize — новый размер блока.
Когда ptr не NULL , osize это размер блока по указателю ptr , т.е. размер полученный при выделении или перераспределении.
Когда ptr = NULL , osize кодирует тип объекта, для которого выделяется память. osize может быть равен LUA_TSTRING , LUA_TTABLE , LUA_TFUNCTION , LUA_TUSERDATA и LUA_TTHREAD , когда (и только когда) Lua создает новый объект данного типа. Когда osize какое-то другое значение, Lua выделяет память для чего-то другого.
Lua предполагает следующее поведение функции выделения памяти:
Когда nsize = 0, функция должна действовать как free и возвращать NULL .
Когда nsize != 0, функция должна действовать как realloc . Функция возвращает NULL только, если не может выполнить запрос. Lua предполагает, что функция выделения памяти не может выдать ошибку при osize >= nsize .
Здесь представлена простая реализация функции выделения памяти. Она используется во вспомогательной библиотеке функцией luaL_newstate .
Учтите, что стандартный C гарантирует, что free(NULL) не производит действий и realloc(NULL,size) эквивалентно malloc(size) . Этот код предполагает, что realloc не вызывает ошибок при уменьшении блока. (Хотя стандартный C не предполагает такого поведения, кажется, это безопасное предположение.)
lua_arith
Выполняет арифметическую или битовую операцию над двумя значениями (или одним, в случае отрицаний), находящимися на вершине стека, значение на вершине является вторым операндом, удаляет эти значения со стека и ложит результат операции. Функция следует семантике соответствующего оператора (т.е., может вызывать метаметоды).
- LUA_OPADD : сложение ( + )
- LUA_OPSUB : вычитание ( — )
- LUA_OPMUL : умножение ( * )
- LUA_OPDIV : деление ( / )
- LUA_OPIDIV : целочисленное деление ( // )
- LUA_OPMOD : модуль ( % )
- LUA_OPPOW : возведение в степень ( ^ )
- LUA_OPUNM : математическое отрицание (одноместный — )
- LUA_OPBNOT : битовое отрицание (
lua_atpanic
Устанавливает новую функцию паники и возвращает старую (см. §4.6).
lua_call
Для вызова функции вы должны использовать следующий протокол: первое, вызываемая функция должна быть помещена в стек; затем, на стек ложатся аргументы в прямом порядке; т.е., первый аргумент ложится первым. Наконец, производится вызов lua_call ; nargs — количество аргументов на стеке. Когда функция вызывается, все аргументы и функция снимаются со стека. Результаты ложатся на стек, когда функция возвращается. Количество результатов корректируется до nresults , если nresults не равно LUA_MULTRET . В этом случае, все результаты из функции ложатся на стек. Lua заботится, чтобы возвращенным значениям хватило места в стеке. Результаты функции ложатся в стек в прямом порядке (первый результат ложится первым), так что после вызова последний результат будет на вершине стека.
Любая ошибка внутри вызванной функции распространяется вверх (с longjmp ).
Следующий пример показывает, как хостовая программа может выполнить действия эквивалентные этому Lua коду:
Обратите внимание, что код выше сбалансирован: после его выполнения стек возвращается в первоначальное состояние. Это хорошая практика програмирования.
lua_callk
Эта функция аналогична lua_call , но позволяет вызываемой функции уступать (см. §4.7).
lua_CFunction
Тип для C функций.
Для правильного взаимодействия с Lua, C функция должна использовать следующий протокол, который определяет как передаются параметры и результаты: C функция получает аргументы из Lua в своём стеке в прямом порядке (первый аргумент ложится первым). Так, когда функция стартует, lua_gettop(L) возвращает количество аргументов, полученных функцией. Первый аргумент (если существует) находится по индексу 1, последний аргумент находится по индексу lua_gettop(L) . Для возврата значений в Lua, C функция просто ложит их на стек в прямом порядке (первый результат ложится первым) и возвращает число результатов. Любое другое значение в стеке ниже результатов будет сброшено Lua. Как и Lua функция, C функция, вызванная Lua, может возвращать несколько результатов.
Например, следующая функция получает переменное количество числовых аргументов и возвращает их среднее и их сумму:
lua_checkstack
Проверяет, что стек имеет место для как минимум n дополнительных слотов. Функция возвращает false, если не может выполнить запрос, потому что размер стека больше фиксированного максимума (обычно несколько тысяч элементов) или поскольку не может выделить память для дополнительных слотов. Эта функция никогда не уменьшает стек; если стек уже больше чем новый размер, он остаётся без изменений.
lua_close
Уничтожает все объекты в Lua состоянии (вызываются соответствующие метаметоды сборки мусора, если существуют) и освобождает всю динамическую память, использованную этим состоянием. На некоторых платформах, вы можете не вызывать эту функцию, т.к. все ресурсы освобождаются при завершении хостовой программы. С другой стороны, долго работающие программы, которые создают множество состояний, такие как демоны или веб-серверы, вероятно будут нуждаться в закрытии состояний, когда они станут ненужными.
lua_compare
Сравнивает два Lua значения. Возвращает 1, если значение по индексу index1 удовлетворяет op , когда сравнивается со значением по индексу index2 , следуя семантике соответствующего оператора Lua (т.е., могут вызываться метаметоды). Иначе возвращает 0. Также, возвращает 0, если любой из индексов не правильный.
- LUA_OPEQ : равенство ( == )
- LUA_OPLT : меньше ( < )
- LUA_OPLE : меньше или равно ( <= )
lua_concat
Производит конкатенацию n значений на вершине стека, снимает их со стека и оставляет результат на вершине стека. Если n = 1, результат это одно значение на стеке (т.е., функция ничего не делает); если n = 0, результат пустая строка. Конкатенация выполняется следуя обычной семантике Lua (см. §3.4.6).
lua_copy
Копирует элемент по индексу fromidx в правильный индекс toidx , заменяя значение на этой позиции. Значения в других позициях не изменяются.
lua_createtable
Создает новую пустую таблицу и ложит её на стек. Параметр narr — подсказка, сколько элементов в таблице будет как последовательность; параметр nrec — подсказка, сколько других элементов будет в таблице. Lua может использовать эти подсказки для предварительного выделения памяти для таблицы. Это предварительное выделение памяти полезно для производительности, когда вы заранее знаете сколько элементов будет в таблице. Иначе вы можете использовать функцию lua_newtable .
lua_dump
Сохраняет функцию как бинарный кусок. Получает Lua функцию на вершине стека и выдает её скомпилированной, при повторной загрузке куска, результаты эквивалентны результатам компилируемой функции. По мере выдачи частей куска, для его записи, lua_dump вызывает функцию writer (см. lua_Writer ) с полученной переменной data .
Если strip = true, бинарное представление может не включать всю отладочную информацию о функции, для уменьшения размера.
Возвращаемое значение: код ошибки, возвращенный при последнем вызове функции writer; 0 означает нет ошибок.
Эта функция не убирает Lua функцию со стека.
lua_error
Генерирует ошибку Lua, используя значение на вершине стека, как объект ошибки. Эта функция производит длинный переход (long jump) и никогда не возвращается (см. luaL_error ).
lua_gc
Управляет сборщиком мусора.
- LUA_GCSTOP : останавливает сборщик мусора.
- LUA_GCRESTART : перезапускает сборщик мусора.
- LUA_GCCOLLECT : производит полный цикл сборки мусора.
- LUA_GCCOUNT : возвращает текущий объем памяти (в килобайтах), используемый Lua.
- LUA_GCCOUNTB : возвращает остаток от деления текущего объема памяти, используемой Lua, в байтах на 1024.
- LUA_GCSTEP : производит шаг очистки мусора.
- LUA_GCSETPAUSE : устанавливает data , как новое значение для паузы сборщика (см. §2.5), и возвращает предыдущее значение паузы.
- LUA_GCSETSTEPMUL : устанавливает data , как новое значение для множителя шагов сборщика (см. §2.5), и возвращает предыдущее значение множителя шагов.
- LUA_GCISRUNNING : возвращает логическое значение, которое говорит, что сборщик запущен (т.е., не остановлен).
Для более подробного описания опций, см. collectgarbage .
lua_getallocf
Возвращает функцию выделения памяти для данного Lua состояния. Если ud не NULL , Lua записывает в *ud непрозрачный указатель, полученный когда устанавливалась функция выделения памяти.
lua_getfield
Ложит в стек значение t[k] , где t — значение по индексу index. Как и в Lua, эта функция может запускать метаметод для события «index» (см. §2.4).
Возвращает тип положенного на стек значения.
lua_getextraspace
Возвращает указатель на область «сырой» (raw) памяти, ассоциированную с данным Lua состоянием. Приложение может использовать эту область для любых целей; Lua не использует эту область.
Каждый новый поток имеет такую область, инициализированную копией области главного потока.
По умолчанию, эта область имеет размер пустого указателя [ sizeof(void*) ], но вы можете перекомпилировать Lua с другим размером для этой области (см. LUA_EXTRASPACE в luaconf.h ).
lua_getglobal
Ложит в стек значение глобальной переменной name . Возвращает тип этого значения.
lua_geti
Ложит в стек значение t[i] , где t — значение по индексу index. Как и в Lua, эта функция может запускать метаметод для события «index» (см. §2.4).
Возвращает тип положенного на стек значения.
lua_getmetatable
Если значение по индексу index имеет метатаблицу, функция ложит эту метатаблицу на стек и возвращает 1. Иначе, функция возвращает 0 и ничего не ложит на стек.
lua_gettable
Ложит на стек значение t[k] , где t — значение по индексу index и k — значение на вершине стека.
Эта функция снимает ключ со стека и ложит результирующее значение на его место. Как и в Lua, эта функция может запускать метаметод для события «index» (см. §2.4).
Возвращает тип положенного на стек значения.
lua_gettop
Возвращает индекс элемента на вершине стека. Т.к. индексы начинаются с 1, результат равен количеству элементов в стеке; в частности, 0 означает, что стек пуст.
lua_getuservalue
Ложит на стек Lua значение ассоциированное с пользовательскими данными (userdata), находящимися по индексу index.
Возвращает тип положенного на стек значения.
lua_insert
Перемещает верхний элемент стека в полученный правильный индекс, сдвигая вверх элементы выше этого индекса. Эта функция не может быть использована с псевдоиндексом, т.к. псевдоиндекс не обозначает актуальной позиции на стеке.
lua_Integer
Тип целых в Lua.
По умолчанию, это тип long long , (обычно 64-битное целое), но это может быть изменено в long или int (обычно 32-битное целое). (см. LUA_INT_TYPE в luaconf.h .)
Lua также определяет константы LUA_MININTEGER и LUA_MAXINTEGER , с минимальным и максимальным значениями для этого типа.
lua_isboolean
Возвращает 1, если значение по индексу index имеет тип boolean, иначе возвращает 0.
lua_iscfunction
Возвращает 1, если значение по индексу index это C функция, иначе возвращает 0.
lua_isfunction
Возвращает 1, если значение по индексу index это функция (любая C или Lua), иначе возвращает 0.
lua_isinteger
Возвращает 1, если значение по индексу index это целое (т.е., это число и оно представлено как целое [integer]), иначе возвращает 0.
lua_islightuserdata
Возвращает 1, если значение по индексу index это легкие пользовательские данные (light userdata), иначе возвращает 0.
lua_isnil
Возвращает 1, если значение по индексу index это nil, иначе возвращает 0.
lua_isnone
Возвращает 1, если полученный индекс не правильный, иначе возвращает 0.
lua_isnoneornil
Возвращает 1, если полученный индекс не правильный или значение по индексу это nil, иначе возвращает 0.
lua_isnumber
Возвращает 1, если значение по индексу index это число или строка конвертируемая в число, иначе возвращает 0.
lua_isstring
Возвращает 1, если значение по индексу index это строка или число (которое всегда можно преобразовать в строку), иначе возвращает 0.
lua_istable
Возвращает 1, если значение по индексу index это таблица, иначе возвращает 0.
lua_isthread
Возвращает 1, если значение по индексу index это поток (thread), иначе возвращает 0.
lua_isuserdata
Возвращает 1, если значение по индексу index это пользовательские данные (любые полные или легкие), иначе возвращает 0.
lua_isyieldable
Возвращает 1, если данная сопрограмма может уступить (yield), иначе возвращает 0.
lua_KContext
Тип для контекста функции продолжения. Он должен быть числовым типом. Этот тип определен как intptr_t , когда intptr_t доступен, так что может содержать и указатели. Иначе, тип определен как ptrdiff_t .
lua_KFunction
Тип для функций продолжения (см. §4.7).
lua_len
Возвращает длину значения по индексу index. Это эквивалент Lua оператору ‘ # ‘ (см. §3.4.7) и может вызывать метаметод для события «length» (см. §2.4). Результат ложится на стек.
lua_load
Загружает Lua кусок без запуска его на исполнение. Если ошибок нет, lua_load ложит на стек скомпилированный кусок, как Lua функцию. Иначе, ложит на стек сообщение об ошибке.
- LUA_OK : нет ошибок;
- LUA_ERRSYNTAX : синтаксическая ошибка при компиляции;
- LUA_ERRMEM : ошибка выделения памяти;
- LUA_ERRGCMM : ошибка при выполнении метаметода __gc . (Эта ошибка не имеет отношения к загружаемому куску. Она генерируется сборщиком мусора.)
Функция lua_load использует пользовательскую функцию reader для чтения куска (см. lua_Reader ). Аргумент data — это непрозрачный указатель, передаваемый функции reader.
Аргумент chunkname дает куску имя, которое используется для сообщений об ошибках и в отладочной информации (см. §4.9).
lua_load автоматически определяет, когда кусок текст или бинарные данные, и соответственно загружает его (см. программу luac ). Строка mode работает как и в функции load , с добавлением того, что значение NULL эквивалентно строке » bt «.
lua_load использует стек непосредственно, поэтому функция reader всегда должна оставлять его неизменным после возвращения.
Если результирующая функция имеет внешние локальные переменные (upvalue), её первое upvalue устанавливается в значение глобального окружения, записанное в реестре по индексу LUA_RIDX_GLOBALS (см. §4.5). При загрузке главных кусков, это upvalue будет переменной _ENV (см. §2.2). Остальные upvalue инициализируются значением nil.
lua_newstate
Создает новый поток, выполняющийся в новом независимом состоянии. Возвращает NULL , если не может создать поток или состояние (из-за нехватки памяти). Аргумент f — функция выделения памяти; Lua выполняет всё выделение памяти для данного состояния через эту функцию. Второй аргумент, ud — это непрозрачный указатель, который Lua передает в функцию выделения памяти при каждом вызове.
lua_newtable
Создает новую пустую таблицу и ложит её на стек. Эквивалентно вызову lua_createtable(L, 0, 0) .
lua_newthread
Создает новый поток, ложит его на стек и возвращает указатель на lua_State , который представляет этот новый поток. Новый поток использует одно глобальное окружение с оригинальным потоком, но имеет независимый стек исполнения.
Не существует явной функции для закрытия или уничтожения потока. Потоки это субъект для сборки мусора, как и любой Lua объект.
lua_newuserdata
Функция выделяет новый блок памяти размером size, ложит на стек новый объект full userdata (полные пользовательские данные) с адресом этого блока, и возвращает этот адрес. Хостовая программа может свободно использовать эту память.
lua_next
Снимает ключ со стека, ложит пару ключ-значение из таблицы, находящейся по индексу index («следующая» пара после данного ключа). Если в таблице больше нет элементов, lua_next возвращает 0 (и ничего не ложит на стек).
Типичный перебор элементов таблицы выглядит так:
Когда производится перебор таблицы, не вызывайте lua_tolstring прямо на ключе, пока не убедитесь, что ключ действительно строка. Помните, что lua_tolstring может изменить значение на полученном индексе; это собьет следующий вызов lua_next .
Смотри функцию next для предостережений о модификации таблицы во время её перебора.
lua_Number
Тип вещественных чисел в Lua.
По умолчанию, это тип double, но он может быть изменен в single float или long double (см. LUA_FLOAT_TYPE в luaconf.h ).
lua_numbertointeger
Преобразует вещественное Lua в целое Lua. Этот макрос предполагает, что n имеет целое значение. Если это значение входит в диапазон целых Lua, оно конвертируется в целое и назначается в *p . Макрос возвращает логическое значение, указывающее, что преобразование успешно. (Учтите, что из-за округлений эта проверка диапазона может быть мудрёной, чтобы сделать её корректно без этого макроса.)
Этот макрос может вычислять свои аргументы несколько раз.
lua_pcall
Вызывает функцию в защищенном режиме.
Оба nargs и nresults имеют тоже значение, что и в lua_call . Если в течение вызова нет ошибок, lua_pcall действует точно как lua_call . Тем не менее, в случае любых ошибок, lua_pcall перехватывает их, ложит одно значение на стек (собщение об ошибке) и возвращает код ошибки. Как и lua_call , lua_pcall всегда удаляет функцию и её аргументы со стека.
Если msgh = 0, сообщение об ошибке, возвращенное на стек, это оригинальное сообщение об ошибке. Иначе, msgh — это стековый индекс обработчика ошибок. (Этот индекс не может быть псевдоиндексом.) В случае ошибок выполнения, эта функция будет вызвана с сообщением об ошибке и значение, которое она вернет, будет возвращено на стеке функцией lua_pcall .
Обычно обработчик ошибок используется чтобы добавить больше отладочной информации в сообщение об ошибке, такой как трассировка стека. Эта информация не может быть получена после возврата из lua_pcall , поскольку стек будет ракручен.
- LUA_OK (0): успех.
- LUA_ERRRUN : ошибка выполнения.
- LUA_ERRMEM : ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик ошибок.
- LUA_ERRERR : ошибка при выполнении обработчика ошибок.
- LUA_ERRGCMM : ошибка при выполнении метаметода __gc . (Эта ошибка обычно не имеет отношения к вызываемой функции.)
lua_pcallk
Функция аналогична lua_pcall , но позволяет вызванной функции уступать (см. §4.7).
lua_pop
Снимает n элементов со стека.
lua_pushboolean
Ложит на стек логическое значение (boolean) равное b .
lua_pushcclosure
Ложит на стек новое C замыкание.
Когда C функция создана, можно ассоциировать с ней несколько значений, таким образом создав C замыкание (closure) (см. §4.4); эти значения доступны функции во время вызова. Чтобы ассоциировать эти значениея с C функцией, сначала эти значения нужно положить на стек (первое значение ложится первым). Затем вызвать lua_pushcclosure для создания C функции на стеке, с аргументом n , сообщающим сколько значений будет ассоциировано с функцией. lua_pushcclosure снимает эти значения со стека.
Максимальное значение для n это 255.
Когда n = 0, эта функция создает лёгкую C функцию, которая является лишь указателем на C функцию. В этом случае, она никогда не вызывает ошибку памяти.
lua_pushcfunction
Ложит C функцию на стек. Эта функция принимает указатель на C функцию и ложит в стек Lua значение типа function , которое при вызове запускает соответствующую C функцию.
Любая функция, чтобы быть работоспособной в Lua, должна следовать корректному протоколу приема параметров и возврата результатов (см. lua_CFunction ).
lua_pushfstring
- Вы не выделяете место для результата: результат Lua строка и Lua заботится о выделении памяти (и её освобождении, через сборку мусора).
- Спецификаторы преобразований ограничены. Здесь нет флагов, ширины или точности. Спецификаторы могут быть только следующими: ‘ %% ‘ (вставляет символ ‘ % ‘), ‘ %s ‘ (вставляет строку завершаемую нулем, без ограничений по размеру), ‘ %f ‘ (вставляет lua_Number ), ‘ %I ‘ (вставляет lua_Integer ), ‘ %p ‘ (вставляет указатель как шестнадцатиричное число), ‘ %d ‘ (вставляет int ), ‘ %c ‘ (вставляет int как однобайтовый символ), ‘ %U ‘ (вставляет long int как байтовую последовательность UTF-8).
lua_pushglobaltable
Ложит глобальное окружение в стек.
lua_pushinteger
Ложит на стек целое равное n .
lua_pushlightuserdata
Ложит на стек легкие пользовательские данные (light userdata).
Пользовательские данные представляют C значения в Lua. Легкие пользовательские данные предсталяют указатель, void* . Это значение (как число): вы не создаете его, оно не имеет индивидуальной метатаблицы, и не уничтожается сборщиком (т.к. никогда не создаётся). Легкие пользовательские данные равны «любым» легким пользовательским данным с тем же C адресом.
lua_pushliteral
Этот макрос аналогичен lua_pushstring , но должен использоваться только, когда s это литеральная строка.
lua_pushlstring
Ложит на стек строку, указанную s , размером len . Lua создает (или использует снова) внутреннюю копию данной строки, так что после завершения функции память по адресу s может быть освобождена или использована снова. Строка может содержать любые бинарные данные, в том числе встроенные нули.
Возвращает указатель на внутреннюю копию строки.
lua_pushnil
Ложит на стек значение nil.
lua_pushnumber
Ложит на стек вещественное число равное n .
lua_pushstring
Ложит на стек завершаемую нулем строку, указанную s . Lua создает (или использует снова) внутреннюю копию данной строки, так что после завершения функции память по адресу s может быть освобождена или использована снова.
Возвращает указатель на внутреннюю копию строки.
Если s = NULL , ложит nil и возвращает NULL .
lua_pushthread
Ложит на стек поток, представленный Lua состоянием L . Возвращает 1, если поток является главным потоком состояния.
lua_pushvalue
Ложит на стек копию элемента по индексу index.
lua_pushvfstring
Аналогично lua_pushfstring , за исключением того, что фунцкция получает va_list вместо переменного числа аргументов.
lua_rawequal
Возвращает 1, если два значения по индексам index1 и index2 примитивно равны (т.е. без вызова метаметодов). Иначе возвращает 0. Также возвращает 0, если любой из индексов не правильный.
lua_rawget
Аналогично lua_gettable , но производит «сырой» доступ (т.е. без вызова метаметодов).
lua_rawgeti
Ложит на стек значение t[n] , где t — таблица по индексу index. Доступ «сырой», т.е. без вызова метаметодов.
Возвращает тип положенного на стек значения.
lua_rawgetp
Ложит на стек значение t[k] , где t — таблица по индексу index, k — указатель p , представленный как лёгкие пользовательские данные. Доступ «сырой», т.е. без вызова метаметодов.
Возвращает тип положенного на стек значения.
lua_rawlen
Возвращет сырую «длину» значения по индексу index: для строк это длина строки; для таблиц это результат оператора длины (‘ # ‘) без метаметодов; для пользовательских данных это размер выделенного блока памяти; для остальных значений это 0.
lua_rawset
Аналогично lua_settable , но производит «сырое» присваивание (т.е. без вызова метаметодов).
lua_rawseti
Действие аналогично t[i] = v , где t — таблица по индексу index, v — значение на вершине стека.
Эта функция снимает значение со стека. Присваивание «сырое», т.е. без вызова метаметодов.
lua_rawsetp
Действие аналогично t[p] = v , где t — таблица по индексу index, p — кодируется как легкие пользовательские данные, v — значение на вершине стека.
Эта функция снимает значение со стека. Присваивание «сырое», т.е. без вызова метаметодов.
lua_Reader
Функция reader использется в lua_load . Каждый раз, когда требуется следующая часть куска, lua_load вызывает функцию reader, передавая ей свой параметр data . Функция reader должна возвращать указатель на блок памяти с новой частью куска и устанавливать size равным размеру блока. Блок должен существовать, пока функция reader не будет вызвана снова. Для сигнала о конце куска, функция должна вернуть NULL или установить size равным 0. Функция reader может возвращать части любого размера больше нуля.
lua_register
Устанавливает C функцию f в качестве нового значения глобальной переменной name . Функция определена как макрос:
lua_remove
Удаляет элемент по данному правильному индексу, сдвигая вниз элементы выше этого индекса, чтобы заполнить промежуток. Эта функция не может быть вызвана с псевдоиндексом, т.к. псевдоиндекс не является действительной позицией в стеке.
lua_replace
Перемещяет элемент с вершины стека в позицию по правильному индексу index без сдвига элементов (следовательно, заменяя значение по данному индексу) и затем снимает вехний элемент со стека.
lua_resume
Запускает и продолжает сопрограмму в данном потоке L .
Для запуска подпрограммы, вы ложите в стек потока главную функцию и её аргументы; затем вызываете lua_resume , nargs — количество аргументов. Этот вызов возвращается, когда сопрограмма приостанавливается или завершается. Когда функция возвращается, стек содержит все значения, переданные в lua_yield , или все значения, возвращенные телом функции. lua_resume возвращает LUA_YIELD — если сопрограмма уступила, LUA_OK — если сопрограмма завершила свое исполнение без ошибок, или код ошибки в случае ошибок (см. lua_pcall ).
В случае ошибок, стек не раскручивается, так вы можете использовать отладочные API на нём. Сообщение об ошибке находится на вершине стека.
Чтобы продолжить сопрограмму, вы удаляете все результаты из последнего lua_yield , ложите в её стек только значения, передаваемые в качестве результатов из yield , и затем вызываете lua_resume .
Параметр from представляет сопрограмму, которая продолжает L . Если такой сопрограммы нет, этот параметр может быть равен NULL .
lua_rotate
Вращает элементы стека между правильным индексом idx и вершиной стека. Элементы вращаются на n позиций по направлению к вершине стека, для позитивного n ; или -n позиций в направлении дна стека, для отрицательного n . Абсолютное значение n должно быть не больше чем размер вырезки для вращения. Эта функция не может быть вызвана с псевдоиндексом, т.к. псевдоиндекс не является действительной позицией в стеке.
lua_setallocf
Заменяет функцию выделения памяти данного состояния на функцию f с пользовательскими данными ud .
lua_setfield
Действие аналогично t[k] = v , где t — таблица по индексу index, v — значение на вершине стека.
Эта функция снимает значение со стека. Как и в Lua, эта функция может запускать метаметод для события «newindex» (см. §2.4).
lua_setglobal
Снимает значение со стека и устанавливает его в качестве нового значения глобальной переменной name .
lua_seti
Действие аналогично t[n] = v , где t — значение по индексу index, v — значение на вершине стека.
Эта функция снимает значение со стека. Как и в Lua, эта функция может запускать метаметод для события «newindex» (см. §2.4).
lua_setmetatable
Снимает таблицу со стека и устанавливает её в качестве новой метатаблицы для значения по индексу index.
lua_settable
Действие аналогично t[k] = v , где t — значение по индексу index, v — значение на вершине стека, k — значение следующее за верхним.
Эта функция снимает со стека ключ и значение. Как и в Lua, эта функция может запускать метаметод для события «newindex» (см. §2.4).
lua_settop
Принимает любой индекс или 0, и устанавливает вершину стека равной этому индексу. Если новая вершина больше предыдущей, новые элементы заполняются значением nil. Если index = 0, то все элементы стека удаляются.
lua_setuservalue
Снимает значение со стека и устанавливает его в качестве нового значения, ассоциированного с пользовальскими данными (userdata) по индексу index.
lua_State
Непрозрачная структура, которая указывает на поток и косвенно (через поток) на целое состояние интерпретатора Lua. Библиотека Lua полностью повторно входимая: она не имеет глобальных переменных. Вся информация о состоянии доступна через эту структуру.
Указатель на эту структуру должен передаваться, как первый аргумент, в каждую функцию в библиотеке, за исключением lua_newstate , которая создает Lua состояние.
lua_status
Возвращает состояние потока L .
Статус может быть 0 ( LUA_OK ) — для нормального потока, код ошибки — если поток завершил выполнение lua_resume с ошибкой, или LUA_YIELD — если поток приостановлен.
Вы можете вызывать функции только в потоках со статусом LUA_OK . Вы можете продолжать потоки со статусом LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для продолжения сопрограммы).
lua_stringtonumber
Преобразует завершаемую нулем строку s в число, ложит это число на стек и возвращает общий размер строки, т.е. её длину + 1. Результатом преобразования может быть целое или вещественное число, в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак. Если строка не правильное число, функция возвращает 0 и ничего не ложит на стек. (Имейте ввиду, что результат может быть использован как логическое значение, если преобразование успешно, то результат true.)
lua_toboolean
Преобразует Lua значение по индексу index в C boolean (0 или 1). Как и все проверки в Lua, lua_toboolean возвращает true для любого Lua значения отличного от false и nil; иначе, возвращает false. (Если вы хотите принимать только значения типа boolean, используйте lua_isboolean для проверки.)
lua_tocfunction
Преобразует Lua значение по индексу index в C функцию. Это значение должно быть C функцией; иначе, возвращает NULL .
lua_tointeger
Эквивалент lua_tointegerx с isnum = NULL .
lua_tointegerx
Преобразует Lua значение по индексу index в целое со знаком типа lua_Integer . Lua значение должно быть целым, или числом или строкой, преобразуемой в целое (см. §3.4.3); иначе, lua_tointegerx возвращает 0.
Если isnum != NULL , он указывает на логическое значение, которое показывает успешность операции.
lua_tolstring
Преобразует Lua значение по индексу index в C строку. Если len != NULL , она также устанавливает *len равным длине строки. Lua значение должно быть строкой или числом; иначе, функция возвращает NULL . Если значение число, то lua_tolstring также изменяет действительное значение в стеке в строку. (Это изменение сбивает lua_next , когда lua_tolstring применяется к ключам при переборе таблицы.)
lua_tolstring возвращает полностью выровненный указатель на строку внутри Lua состояния. Эта строка всегда имеет завершающий ноль (‘ \0 ‘) после последнего символа (как в C), но может содержать другие нули в своем теле.
Т.к. в Lua есть сборка мусора, нет гарантии, что указатель, возвращенный lua_tolstring , будет действителен после удаления соответствующего Lua значения из стека.
lua_tonumber
Эквивалент lua_tonumberx с isnum = NULL .
lua_tonumberx
Преобразует Lua значение по индексу index в C тип lua_Number (см. lua_Number ). Lua значение должно быть числом или строкой, преобразуемой в число (см. §3.4.3); иначе, lua_tonumberx возвращает 0.
Если isnum != NULL , он указывает на логическое значение, которое показывает успешность операции.
lua_topointer
Преобразует Lua значение по индексу index в пустой C указатель ( void* ). Значение может быть пользовательскими данными, таблицей, потоком или функцией; иначе, lua_topointer возвращает NULL . Разные объекты дадут разные указатели. Не существует способа сконвертировать указатель обратно в оригинальное значение.
Обычно эта функция используется для хеширования и отладочной информации.
lua_tostring
Эквивалент lua_tolstring с len = NULL .
lua_tothread
Преобразует Lua значение по индексу index в Lua поток (представленный как lua_State* ). Это значение должно быть потоком; иначе, функция возвращает NULL .
lua_touserdata
Если значение по индексу index это полные пользовательские данные, возвращает адрес их блока. Если значение это легкие пользовательские данные, возвращает их указатель. Иначе, возвращает NULL .
lua_type
Возвращает тип значения по правильному индексу index, или LUA_TNONE для не правильного (но допустимого) индекса. Типы, возвращаемые lua_type , кодируются следующими константами (определены в lua.h ): LUA_TNIL (0), LUA_TNUMBER , LUA_TBOOLEAN , LUA_TSTRING , LUA_TTABLE , LUA_TFUNCTION , LUA_TUSERDATA , LUA_TTHREAD и LUA_TLIGHTUSERDATA .
lua_typename
Возвращает имя типа, кодированного значением tp , которое должно быть одним из возвращаемых lua_type .
lua_Unsigned
lua_upvalueindex
Возвращает псевдоиндекс, который представляет i -е upvalue запущенной функции (см. §4.4).
lua_version
Возвращает адрес номера версии, хранящейся в ядре Lua. Когда вызвана с правильным lua_State , возвращает адрес версии, использованной для создания этого состояния. Когда вызвана с NULL , возвращает адрес версии выполнившей вызов.
lua_Writer
Тип функции writer, используемой в lua_dump . Каждый раз, когда производится очередная часть куска, lua_dump вызывает функцию writer, передавая ей буфер для записи ( p ), его размер ( sz ) и параметр data , переданный в lua_dump .
Функция writer возвращает код ошибки; 0 означает нет ошибок; любое другое значение означает ошибку и останавливает lua_dump от последующих вызовов writer.
lua_xmove
Обмен значениями между разными потоками одного состояния.
Эта функция снимает со стека from n значений и ложит их в стек to .
lua_yield
Функция аналогична lua_yieldk , но она не имеет продолжения (см. §4.7). Следовательно, когда поток продолжается, он продолжает функцию, которая вызвала lua_yield .
lua_yieldk
Устапает сопрограмму (поток).
Когда C функция вызывает lua_yieldk , вызывающая сопрограмма приостанавливает свое исполнение, и вызов lua_resume , который запустил эту сопрограмму, возвращается. Параметр nresults — это количество значений в стеке, которые будут переданы как результаты в lua_resume .
Когда сопрограмма снова возобновится, Lua вызывает переданную функцию продолжения k , для продолжения выполнения C функции, которая уступила (см. §4.7). Эта функция продолжения получает тот же стек из предыдущей функции, но n результатов будут удалены и заменены аргументами, переданными в lua_resume . Кроме того, функция продолжения получает значение ctx , переданное в lua_yieldk .
Обычно эта функция не возвращается; когда сопрограмма в конечном счете возобновляется, она выполняет фукнцию продолжения. Тем не менее, есть один специальный случай, который случается когда функция вызвана из построчного перехватчика (см. §4.9). В этом случает, lua_yieldk должна быть вызвана без продолжения (вероятно в форме lua_yield ), и перехватчик должен вернуться непосредственно после вызова. Lua уступит и, когда сопрограмма вновь возобновится, она продолжит нормальное исполнение (Lua) функции, которая инициировала перехват.
Эта функция может вызывать ошибку, если вызвана из потока с незаконченным C вызовом без функции продолжения, или если вызвана из потока, который не запущен внутри сопрограммы (т.е., главный поток).
4.9 – Отладочный интерфейс
Lua не имеет встроенных отладочных средств. Взамен, он предлагает специальный интерфейс функций и перехватчиков (hook). Этот интерфейс позволяет строить различные типы отладчиков, профилировщиков и других инструментов, нуждающихся во «внутренней информации» интерпретатора.
lua_Debug
Структура, используемая для хранения различных частей информации о функции или о записи активации. lua_getstack заполняет только приватную часть этой структуры, для последующего использования. Для заполнения остальных полей lua_Debug полезной информацией, вызовите lua_getinfo .
- source : имя куска, который создал функцию. Если source начинается с ‘ @ ‘, это означает, что функция была определена в файле, где имя файла следует за символом ‘ @ ‘. Если source начинается с ‘ = ‘, остаток его содержимого описывает источник в определяемой пользователем форме. Иначе, функция была определена в строке, где source — эта строка.
- short_src : «выводимая» (printable) версия source , для использования в сообщениях об ошибках.
- linedefined : номер строки, где начинается определение функции.
- lastlinedefined : номер строки, где заканчивается определение функции.
- what : строка «Lua» — если функция это Lua функция, «C» — если это C функция, «main» — если это главная часть куска.
- currentline : текущая строка, где полученная функция исполняется. Когда информация о строках не доступна, currentline устанавливается равным -1.
- name : разумное имя полученной функции. Т.к. функции в Lua это первоклассные значения, они не имеют фиксированных имен: некоторые функции могут быть значениями множества глобальных переменных, тогда как другие могут храниться только в полях таблицы. Чтобы найти подходящее имя lua_getinfo проверяет как функция была вызвана. Если она не может найти имя, то name устанавливается равным NULL .
- namewhat : поясняет поле name . Значение namewhat может быть «global» , «local» , «method» , «field» , «upvalue» или «» (пустая строка), в соответствии с тем как была вызвана функция. (Lua использует пустую строку, когда не может применить ни какую другую опцию.)
- istailcall : истина, если этот вызов функции хвостовой (tail call). В этом случае, вызывающий этого уровня не на стеке.
- nups : количество upvalue у функции.
- nparams : количество фиксированных параметров у функции (всегда 0 для C функций).
- isvararg : истина, если функция имеет переменное число аргументов (всегда истина для C функций).
lua_gethook
Возвращает текущую функцию перехватчик.
lua_gethookcount
Возвращает количество перехватчиков.
lua_gethookmask
Возвращает текущую маску перехватов.
lua_getinfo
Предоставляет информацию о специфической функции или о вызове функции.
Для получения информации о вызове функции, параметр ar должен быть правильной записью активации, которая заполняется вызовом lua_getstack или передается как аргумент в перехватчик (см. lua_Hook ).
Для получения информации о функции, нужно положить её в стек и начать строку what символом ‘ > ‘. (В этом случае, lua_getinfo снимет функцию с вершины стека.) Например, чтобы узнать в которой строке определена функция f , вы можете написать следующий код:
- ‘ n ‘: заполняет поля name и namewhat ;
- ‘ S ‘: заполняет поля source , short_src , linedefined , lastlinedefined и what ;
- ‘ l ‘: заполняет поле currentline ;
- ‘ t ‘: заполняет поле istailcall ;
- ‘ u ‘: заполняет поля nups , nparams и isvararg ;
- ‘ f ‘: ложит в стек функцию, которая запущена на данном уровне;
- ‘ L ‘: ложит в стек таблицу, индексы которой — это номера значимых строк функции. (Значимая строка — это строка с некоторым кодом, т.е. строка, где можно поставить точку останова [break point]. Не значащие строки — это пустые строки и комментарии.)
Эта функция возвращает 0 при ошибке (например, при неправильной опции в строке what ).
lua_getlocal
Предоставляет информацию о локальной переменной данной записи активации или функции.
В первом случае, параметр ar должен быть правильной записью активации, которая заполнена предыдущим вызовом lua_getstack или передана как аргумент перехватчику (см. lua_Hook ). Индекс n выбирает локальную переменную для проверки; см. debug.getlocal для подробностей о индексах и именах переменных.
lua_getlocal ложит в стек значение переменной и возвращает её имя.
Во втором случае, ar должен быть NULL , и функция для проверки должна находиться на вершине стека. В этом случае, видны только параметры Lua функций (т.к. здесь нет информации о том, какие переменные активны) и значения в стек не ложатся.
Возвращает NULL (и ничего не ложит на стек), когда индекс больше чем количество активных локальных переменных.
lua_getstack
Предоставляет информацию о исполняемом (runtime) стеке интерпретатора.
Эта функция заполняет части структуры lua_Debug с индентификацией записи активации функции, выполняемой на данном уровне (level). Уровень 0 — это текущая выполняющаяся функция, уровень n+1 — это функция которая вызывает уровень n (за исключением хвостовых вызовов, которые не считаются на стеке). Когда ошибок нет, lua_getstack возвращает 1; когда вызвана с уровнем больше чем глубина стека, возвращает 0.
lua_getupvalue
Предоставляет информацию о n -ном upvalue замыкания по индексу funcindex . Функция ложит на стек значение upvalue и возвращает его имя. Возвращает NULL (и ничего не ложит на стек), когда индекс n больше количества upvalue.
Для C функций, эта функция использует пустую строку «» в качестве имени для всех upvalue. (Для Lua функций, upvalue — это внешние локальные переменные, которые использует функция, и которые, следовательно, включены в её замыкание.)
Upvalue не имеют конкретного порядка, как они активны внутри функции. Они нумеруются в произвольном порядке.
lua_Hook
Тип для отладочных функций перехватчиков.
Всякий раз, когда вызывается перехватчик, его аргумент ar имеет поле event , установленное согласно событию, вызвавшему срабатывание перехватчика. Lua идентифицирует эти события следующими константами: LUA_HOOKCALL , LUA_HOOKRET , LUA_HOOKTAILCALL , LUA_HOOKLINE и LUA_HOOKCOUNT . Более того, для событий строк устанавливается поле currentline . Для получения значений остальных полей в ar , перехватчик должен вызвать lua_getinfo .
Для событий вызова, event может быть LUA_HOOKCALL — нормальное значение, или LUA_HOOKTAILCALL — для хвостового вызова; в этом случае, соответствующего события возврата не будет.
Пока Lua выполняет перехватчик, все остальные перехватчики отключаются. Следовательно, если перехватчик вызывает Lua для выполнения функции или куска, это выполнение произойдет без вызова перехватчиков.
Функции перехватчики не могут иметь продолжений, т.е. они не могут вызывать lua_yieldk , lua_pcallk или lua_callk с не нулевым k .
Функции перехватчики могут уступать при следующих условиях: только счетные и события строк могут уступать; для уступки, функция перехватчик должна завершить свое исполнение, вызвав lua_yield с nresults = 0 (т.е. без значений).
lua_sethook
Устанавливает отладочную функцию-перехватчик.
- Перехватчик вызова (call hook): вызывается, когда интерпретатор вызывает функцию. Перехватчик вызывается сразу после того, как Lua войдет в новую функцию, перед тем как функция получит свои аргументы.
- Перехватчик возврата (return hook): вызывается, когда интерпретатор возвращается из функции. Перехватчик вызывается перед тем, как Lua покинет функцию. Здесь нет стандартного пути для доступа к возвращаемым функцией значениям.
- Перехватчик строки (line hook): вызывается, когда интерпретатор начинает выполнение новой строки кода, или когда он переходит назад в код (даже в ту же строку). (Это событие случается только пока Lua выполняет Lua функцию.)
- Счетный перехватчик (count hook): вызывается после того, как интерпретатор запустит count инструкций. (Это событие случается только пока Lua выполняет Lua функцию.)
Перехват отключается установкой mask = 0.
lua_setlocal
Устанавливает значение локальной переменной в данной записи активации (ar). Устанавливает переменной значение с вершины стека и возвращает её имя, затем удаляет значение из стека.
Возвращает NULL (и ничего не удаляет со стека), когда индекс больше количества активных локальных переменных.
Параметры ar и n такие же, как в функции lua_getlocal .
lua_setupvalue
Устанавливает значение для upvalue замыкания. Устанавливает upvalue равным значению с вершины стека и возвращает её имя, затем удаляет значение из стека
Возвращает NULL (и ничего не удаляет со стека), когда индекс больше количества upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue .
lua_upvalueid
Возвращает уникальный идентификатор для upvalue под номером n из замыкания по индексу funcindex .
Эти уникальные идентификаторы позволяют программе проверить, когда замыкания совместно используют upvalue. Lua замыкания, которые совместно используют upvalue (т.е., обращаются к одной внешней локальной переменной), вернут одинаковые идентификаторы для индексов своих upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue , но n не может быть больше количества upvalue.
lua_upvaluejoin
Делает n1 -ое upvalue Lua замыкания по индексу funcindex1 ссылкой на n2 -ое upvalue Lua замыкания по индексу funcindex2 .
5 – Вспомогательная библиотека
Вспомогательная библиотека предоставляет различные удобные функции для взаимодействия C с Lua. Когда базовые API предоставляют примитивные функции для всех взаимодействий между C и Lua, вспомогательная библиотека предоставляет высокоуровневые функции для некоторых общих задач.
Все функции и типы вспомогательной библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_ .
Все функции вспомогательной библиотеки строятся из базовых API, и так они не предоставляют ничего, чего нельзя было бы сделать с помощью этих API. Тем не менее, использование вспомогательной библиотеки гарантирует большую стабильность вашему коду.
Различные функции вспомогательной библиотеки используют внутри несколько дополнительных слотов. Когда функция вспомогательной библиотеки использует меньше пяти слотов, она не проверяет размер стека; она просто предполагает, что там достаточно слотов.
Различные функции вспомогательной библиотеки используются для проверки аргументов C функций. Так как сообщение об ошибке формируется для аргументов (т.е., » bad argument #1 «), вы не должны использовать эти функции для других значений стека.
Функции luaL_check* всегда генерируют ошибку, если проверка не удовлетворена.
5.1 – Функции и типы
Здесь представлен список всех функций и типов вспомогательной библиотеки в алфавитном порядке.
luaL_addchar
Добавляет байт c в буфер B (см. luaL_Buffer ).
luaL_addlstring
Добавляет строку по указателю s длиной l в буфер B (см. luaL_Buffer ). Строка может содержать встроенные нули.
luaL_addsize
Добавляет в буфер B (см. luaL_Buffer ) строку длиной n , прежде скопированную в область буфера (см. luaL_prepbuffer ).
luaL_addstring
Добавляет завершаемую нулем строку по указателю s в буфер B (см. luaL_Buffer ).
luaL_addvalue
Добавляет значение с вершины стека в буфер B (см. luaL_Buffer ). Снимает значение со стека.
Только эта функция для строковых буферов может (и должна) вызываться с дополнительным аргументом на стеке, являющимся значением для добавления в буфер.
luaL_argcheck
Проверяет когда cond истина. Если это не так, генерирует ошибку со стандартным сообщением (см. luaL_argerror ).
luaL_argerror
Генерирует ошибку, сообщающую о проблеме с аргументом arg для C функции, которая вызвала luaL_argerror. Используется стандартное сообщение, включающее extramsg как комментарий:
Эта функция никогда не возвращается.
luaL_Buffer
Тип для строкового буфера.
- Сначала объявляется переменная b типа luaL_Buffer .
- Затем она инициализируется вызовом luaL_buffinit(L, &b) .
- Затем части строки добавляются в буфер вызовами функций luaL_add* .
- Завершается вызовом luaL_pushresult(&b) . Этот вызов оставляет финальную строку на вершине стека.
- Сначала объявляется переменная b типа luaL_Buffer .
- Затем вызовом luaL_buffinitsize(L, &b, sz) она инициализируется, и для неё выделяется память размером sz .
- Затем в эту область копируется строка.
- Завершается вызовом luaL_pushresultsize(&b, sz) , где sz — размер результирующей строки, скопированной в эту область.
При нормальном управлении, строковый буфер использует переменное число слотов стека. Так, пока используется буфер, вы не можете предполагать, что вы знаете где вершина стека. Вы можете использовать стек между успешными вызовами буферных операций, пока он сбалансирован; т.е., когда вы вызываете буферную операцию, стек должен быть на том же уровне, что и непосредственно после предыдущей буферной операции. (Существует только одно исключение, это luaL_addvalue .) После вызова luaL_pushresult стек возвращается на тот уровень, когда был инициализирован буфер, плюс результирующая строка на вершине.
luaL_buffinit
Инициализирует буфер B . Эта функция не выделяет память; буфер должен быть определен как переменная (см. luaL_Buffer ).
luaL_buffinitsize
luaL_callmeta
Если объект по индексу obj имеет метатаблицу и его метатаблица имеет поле e , эта функция вызывает это поле, передавая объект в качестве первого аргумента. В этом случае функция возвращает true и ложит в стек значение, возвращенное вызовом метаметода. Если метатаблицы или метаметода не существует, функция возвращает false (и ничего не ложит на стек).
luaL_checkany
Проверяет, что функция имеет аргумент любого типа (включая nil) по индексу arg .
luaL_checkinteger
Проверяет, что аргумент функции arg это целое (или может быть преобразован в целое), и возвращает это целое, как lua_Integer .
luaL_checklstring
Проверяет, что аргумент функции arg это строка, и возвращает эту строку; если l не NULL , пишет в *l длину строки.
Эта функция использует lua_tolstring для получения результата, так все преобразования и предостережения этой функции относятся и сюда.
luaL_checknumber
Проверяет, что аргумент функции arg это число, и возвращает это число.
luaL_checkoption
Проверяет, что аргумент функции arg это строка, и ищет эту строку в массиве lst (который должен завершаться NULL-символом). Возвращает индекс в массиве, где найдена строка. Генерирует ошибку, если аргумент не строка или строка не найдена в массиве.
Если def не NULL , функция использует def как значение по умолчанию, когда нет аргумента arg или он равен nil.
Эта функция полезна для отображения строк в C перечисления (enum). (Обычно, для выбора опций в Lua библиотеках принято использовать строки вместо чисел.)
luaL_checkstack
Увеличивает размер стека до top + sz элементов, вызывает ошибку, если стек не может быть увеличен до этого размера. msg — это дополнительный текст для сообщения об ошибке (или NULL , если его нет).
luaL_checkstring
Проверяет, что аргумент функции arg это строка, и возвращает эту строку.
Эта функция использует lua_tolstring для получения результата, так все преобразования и предостережения этой функции относятся и сюда.
luaL_checktype
Проверяет, что аргумент функции arg имеет тип t . См. lua_type для кодировок типов t .
luaL_checkudata
Проверяет, что аргумент функции arg это пользовательские данные типа tname (см. luaL_newmetatable ), и возвращает адрес пользовательских данных (см. lua_touserdata ).
luaL_checkversion
Проверяет, что ядро, выполняющее вызов, ядро, создавшее Lua состояние, и код, производящий вызов, все используют одну версию Lua. Также проверяет, что ядро, выполняющее вызов, и ядро, создавшее Lua состояние, используют одно адресное пространство.
luaL_dofile
Загружает и запускает данный файл. Определена как макрос:
Возвращает false, если ошибок нет, или true в случае ошибок.
luaL_dostring
Загружает и запускает переданную строку. Определена как макрос:
Возвращает false, если ошибок нет, или true в случае ошибок.
luaL_error
Генерирует ошибку. Сообщение об ошибке форматируется строкой fmt и дополнительными аргументами, следует тем же правилам, что и lua_pushfstring . Также добавляет в начало сообщения имя файла и номер строки, где произошла ошибка, если эта информация доступна.
Эта функция никогда не возвращается, но её идиома для использования в C функциях: return luaL_error(args) .
luaL_execresult
Эта функция выдает возвращаемые значения для связанных с процессами функций стандартной библиотеки ( os.execute и io.close ).
luaL_fileresult
Эта функция выдает возвращаемые значения для связанных с файлами функций стандартной библиотеки ( io.open , os.rename , file:seek и др.).
luaL_getmetafield
Ложит на стек поле e из метатаблицы объекта по индексу obj и возвращает тип положенного на стек значения. Если объект не имеет метатаблицы или в метатаблице нет этого поля, ничего не ложит на стек и возвращает LUA_TNIL .
luaL_getmetatable
Ложит на стек метатаблицу, ассоциированную с именем tname в реестре (см. luaL_newmetatable ) (nil, если метатаблицы с таким именем нет). Возвращает тип положенного на стек значения.
luaL_getsubtable
Гарантирует, что значение t[fname] это таблица, и ложит эту таблицу на стек; t — это значение по индексу idx . Возвращает true, если находит существующую таблицу, и false, если создает новую.
luaL_gsub
Создает копию строки s , заменяя все вхождения строки p на строку r . Ложит на стек результирующую строку и возвращает её.
luaL_len
Возвращает «длину» значения по индексу index как число; эквивалентна Lua оператору ‘ # ‘ (см. §3.4.7). Генерирует ошибку, если результат операции не целое. (Это может случиться только через метаметоды.)
luaL_loadbuffer
Эквивалентно luaL_loadbufferx с mode = NULL .
luaL_loadbufferx
Загружает буфер как Lua кусок. Эта функция использует lua_load для загрузки куска в буфер buff размером sz .
Функция возвращает те же результаты, что и lua_load .
name — имя куска, используемое для отладочной информации и сообщений об ошибках. Строка mode работает как в функции lua_load .
luaL_loadfile
Эквивалентно luaL_loadfilex с mode = NULL .
luaL_loadfilex
Загружает файл как Lua кусок. Эта функция использует lua_load для загрузки куска из файла filename . Если filename = NULL , загружает кусок из потока стандартного ввода. Первая линия файла игнорируется, если она начинается с # .
Строка mode работает как в функции lua_load .
Эта функция возвращает те же результаты, что и lua_load , но имеет дополнительный код ошибки LUA_ERRFILE , если не может открыть/прочитать файл или файл имеет неверный режим.
Как и lua_load , эта функция только загружает кусок; но не запускает его.
luaL_loadstring
Загружает строку как Lua кусок. Эта функция использует lua_load для загрузки завершаемой нулем строки s .
Эта функция возвращает те же результаты, что и lua_load .
Как и lua_load , эта функция только загружает кусок; но не запускает его.
luaL_newlib
Создает новую таблицу и регистрирует в ней функции из списка l .
Реализована как макрос:
Массив l должен быть фактическим массивом, не указателем на него.
luaL_newlibtable
Создает новую таблицу с размером, оптимизированным для хранения всех записей массива l (но фактически не сохраняет их). Она предполагается для использования в связке с luaL_setfuncs (см. luaL_newlib ).
Реализована как макрос. Массив l должен быть фактическим массивом, не указателем на него.
luaL_newmetatable
Если реестр уже содержит ключ tname , возвращает 0. Иначе, создает новую таблицу для использования в качестве метатаблицы пользовательских данных, добавляет в эту новую таблицу пару __name = tname , добавляет в реестр пару [tname] = new table , и возвращает 1. (Элемент __name используется некоторыми функциями, сообщающими об ошибках.)
В обоих случаях ложит на стек финальное значение ассоциированное с tname в реестре.
luaL_newstate
Создает новое Lua состояние. Вызывает lua_newstate с функцией выделения памяти, базирующейся на стандартной C функции realloc , и затем устанавливает функцию паники (см. §4.6), которая в случае фатальных ошибок печатает сообщение об ошибке в стандартный поток вывода.
Возвращает новое состояние, или NULL , если не удалось выделить память.
luaL_openlibs
Открывает все стандартные библиотеки Lua в данное состояние.
luaL_optinteger
Если аргумент функции arg это целое (или может быть преобразован в целое), возвращает это целое. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
luaL_optlstring
Если аргумент функции arg это строка, возвращает эту строку. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
Если l не NULL , записывает в *l длину результата.
luaL_optnumber
Если аргумент функции arg это число, возвращает это число. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
luaL_optstring
Если аргумент функции arg это строка, возвращает эту строку. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
luaL_prepbuffer
Эвивалентно luaL_prepbuffsize с предопределенным размером LUAL_BUFFERSIZE .
luaL_prepbuffsize
Возвращает адрес пространства размером sz , куда вы можете скопировать строку, чтобы добавить в буфер B (см. luaL_Buffer ). После копирования строки в это пространство, вы должны вызвать luaL_addsize с размером строки, для фактического добавления её в буфер.
luaL_pushresult
Завершает использование буфера B , оставляя финальную строку на вершине стека.
luaL_pushresultsize
luaL_ref
Создает и возвращает ссылку (reference) в таблице по индексу t , для объекта на вершине стека (и снимает этот объект со стека).
Ссылка это уникальный целый ключ. Пока вы не добавляете целые ключи в таблицу t , luaL_ref гарантирует уникальность возвращаемых ключей. Вы можете извлечь объект по ссылке r , вызвав lua_rawgeti(L, t, r) . Функция luaL_unref освобождает ссылку и ассоциированный с ней объект.
Если объект на вершине стека равен nil, luaL_ref возвращает константу LUA_REFNIL . Константа LUA_NOREF всегда отлична от любой другой ссылки, возвращаемой luaL_ref .
luaL_Reg
Тип для массивов функций для регистрации функцией luaL_setfuncs . name — имя функции, func — указатель на функцию. Любой массив luaL_Reg должен завершаться ключевым элементом, в котором name и func = NULL .
luaL_requiref
Если modname ещё не присутствует в package.loaded , вызывает функцию openf со строкой modname в качестве аргумента и пишет результат вызова в package.loaded[modname] , как если бы эта функция была бы вызвана через require .
Если glb = true, также сохраняет модуль в глобальную modname .
Оставляет копию модуля на стеке.
luaL_setfuncs
Регистрирует все функции в массиве l (см. luaL_Reg ) в таблицу на вершине стека (ниже опциональных upvalue, см. далее).
Когда nup != 0, все функции создаются, разделяющими nup upvalue, которые должны быть предварительно положены на стек поверх таблицы библиотеки. После регистрации эти значения снимаются со стека.
luaL_setmetatable
Устанавливает метатаблицей объекта на вершине стека метатаблицу, ассоциированную с именем tname в реестре (см. luaL_newmetatable ).
luaL_Stream
Стандартное представление для описателей файлов (handle), которые используются стандартной библиотекой ввода-вывода.
Описатель файла реализован как полные пользовательские данные, с метатаблицей называемой LUA_FILEHANDLE (где LUA_FILEHANDLE — это макрос с фактическим именем метатаблицы). Метатаблица создается библиотекой ввода-вывода (см. luaL_newmetatable ).
Эти пользовательские данные должны начинаться со структуры luaL_Stream ; они могут содержать другие данные после этой начальной структуры. Поле f — указывает на соответствующий C поток (ими может быть NULL для индикации не полностью созданного описателя). Поле closef — указывает на Lua функцию, которая будет вызвана для закрытия потока, при закрытии или сборке описателя; эта функция получает описатель файла в качестве единственного аргумента и должна вернуть true (в случае успеха) или nil с сообщением об ошибке (в случае ошибки). Как только Lua вызывает это поле, его значение меняется на NULL для сигнализации, что описатель закрыт.
luaL_testudata
Эта функция работает как luaL_checkudata , за исключением того, что когда проверка неудачна, она возвращает NULL , вместо генерирования ошибки.
luaL_tolstring
Конвертирует любое Lua значение по индексу idx в C строку в разумном формате. Результирующая строка ложится на стек и также возвращается функцией. Если len не NULL , функция пишет в *len длину строки.
Если значение имеет метатаблицу с полем «__tostring» , то luaL_tolstring вызывает соответствующий метаметод со значением в качестве аргумента и использует результат вызова, как свой результат.
luaL_traceback
Создает и ложит на стек трассировку стека L1 . Если msg не NULL , оно добавляется в начало трассировки. Параметр level указывает на каком уровне начинать трассировку.
luaL_typename
Возвращает имя типа для значения по индексу index.
luaL_unref
Освобождает ссылку ref из таблицы по индексу t (см. luaL_ref ). Элемент удаляется из таблицы, так что ассоциированный объект может быть собран сборщиком мусора. Ссылка ref также освобождается для повторного использования.
Если ref = LUA_NOREF или LUA_REFNIL , luaL_unref ничего не делает.
luaL_where
Ложит на стек строку, идентифицирующую текущую позицию на управляющем уровне lvl в стеке вызовов. Обычно эта строка имеет следующий формат:
Уровень 0 — это текущая выполняемая функция, уровень 1 — это функция, которая вызвала текущую, и так далее.
Эта функция используется для формирования префикса сообщений об ошибках.
6 – Стандартные библиотеки
Стандартные библиотеки Lua предоставляют полезные функции, реализованные напрямую через C API. Некоторые из этих функций предоставляют существенные службы языка (например, type и getmetatable ); другие предоставляют доступ к «внешним» сервисам (например, I/O); и другие могут быть реализованы в Lua самостоятельно, но очень полезны и имеют критические требования к производительности, что заслуживает реализации в C (например, table.sort ).
- базовая библиотека (§6.1);
- библиотека сопрограмм (§6.2);
- библиотека пакетов (§6.3);
- манипуляции со строками (§6.4);
- базовая поддержка UTF-8 (§6.5);
- манипуляции с таблицами (§6.6);
- математические функции (§6.7) (sin, log и др.);
- ввод и вывод (§6.8);
- средства операционной системы (§6.9);
- отладочные средства (§6.10).
За исключением базовой и пакетной библиотек, каждая библиотека предоставляет все свои функции, как поля глобальной таблицы или методы её объектов.
Для получения доступа к этим библиотекам хоствая C программа должна вызвать функцию luaL_openlibs , которая открывает все стандартные библиотеки. Либо, хостовая программа может открыть их индивидуально, используя luaL_requiref для вызова luaopen_base (для базовой библиотеки), luaopen_package (для библиотеки пакетов), luaopen_coroutine (для библиотеки сопрограмм), luaopen_string (для строковой библиотеки), luaopen_utf8 (для библиотеки UTF8), luaopen_table (для табличной библиотеки), luaopen_math (для математической библиотеки), luaopen_io (для библиотеки ввода-вывода), luaopen_os (для библиотеки операционной системы) и luaopen_debug (для отладочной библиотеки). Все эти функции определены в lualib.h .
6.1 – Базовые функции
Базовая библиотека предоставляет функции ядра для Lua. Если вы не включите эту библиотеку в ваше приложение, вы должны проявлять осторожность, когда будете нуждаться в предоставлении реализаций для некоторых её возможностей.
assert (v [, message])
Вызывает error , если значение аргумента v = false (т.е., nil или false); иначе, возвращает все свои аргументы. В случае ошибки, message — это объект ошибки; когда он отсутствует, его значение по умолчанию » assertion failed! «
collectgarbage ([opt [, arg]])
- » collect «: выполняет полный цикл очистки мусора. Это опция по умолчанию.
- » stop «: останавливает автоматическое выполнение сборщика мусора. Сборщик будет запущен, только когда явно вызван, до вызова его перезапуска.
- » restart «: перезапускает автоматическое выполнение сборщика мусора.
- » count «: возвращает общее количество используемой Lua памяти в килобайтах. Это значение имеет дробную часть, так что его произведение на 1024 дает точное количство байт, используемых Lua (за исключением переполнений).
- » step «: выполняет шаг сборки мусора. «Размер» шага контролируется аргументом arg . С нулевым значением сборщик выполнит один базовый (неделимый) шаг. Для не нулевых значений, сборщик выполнит, как если это количество памяти (в килобайтах) было выделено Lua. Возвращает true, если шаг завершил цикл сборки.
- » setpause «: устанавливает arg в качестве нового значения для паузы сборщика (см. §2.5). Возвращает предыдущее значение паузы.
- » setstepmul «: устанавливает arg в качестве нового значения для множителя шагов сборщика (см. §2.5). Возвращает предыдущее значение шага.
- » isrunning «: возвращает логическое значение, говорящее запущен ли сборщик (т.е. не остановлен).
dofile ([filename])
error (message [, level])
Обычно error добавляет информацию о позиции ошибки в начало сообщения, если сообщение (message) это строка. Аргумент level определяет как получить позицию ошибки. Когда level = 1 (по умолчанию) — позиция ошибки там, где вызвана функция error . Level = 2 — указывает ошибку там, где вызвана функция, вызвавшая error ; и так далее. Передача level = 0 — позиция ошибки не влючается в сообщение.
getmetatable (object)
Если object не имеет метатаблицы, возвращает nil. Иначе, если метатаблица объекта имеет поле «__metatable» , возвращает ассоциированное с этим полем значение. Иначе, возвращает метатаблицу переданного объекта.
ipairs (t)
Возвращет три значения (функцию итератор, таблицу t и 0), так что конструкция
будет перебирать пары ключ–значение ( 1,t[1] ), ( 2,t[2] ), . до первого значения nil.
load (chunk [, chunkname [, mode [, env]]])
Если chunk это строка, кусок будет этой строкой. Если chunk это функция, load многократно вызывает её, чобы получить части куска. Каждый вызов chunk должен возвращать строку, которая присоединяется к предыдущим результатам. Возврат пустой строки, nil или ничего сигнализирует о конце куска.
Если в куске нет синтаксических ошибок, возвращает скомпилированный кусок, как функцию; иначе, возвращает nil и сообщение об ошибке.
Если результирующая функция имеет upvalue, первое upvalue устанавливается равным env , если этот параметр передан, или в значение глобального окружения. Остальные upvalue инициализируются значением nil. (Когда вы загружаете главный кусок, результирующая функция всегда будет иметь только одно upvalue, переменную _ENV (см. §2.2). Тем не менее, когда вы загружаете бинарный кусок, созданный из функции (см. string.dump ), результирующая функция может иметь произвольное количество upvalue.) Все upvalue свежие, т.е. они не разделяются между любыми другими функциями.
chunkname — используется как имя куска, для сообщений об ошибках и отладочной информации (см. §4.9). Когда отсутствует, его значение по умолчанию это сам chunk , если chunk это строка, или » =(load) » иначе.
Строка mode — управляет каким может быть кусок, текстовым или бинарным (т.е. прекомпилированным). Она может быть » b » (только бинарные куски), » t » (только текстовые куски) или » bt » (текстовые и бинарные куски). Значение по умолчанию это » bt «.
Lua не проверяет правильность бинарных кусков. Злонамеренно созданный бинарный кусок может разрушить интерпретатор.
loadfile ([filename [, mode [, env]]])
Аналогично load , но получает кусок из файла filename или из стандартного потока ввода, если имя файла не передано.
next (table [, index])
Позволяет программе просмостреть все поля таблицы. Её первый аргумент — это таблица, второй аргумент — индекс в этой таблице. next возвращает следующий индекс таблицы и ассоциированное с ним значение. Когда вызывается с nil в качестве второго аргумента, next возвращает начальный индекс и ассоциированое с ним значение. Когда вызывается с последним индексом, или с nil для пустой таблицы, next возвращает nil. Если второй аргумет отсутствует, то он интерпретируется как nil. В частности, вы можете использовать next(t) для проверки, что таблица пустая.
Порядок перечисления индексов не определен, даже для числовых индексов. (Для просмотра таблицы в числовом порядке, используйте числовой for.)
Поведение next неопределено, если во время просмотра вы присваиваете любое значение несуществующему полю в таблице. Тем не менее вы можете модифицировать существующие поля. В частности, вы можете очищать существующие поля.
pairs (t)
Если t имеет метаметод __pairs , вызывает его с аргументом t и возвращает первые три результата вызова.
Иначе, возвращает три значения: функцию next , таблицу t и nil, так что конструкция
будет перебирать все пары ключ–значение в таблице t .
См. функцию next для предострежений о модификации таблицы во время просмотра.
pcall (f [, arg1, ···])
Вызывает функцию f с переданными аргументами в защищенном режиме. Это значит, что любая ошибка внутри f не распространяется; взамен, pcall перехватывает ошибку и возвращает код статуса. Её первый результат — код статуса (логическое значение), которое равно true, если вызов успешен. В этом случае pcall также возвращает все результаты из вызова, после первого результата. В случае ошибки pcall возвращает false и сообщение об ошибке.
print (···)
rawequal (v1, v2)
rawget (table, index)
rawlen (v)
rawset (table, index, value)
Эта функция возвращает table .
select (index, ···)
Если index это число, возвращает все аргументы после аргумента номер index ; негативное число индексируется с конца (-1 последний аргумент). Иначе, если index строка «#» , select вернет общее количество дополнительных аргументов.
setmetatable (table, metatable)
Устанавливает метатаблицу для данной таблицы. (Вы не можете изменять метатаблицы других типов из Lua, только из C.) Если metatable = nil, удаляет метатаблицу переданной таблицы. Если оригинальная метатаблица имеет поле «__metatable» , генерирует ошибку.
Эта функция возвращает table .
tonumber (e [, base])
Когда вызвана без аргумента base , tonumber пытается конвертировать аргумент в число. Если аргумент уже число или строка, которую можно преобразовать в число, то tonumber возвращает это число; иначе, возвращает nil.
Преобразование строк может выдавать в результате целые или вещественные числа, в соответствии с лексическими соглашениями Lua (см. §3.1). (Строка может иметь начальные и конечные пробелы и знак.)
Когда вызвана с аргументом base , то аргумент e должен быть строкой, которая интерпретируется как целое в данной системе счисления. base может быть любым целым от 2 до 36, включительно. При base > 10, символ ‘ A ‘ (в верхнем или нижнем регистре) представляет 10, ‘ B ‘ представляет 11 и так далее, с ‘ Z ‘ представляющим 35. Если строка e не правильное число в данной системе счисления, функция возвращает nil.
tostring (v)
Если метатаблица v имеет поле «__tostring» , то tostring вызывает соответствующее значение с v в качестве аргумента и использует результат вызова, как свой результат.
type (v)
_VERSION
xpcall (f, msgh [, arg1, ···])
Эта функция похожа на pcall , но она устанавливает новый обработчик сообщений msgh .
6.2 – Работа с сопроцессами
Эта библиотека содержит операции для манипуляции с сопроцессами, которые хранятся в таблице coroutine . См. §2.6 для общего описания сопроцессов.
coroutine.create (f)
Создает новый сопроцесс, с телом f . f должен быть функцией. Возвращает этот новый сопроцесс, как объект с типом «thread» .
coroutine.isyieldable ()
Возвращает true, когда запущенный сопроцесс может уступить.
Запущенный сопроцесс может уступать, если это не главный поток и он не внутри неприостанавливаемой C функции.
coroutine.resume (co [, val1, ···])
Начинает или продолжает выполнение сопроцесса co . При первом возобновлении сопроцесса запускает его тело. Значение val1 , . передаются как аргументы телу сопроцесса (его функции). Если сопроцесс был приостановлен, resume перезапускает его; значниния val1 , . передаются как результаты из yield.
Если сопроцесс запущен без ошибок, resume возвращает true и все значения, переданные в yield (когда сопроцесс уступает) или все значения, возвращенные функцией сопроцесса (когда сопроцесс завершается). В случае ошибок, resume возвращает false и сообщение об ошибке.
coroutine.running ()
Возвращает запущенный сопроцесс и логическое значение; true, если сопроцесс это главный поток.
coroutine.status (co)
Возвращает статус сопроцесса co , как строку: «running» — сопроцесс запущен (т.е. он вызвал status ); «suspended» — сопроцесс приостановлен в вызове yield или еще не запущен; «normal» — сопроцесс активен, но не выполняется (т.е. он был продолжен другим сопроцессом); «dead» — сопроцесс завершил своё тело или был остановлен с ошибкой.
coroutine.wrap (f)
Создает новый сопроцесс с телом f . f должен быть функцией. Возвращает функцию, которая возобновляет сопроцесс при каждом её вызове. Все аргументы, переданные этой функции, ведут себя как дополнительные аргументы в resume . Возвращает те же значения, что и resume , за исключением первого логического значения. В случае ошибки, распространяет ошибку.
coroutine.yield (···)
Приостанавливает выполнение вызывающего сопроцесса. Все аргументы yield передаются, как дополнительные результаты в resume .
6.3 – Модули
Эта пакетная библиотека предоставляет базовые возможности для загрузки модулей в Lua. Она экспортирует одну функцию напрямую в глобальное окружение: require . Всё остальное экспортируется в таблице package .
require (modname)
Загружает переданный модуль. Функция начинает с просмотра таблицы package.loaded для определения, что модуль modname уже загружен. Если это так, то require возвращает значение, хранящееся в package.loaded[modname] . Иначе, пробует найти загрузчик для модуля.
При поиске загрузчика require руководствуется последовательностью package.searchers . Изменяя эту последовательность, вы можете изменить то, как require ищет модуль. Следующее объяснение базируется на конфигурации по умолчанию для package.searchers .
Сначала require запрашивает package.preload[modname] . Если это значение существует, то это значение (которое может быть функцией) это загрузчик. Иначе require ищет Lua загрузчик, используя путь, хранящийся в package.path . Если это тоже неудачно, она ищет C загрузчик, используя путь, хранящийся в package.cpath . Если и это неудачно, пробует все в одном загрузчик (см. package.searchers ).
Как только загрузчик найден, require вызывает загрузчик с двумя аргументами: modname и дополнительное значение, зависящее от того, как получен загрузчик. (Если загрузчик пришел из файла, это дополнительное значение будет именем файла.) Если загрузчик возвращает не-nil значение, require записывает возвращенное значение в package.loaded[modname] . Если загрузчик не вернул не нулевое значение и package.loaded[modname] не присвоено никакое значение, то require пишет туда true. В любом случае, require возвращает финальное значение package.loaded[modname] .
Если во время загрузки или запуска модуля происходит ошибка, или если не найден ни один загрузчик для модуля, require генерирует ошибку.
package.config
- Первая строка — это строка разделитель директорий. По умолчанию, это ‘ \ ‘ для Windows и ‘ / ‘ для всех остальных систем.
- Вторая строка — символ, который разделяет шаблоны в пути. По умолчанию это ‘ ; ‘.
- Третья строка — это строка, которая обозначает точки замены в шаблоне. По умолчанию это ‘ ? ‘.
- Четвертая строка — это строка, которая в пути в Windows, заменяется на директорию исполняемого файла. По умолчанию это ‘ ! ‘.
- Пятая строка — это метка для игнорирования всего текста после неё, когда формируется имя функции luaopen_ . По умолчанию это ‘ — ‘.
package.cpath
Этот путь используется require для поиска C загрузчика.
Lua инициализирует C путь package.cpath также, как и Lua путь package.path , используя переменную окружения LUA_CPATH_5_3 или переменную окружения LUA_CPATH или путь по умолчанию, определенный в luaconf.h .
package.loaded
Таблица, используемая require для контроля за тем, какие модули уже загружены. Когда вы загружаете модуль modname и package.loaded[modname] не false, require просто возвращает хранящееся там значение.
Эта переменная только ссылка на реальную таблицу; присваивание этой переменной не изменяет таблицу, используемую функцией require .
package.loadlib (libname, funcname)
Динамически связывает (link) хостовую программу с C библиотекой libname .
Если funcname , то она только связывает с библиотекой, делая экспортируемые библиотекой символы доступными для других динамических библиотек. Иначе, она ищет функцию funcname внутри библиотеки и возвращает эту функцию, как C функцию. Так, funcname должна соответствовать прототипу lua_CFunction (см. lua_CFunction ).
Это низкоуровневая функция. Она полностью обходит систему пакетов и модулей. В отличие от require , она не производит поисков пути и не добавляет расширения автоматически. libname должен быть завершенным именем файла C библиотеки, включая, если необходимо, путь и расширение. funcname должен быть точным именем, экспортируемым C библиотекой (которое может зависеть от используемого C компилятора и компоновщика).
Эта функция не поддерживается стандартным C. Т.к., она доступна только для некоторых платформ (Windows, Linux, Mac OS X, Solaris, BSD и другие Unix системы, которые поддерживаю стандарт dlfcn ).
package.path
Этот путь используется require для поиска Lua загрузчика.
Во время запуска Lua инициализирует эту переменную значением переменной окружения LUA_PATH_5_3 или переменной окружения LUA_PATH , или значением по умолчанию, определенным в luaconf.h , если эти переменные окружения не определены. Любое » ;; » в значении переменной окружения заменяется путем по умолчанию.
package.preload
Таблица для хранения загрузчиков для специфических модулей (см. require ).
Эта переменная только ссылается на реальную таблицу; присваиваение этой переменной не изменяет таблицу, используемую функцией require .
package.searchers
Таблица, используемая require для контроля над тем, как загружать модули.
Каждый элемент в этой таблице это функция искатель (searcher). Когда ищется модуль, require вызывает каждую из этих функций в возрастающем порядке, с именем модуля (аргумент переданный в require ) в качестве единственного параметра. Функция может вернуть другую функцию (загрузчик модуля) и дополнительное значение, которое будет передано загрузчику, или строку, объясняющую, почему модуль не найден (или nil если нечего сказать).
Lua инициализирует эту таблицу четырьмя функциями искателями.
первый искатель просто ищет загрузчик в таблице package.preload .
Втрой искатель ищет загрузчик для Lua библиотеки, используя путь package.path . Поиск производится как описано в функции package.searchpath .
Третий искатель ищет загрузчик для C библиотеки, используя путь package.cpath . Поиск производится как описано в функции package.searchpath . Например, если C путь это строка
искатель для модуля foo будет пробовать открыть файлы ./foo.so , ./foo.dll , и /usr/local/foo/init.so , в этом порядке. Когда он найдет C библиотеку, сначала он использует средства динамического связывания с библиотекой. Затем попытается найти в библиотеке C функцию для использования в качестве загрузчика. Имя этой C функции это строка » luaopen_ «, склеенная с копией имени модуля, где каждая точка заменена на подчеркивание. Более того, если имя модуля имеет дефис, его суффикс после первого дефиса удаляется (дефис тоже удаляется). Например, если имя модуля a.b.c-v2.1 , имя функции будет luaopen_a_b_c .
Четвертый искатель пробует все в одном загрузчик. Он ищет C путь для библиотеки с корневым путем переданного модуля. Например, когда требуется a.b.c , он будет искать C библиотеку a . Если существует, он заглянет в нее для открытия функции подмодуля; в нашем примере, это будет luaopen_a_b_c . С этой возможностью, пакет может упаковывать различные C подмодули в одной библиотеке, где каждый подмодуль имеет свою оригинальную функцию открытия.
Все искатели, за исключением первого (preload), возвращают имя файла, где найден модуль, как дополнительное значение, возвращаемое package.searchpath . Первый искатель не возвращает дополнительное значение.
package.searchpath (name, path [, sep [, rep]])
Ищет имя name в пути path .
Путь — это строка, содержащая последовательность шаблонов, разделенных точкой с запятой (;). Для каждого шаблона, функция заменяет каждый знак вопроса (если существует) копией name , где все случаи sep (точка, по умолчанию) заменяются на rep (системный разделитель директорий, по умолчанию), и пытается открыть результирующее имя файла.
Например, если путь это строка
поиск имени foo.a будет пытаться открыть файлы ./foo/a.lua , ./foo/a.lc и /usr/local/foo/a/init.lua , в этом порядке.
Возвращает результирующее имя первого файла, который можно открыть в режиме чтения (после закрытия файла), или nil и сообщение об ошибке, если ничего не удалось. (Это сообщение об ошибке перечисляет все имена файлов, которые пыталась открыть функция.)
6.4 – Работа со строками
Эта библиотека предоставляет общие функции для работы со строками, такие как поиск, извлечение подстрок и сопоставление шаблонов. Когда индексируются строки в Lua, первый символ находится на позиции 1 (не на 0, как в C). Допускаются негативные индексы, они интерпретируются как индексирование обратно (задом наперед), с конца строки. Таким образом, последний символ находится на позиции -1 и так далее.
Строковая библиотека предоставляет все свои функции в таблице string . Она также устанавливает метатаблицу для строк, где поле __index указывает на таблицу string . Следовательно, вы можете использовать строковые функции в объектно-ориентированном стиле. Например, выражение string.byte(s,i) может быть записано как s:byte(i) .
Строковая библиотека предполагает кодирование символов одним байтом.
string.byte (s [, i [, j]])
Цифровые коды не обязательно портабельны между платформами.
string.char (···)
Цифровые коды не обязательно портабельны между платформами.
string.dump (function [, strip])
Возвращает строку содержащую бинарное представление (бинарный кусок) переданной функции, так что load для этой строки возвращает копию функции (но с новыми upvalue). Если strip = true, бинарное представление может не включать всю отладочную информацию о функции, для уменьшения размера.
Функции с upvalue сохраняют только количество upvalue. При загрузке, эти upvalue получают свежие экземпляры, содержащие nil. (Вы можете использовать отладочную библиотеку, чтобы сохранить и перезагрузить upvalue функции в том виде, как вам нужно.)
string.find (s, pattern [, init [, plain]])
Ищет первое совпадение шаблона pattern (см. §6.4.1) в строке s . Если совпадение найдено, то find возвращает индексы s , где совпадение начинается и заканчивается; иначе, возвращает nil. Третий опциональный цифровой аргумент init определяет, где начинать поиск; по умолчанию он равен 1 и может быть отрицательным. Значение true в качестве четвертого опционального аргумента plain выключает возможности поиска шаблонов, так функция выполняет плоский поиск подстроки, без магических символов в pattern . Учтите, что если передан plain , то должен быть передан и init .
Если шаблон имеет захваты (capture), то при успешном совпадении захваченные значения также возвращаются, после двух индексов.
string.format (formatstring, ···)
Возвращает форматированную версию переменного количества аргументов, следуя описанию в первом аргументе (должен быть строкой). formatstring — следует тем же правилам, что и в функции sprintf в ISO C. Только отличается тем, что опции/модификаторы * , h , L , l , n и p не поддерживаются, и тем, что имеет дополнительную опцию q . Опция q форматирует строку между двойными кавычками и использует управляющие символы, когда необходимо гарантировать, что строка может быть прочитана Lua интерпретатором обратно. Например, вызов
может выдать строку:
Опции A , a , E , e , f , G и g — все ожидают цифровой аргумент. Оции c , d , i , o , u , X и x — ожидают целое. Опция q — ожидает строку. Опция s — ожидает строку без встроенных нулей; если аргумент не строка, он конвертируется следуя тем же правилам, что и в tostring .
Когда Lua скомпилирована с не C99 компилятором, опции A и a (шестнадцатиричные вещественные числа) не поддерживают модификаторы (флаги, ширина, длина).
string.gmatch (s, pattern)
Например, следующий цикл будет перебирать все слова из строки s , печатая по одному в строке:
Следующий пример собирает в таблице все пары key=value из строки:
Для этой функции, символ ‘ ^ ‘ в начале шаблона не работает как якорь, т.к. это мешает итерации.
string.gsub (s, pattern, repl [, n])
Если repl это строка, то её значение используется для замены. Символ % работает, как управляющий символ: любая последовательность в repl в виде %d , с d между 1 и 9, соответствует d-ой захваченной подстроке. Последовательность %0 соответствует полному совпадению. Последовательность %% соответствует одному символу % .
Если repl это таблица, то таблица запрашивается для каждого совпадения, используя первое захваченное значение, как ключ.
Если repl это функция, то эта функция вызывается для каждого совпадения, все захваченные подстроки передаются в качестве аргументов, по порядку.
В любом случае, если шаблон не имеет захватов, то он ведет себя так, будто весь шаблон находится в захвате.
Если значение, возвращенное из табличного запроса или из функции, это строка или число, то оно используется, как замещающая строка; иначе, если это false или nil, то замена не производится (т.е. оригинальное содержимое совпадения сохраняется в строке).
string.len (s)
string.lower (s)
string.match (s, pattern [, init])
string.pack (fmt, v1, v2, ···)
Возвращает бинарную строку, содержащую значения v1 , v2 и т.д. упакованными (т.е. записанными в бинарной форме) согласно форматной строке fmt (см. §6.4.2).
string.packsize (fmt)
Возвращает размер результирующей строки из string.pack с переданным форматом. Форматная строка не может иметь опций переменной длины ‘ s ‘ или ‘ z ‘ (см. §6.4.2).
string.rep (s, n [, sep])
string.reverse (s)
string.sub (s, i [, j])
Если после трансляции отрицательных индексов i j больше длины строки, он корректируется до этой длины. Если после этих преобразований i > j , функция возвращает пустую строку.
string.unpack (fmt, s [, pos])
Возвращает значения, упакованные в строке s (см. string.pack ) согласно форматной строке fmt (см. §6.4.2). Опциональный параметр pos отмечает, где начинать чтение в s (по умолчанию 1). После чтения значений, эта функция также возвращает индекс первого не прочитанного байта в s .
string.upper (s)
6.4.1 – Шаблоны
Шаблоны в Lua описываются регулярными строками, которые интерпретируются, как шаблоны, функциями сопоставления шаблонов string.find , string.gmatch , string.gsub и string.match . Этот раздел описывает синтаксис и значение (сопоставление) этих строк.
Символьный класс:
- x: (где x — не один из магических символов ^$()%.[]*+-? ) представляет символ x непосредственно.
- . : (точка) представляет все символы.
- %a : представляет все буквы.
- %c : представляет все управляющие символы.
- %d : представляет все цифры.
- %g : представляет все печатаемые символы, кроме пробела.
- %l : представляет все буквы в нижнем регистре.
- %p : представляет все знаки пунктуации.
- %s : представляет все пробельные символы.
- %u : представляет все буквы в верхнем регистре.
- %w : представляет все алфавитно-цифровые символы.
- %x : представляет все шестнадцатиричные символы.
- %x : (где x — не алфавитно-цифровой символ) представляет символ x. Это стандартный способ кодирования магических символов. Любой не алфавитно-цифровой символ (включая все знаки пунктуации, даже не магические) могут предваряться ‘ % ‘, когда используются для представления себя в шаблоне.
- [набор] : представляет класс, который является объединением всех символов в наборе. Диапазон символов может быть определен отделением конечного символа диапазона, в восходящем порядке, символом ‘ — ‘. Все классы % x, описанные выше, также могут быть включены в набор, как компоненты. Все остальные символы в наборе представляют непосредственно себя. Например, [%w_] (или [_%w] ) представляет все алфавитно-цифровые символы и подчеркивание, [0-7] представляет восьмиричные цифры, [0-7%l%-] представляет восьмиричные цифры, буквы в нижнем регистре и символ ‘ — ‘.
Для всех классов, представленных одним символом ( %a , %c и др.), соответствующие представления с буквой в верхнем регистре отрицают класс. Например, %S представляет все не пробельные символы.
Определения букв, пробелов и других групп символов зависят от текущей локали. В частности, класс [a-z] может не быть эквивалентом %l .
Элемент шаблона:
- односимвольный класс, который соответствует одному символу в классе;
- односимвольный класс с последующим символом ‘ * ‘, который соответствует нулю или более повторам символов в классе. Этот повтор элементов всегда будет соответствовать самой длинной возможной последовательности;
- односимвольный класс с последующим символом ‘ + ‘, который соответствует одному или более повторам символов в классе. Этот повтор элементов всегда будет соответствовать самой длинной возможной последовательности;
- односимвольный класс с последующим символом ‘ — ‘, который соответствует нулю или более повторам символов в классе. В отличие от ‘ * ‘, этот повтор элементов всегда будет соответствовать самой короткой возможной последовательности;
- односимвольный класс с последующим символом ‘ ? ‘, который соответствует нулю или одному случаю символа в классе. Он всегда соответсвует одному вхождению, если возможно;
- %n , для n между 1 и 9; этот элемент соответствует подстроке равной n-й захваченной строке (см. ниже);
- %bxy , где x и y два четких символа; этот элемент соответствует строкам, которые начинаются с x и заканчиваются на y, и где x и yсбалансированы. Это значит, что если при чтении строки слева направо, считать +1 для x и -1 для y, завершающий y это первый y, где счет достигнет 0. Например, элемент %b() соответсвует выражениям в сбалансированных скобках.
- %f[набор] , граничный шаблон; этот элемент соответствует пустой строке в любой позиции такой, что следующий символ принадлежит набору и предыдущий символ не принадлежит набору. Набор интерпретируется, как описано выше. Начало и конец субъекта обрабатывается, как если там символ ‘ \0 ‘.
Шаблон:
Шаблон — это последовательность элементов шаблона. Символ ‘ ^ ‘ в начале шаблона фиксирует его в начале строки. Символ ‘ $ ‘ в конце шаблона фиксирует его в конце строки. В остальных позициях ‘ ^ ‘ и ‘ $ ‘ не имеют специального значения и представляют сами себя.
Захваты (capture):
Шаблон может содержать подшаблоны заключенные в скобки; они описывают захваты. Когда совпадение успешно, подстроки, которые соответсвуют захватам (захваченные), сохраняются для последующего использования. Захваты нумеруются соответственно их левым скобкам. Например, в шаблоне «(a*(.)%w(%s*))» , часть строки, соответствующая «a*(.)%w(%s*)» , сохраняется как первый захват (и следовательно имеет номер 1); соответствие » . » захватывается с номером 2, и часть соответствующая » %s* » имеет номер 3.
Специальный случай, пустой захват () захватывает текущую позицию в строке (число). Например, если мы применим шаблон «()aa()» к строке «flaaap» , будет сделано два захвата: 3 и 5.
6.4.2 – Формат строк для string.pack и string.unpack
Первый аргумент в string.pack , string.packsize и string.unpack это строка формата, которая описывает формат создаваемой или читаемой структуры.
- < : устанавливает прямой порядок байт (little endian)
- > : устанавливает обратный порядок байт (big endian)
- = : устанавливает исконный порядок байт
- ![n] : устанавливает максимальное выравнивание равным n (по умолчанию, исконное выравнивание)
- b : знаковый байт ( char )
- B : беззнаковый байт ( char )
- h : знаковый short (исконный размер)
- H : беззнаковый short (исконный размер)
- l : знаковый long (исконный размер)
- L : беззнаковый long (исконный размер)
- j : lua_Integer
- J : lua_Unsigned
- T : size_t (исконный размер)
- i[n] : знаковый int с n байт (по умолчанию, исконный размер)
- I[n] : беззнаковый int с n байт (по умолчанию, исконный размер)
- f : float (исконный размер)
- d : double (исконный размер)
- n : lua_Number
- cn : строка фиксированного размера с n байт
- z : завершаемая нулем строка
- s[n] : строка с предваряющим её размером, кодированным как беззнаковое целое с n байт (по умолчанию, это size_t )
- x : один байт заполнения
- Xop : пустой элемент, который выравнивает в соответствии с опцией op (которая в противном случае игнорируется)
- ‘ ‘: (пустое пространство) игнорируется
(» [n] » означает опциональную целую цифру.) Кроме заполнения, пробелов и конфигураций (опции » xX <=>! «), каждая опция соответствует аргументу (в string.pack ) или результату (в string.unpack ).
Для опций » !n «, » sn «, » in » и » In «, n может быть целым от 1 до 16. Все целые опции проверяют переполнения; string.pack проверяет, что переданное значение поместится в переданный размер; string.unpack проверяет, что прочитанное значение поместится в целое Lua.
Любая строка формата начинается так, будто содержит префикс » !1= «, т.е. с максимальным выравниванием 1 (без выравнивания) и исконным порядком байт.
Выравнивание работает так: для каждой опции формат получает дополнительное заполнение, пока не начнутся данные по смещению, которое равно произведению минимума между размером опции и максимального выравнивания; этот минимум должен быть степенью 2. Опции » c » и » z » не выравниваются; опция » s » следует выравниванию её начального целого.
Все заполнения заполняются нулями в string.pack (и игнорируются в string.unpack ).
6.5 – Поддержка UTF-8
Эта библиотека предоставляет базовую поддержку для кодировки UTF-8. Она предоставляет все свои функции в таблице utf8 . Эта библиотека не предоставляет другой поддержки для Unicode, кроме обработки кодировки. Все операции, нуждающиеся в значении символа, такие как классификация символов, не входят в эту область.
Пока не установлено иначе, все функции, которые ожидают позицию байта, как параметр, предполагают, что переданная позиция является также началом последовательности байт или позиция плюс длина строки. Как и в строковой библиотеке, отрицательные индексы отсчитываются с конца строки.
utf8.char (···)
utf8.charpattern
utf8.codes (s)
Возвращает значения такие, что конструкция
будет перебирать все символы в строке s , где p — позиция (в байтах) и c — кодовая точка для каждого символа. Функция вызывает ошибку, если встретит неправильную последовательность байт.
utf8.codepoint (s [, i [, j]])
utf8.len (s [, i [, j]])
utf8.offset (s, n [, i])
Специальный случай, когда n = 0, функция возвращает начало закодированного символа, который содержит i -й байт строки s .
Эта функция предполагает, что s это правильная строка UTF-8.
6.6 – Работа с таблицами
Эта библиотека предоставляет базовые функции для работы с таблицами. Она предоставляет все свои функции в таблице table .
Помните, что когда операция нуждается в длине таблицы, таблица должа содержать соответсвующую последовательность или иметь метаметод __len (см. §3.4.7). Все функции игнорируют не цифровые ключи в таблицах, полученных как аргументы.
table.concat (list [, sep [, i [, j]]])
Получает список list, где все элементы строки или числа, возвращает строку list[i]..sep..list[i+1] ··· sep..list[j] . По умолчанию, sep это пустая строка, i = 1 и j = #list . Если i > j , возвращает пустую строку.
table.insert (list, [pos,] value)
Вставляет элемент value на позицию pos в список list , сдвигая элементы вверх list[pos], list[pos+1], ···, list[#list] . По умолчанию, pos = #list+1 , так вызов table.insert(t,x) вставляет x в конец списка t .
table.move (a1, f, e, t [,a2])
Перемещает элементы из таблицы a1 в таблицу a2 . Эта функция эквивалентна множественному присваиванию: a2[t],··· = a1[f],···,a1[e] . По умолчанию, a2 = a1 . Целевой диапазон может перекрываться с диапазоном источником. Количество элементов для перемещения должно помещаться в целое Lua.
table.pack (···)
Возвращает новую таблицу, в которой все параметры сохранены с ключами 1, 2 и т.д. и поле » n » содержит количество параметров. Учтите, что результирующая таблица может не быть последовательностью.
table.remove (list [, pos])
Удаляет из списка list элемент на позиции pos , возвращая значение этого элемента. Когда pos это целое между 1 и #list , функция сдвигает элементы вниз list[pos+1], list[pos+2], ···, list[#list] и стирает элемент list[#list] ; Индекс pos может быть 0, когда #list = 0, или #list + 1 ; в этих случаях функция стирает элемент list[pos] .
По умолчанию, pos = #list , так вызов table.remove(l) удаляет последний элемент списка l .
table.sort (list [, comp])
Сортирует элементы полученного списка, на месте, от list[1] до list[#list] . Если передан параметр comp , он должен быть функцией, которая получает два элемента списка и возвращает true, когда первый элемент должен находиться перед вторым в финальном упорядочении (так выражение not comp(list[i+1],list[i]) будет истинным после сортировки). Если параметр comp не передан, то взамен Lua использует стандартный оператор < .
Алгоритм сортировки не стабилен; т.е. элементы, считающиеся равными в этом упорядочении, в результате сортировки могут изменить свои относительные позиции.
table.unpack (list [, i [, j]])
Возвращает элементы из полученного списка. Эта функция эквивалентна
По умолчанию, i = 1 и j = #list .
6.7 – Математические функции
Эта библиотека предоставляет базовые математические функции. Она предоставляет все свои функции и константы в таблице math . Функции с комментарием » integer/float » выдают целые результаты для целых аргументов и вещественные результаты для вещественных (или смешанных) аргументов. Функции округления ( math.ceil , math.floor и math.modf ) возвращают целое, когда результат помещается в диапазон целых, или вещественное иначе.
math.abs (x)
Возвращает абсолютное значение x . (integer/float)
math.acos (x)
Возвращает арккосинус x (в радианах).
math.asin (x)
Возвращает арксинус x (в радианах).
math.atan (y [, x])
Возвращает арктангенс y/x (в радианах), но использует знаки обоих параметров для поиска квадранта результата. (Также корректно обрабатывает случай, когда x = 0.)
По умолчанию x = 1, так вызов math.atan(y) возвращает арктангенс y .
math.ceil (x)
Возвращает наименьшее целое значение, которое больше или равно x .
math.cos (x)
Возвращает косинус x (в радианах).
math.deg (x)
Преобразует угол x из радиан в градусы.
math.exp (x)
Возвращает значение e x (где e — основание натурального логарифма).
math.floor (x)
Возвращает наибольшее значение, которое меньше или равно x .
math.fmod (x, y)
Возвращает остаток от деления x на y , который округляет частное к нулю. (integer/float)
math.huge
Вещественное значение HUGE_VAL , которое больше любого другого числового значения.
math.log (x [, base])
Возвращает логарифм x по основанию base . По умолчанию, base = e (так функция возвращает натуральный логарифм x ).
math.max (x, ···)
Возвращает аргумент с максимальным значением, в соответствии с Lua оператором < . (integer/float)
math.maxinteger
math.min (x, ···)
Возвращает аргумент с минимальным значением, в соответствии с Lua оператором < . (integer/float)
math.mininteger
math.modf (x)
Возвращает целую и дробную часть x . Второй результат всегда вещественное число.
math.pi
math.rad (x)
Преобразует угол x из градусов в радианы.
math.random ([m [, n]])
Когда вызвана без аргументов, возвращает псевдослучайное вещественное число с однородным распределением в диапазоне [0,1). Когда вызвана с двумя целыми m и n , math.random возвращает псевдослучайное целое с однородным распределением в диапазоне [m, n]. (Значение m-n не может быть отрицательным и должно помещаться в целое Lua.) Вызов math.random(n) эквивалентен вызову math.random(1,n) .
Эта функция является интерфейсом к генератору псевдослучайных чисел, предоставляемому C. Нет гарантий для его статистических свойств.
math.randomseed (x)
Устанавливает x как «затравку» (seed) для генератора псевдослучайных чисел: одинаковые затравки производят одинаковые последовательности чисел.
math.sin (x)
Возвращает синус x (в радианах).
math.sqrt (x)
Возвращает квадратный корень x . (Для вычисления этого значения вы также можете использовать выражение x^0.5 .)
math.tan (x)
Возвращает тангенс x (в радианах).
math.tointeger (x)
Если значение x можно преобразовать в целое, возвращает целое. Иначе, возвращает nil.
math.type (x)
Возвращает » integer » — если x целое, » float » — если x вещественное, или nil — если x не число.
math.ult (m, n)
Возвращает логическое значение, true, если целое m ниже целого n , когда они сравниваются как беззнаковые целые.
6.8 – Средства ввода-вывода
Библиотека ввода-вывода предоставляет два разных стиля для файловых манипуляций. Первый использует подразумевающиеся описатели файлов (handle); т.е. там есть операции установки файла ввода и файла вывода по умолчанию, и все операции ввода-вывода используют эти файлы. Второй стиль использует явные описатели файлов.
При использовании неявных описателей файлов, все операции предоставляются в таблице io . При использовании явных описателей, операция io.open возвращает описатель файла и затем все операции предоставляются, как методы этого описателя.
Таблица io также предоставляет три предопределенных файловых описателя с обычными значениями из C: io.stdin , io.stdout и io.stderr . Библиотека ввода-вывода никогда не закрывает эти файлы.
Пока не установлено иначе, все функции ввода-вывода возвращают nil при ошибке (и сообщение об ошибке, как второй результат, и зависящий от системы код ошибки, как третий) и отличное от nil значение при успехе. На не POSIX системах, формирование сообщения об ошибке и кода ошибки может не быть потокобезопасным, т.к. они полагаются на глобальную C переменную errno .
io.close ([file])
Эквивалентно file:close() . Без file , закрывает выходной файл по умолчанию.
io.flush ()
io.input ([file])
Когда вызвана с именем файла, открывает данный файл (в текстовом режиме), и устанавливает его описатель, как файл ввода по умолчанию. Когда вызвана с описателем файла, просто устанавливает этот описатель, как файл ввода по умолчанию Когда вызвана без параметров, возвращает текущий файл ввода по умолчанию.
В случае ошибок эта функция генерирует ошибку, вместо возвращения кода ошибки.
io.lines ([filename ···])
Открывает переданный файл в режиме чтения и возвращает функцию итератор, которая работает подобно file:lines(···) для открытого файла. Когда итератор доходит до конца файла, он ничего не возвращает (для завершения цикла) и автоматически закрывает файл.
Вызов io.lines() (без имени файла) эквивалентно io.input():lines(«*l») ; т.е. он перебирает линии файла ввода по умолчанию. В этом случае он не закрывает файл при завершении цикла.
В случае ошибок эта функция генерирует ошибку, вместо возвращения кода ошибки.
io.open (filename [, mode])
Функция открывает файл в режиме, определяемым строкой mode . Возвращает новый описатель файла, или, в случае ошибок, возвращает nil и сообщение об ошибке.
- » r «: режим чтения (по умолчанию);
- » w «: режим записи;
- » a «: режим добавления;
- » r+ «: режим обновления, все предыдущие данные сохраняются;
- » w+ «: режим обновления, все предыдущие данные стираются;
- » a+ «: режим добавления и обновления, предыдущие данные сохраняются, запись разрешена только в конец файла.
Строка mode также может содержать ‘ b ‘ в конце, это нужно на некоторых системах для открытия файла в бинарном режиме.
io.output ([file])
Подобно io.input , но для файла вывода по умолчанию.
io.popen (prog [, mode])
Эта функция зависит от системы и не доступна на некоторых платформах.
Запускает программу prog в отдельном процессе и возвращает описатель файла, который вы можете использовать для чтения данных из этой программы (если mode = «r» , по умолчанию) или для записи данных в программу (если mode = «w» ).
io.read (···)
io.tmpfile ()
Возвращает описатель для временного файла. Этот файл открывается в режиме обновления и автоматически удаляется по завершении программы.
io.type (obj)
Проверяет, что независимый obj это правильный описатель файла. Возвращает строку «file» — если obj открытый описатель файла, «closed file» — если obj закрытый описатель файла, или nil — если obj не является описателем файла.
io.write (···)
file:close ()
Закрывает file . Учтите, что файлы закрываются автоматически, когда их описатели собраны сборщиком мусора, но это может занять неопределенное количество времени.
Когда закрываемый описатель файла создан функцией io.popen , file:close возвращает те же значения, что и os.execute .
file:flush ()
Сохраняет все записанные данные в file .
file:lines (···)
Возвращает функцию итератор, которая при каждом вызове читает файл в соответствии с переданными форматами. Когда формат не передан, использует » l «, по умолчанию. Например, конструкция
будет перебирать все символы файла, начиная с текущей позиции. В отличие от io.lines , эта функция не закрывает файл после завершения цикла.
В случае ошибок эта функция генерирует ошибку, вместо возвращения кода ошибки.
file:read (···)
Читает файл file , в соответствии с переданными форматами, которые определяют, что читать. Для каждого формата, функция возвращает строку или число с прочитанными символами, или nil, если не может прочитать данные в этом формате. (В этом последнем случае, функция не читает последующие форматы.) Когда вызвана без форматов, использует по умолчанию формат, читающий следующую строку (см. ниже).
- » n «: читает число и возвращает его, как вещественное или целое, следуя лексическим соглашениям Lua. (Число может содержать начальные пробелы и знак.) Этот формат всегда читает самую длинную входную последовательность, которая является правильным префиксом для числа; если префикс не правильный (пустая строка, » 0x » или » 3.4e- «), он отбрасывается и функция возвращает nil.
- » a «: читает весь файл, начиная с текущей позиции. В конце файла возвращает пустую строку.
- » l «: читает следующую строку, пропуская символ конца строки, возвращает nil в конце файла. Это формат по умолчанию.
- » L «: читает следующую строку, сохраняя символ конца строки (если есть), возвращает nil в конце файла.
- число: читает строку этой длины в байтах, возвращает nil в конце файла. Если number = 0, ничего не читает и возвращает пустую строку, или nil в конце файла.
Форматы » l » и » L » должны использоваться только для текстовых файлов.
file:seek ([whence [, offset]])
- » set «: база на позиции 0 (начало файла);
- » cur «: база на текущей позиции;
- » end «: база в конце файла;
В случае успеха, seek возвращает окончательную позицию в файле, измеряемую в байтах от начала файла. При ошибке, возвращает nil и сообщение об ошибке.
По умолчанию whence = «cur» , offset = 0. Так вызов file:seek() возвращает текущую позицию, не изменяя её; вызов file:seek(«set») устанавливает позицию в начало файла (и возвращает 0); вызов file:seek(«end») устанавливает позицию в конец файла и возвращает размер файла.
file:setvbuf (mode [, size])
- » no «: без буферизации; результат любой операции вывода проявляется непосредственно.
- » full «: полная буферизация; операция вывода выполняется только, когда буфер полон или когда вы явно сбрасываете (flush) файл (см. io.flush ).
- » line «: строчная буферизация; выход буферизуется до новой строки в выводе или до любого ввода из специальных файлов (таких как терминал).
Для двух последних случаев size определяет размер буфера, в байтах. По умолчанию это подходящий размер.
file:write (···)
Записывает значение каждого аргумента в file . Аргументы должны быть строками или числами.
В случае успеха функция возвращает file . Иначе, возвращает nil и сообщение об ошибке.
6.9 – Средства операционной системы
Эта библиотека реализована через таблицу os .
os.clock ()
Возвращает апроксимацию количества секунд времени процессора, использованного программой.
os.date ([format [, time]])
Возвращает строку или таблицу, содержащую дату и время, отформатированную в соответствии с переданной строкой format .
Если аргумент time передан, то он является временем для форматирования (см. функцию os.time для описания этого значения). Иначе, date форматирует текущее время.
Если format начинается с символа ‘ ! ‘, то дата форматируется во всемирном координированном времени (UTC). После этого опционального символа, если format это строка » *t «, то date возвращает таблицу со следующими полями: year — год (четыре цифры), month — месяц (1–12), day — день (1–31), hour — час (0–23), min — минута (0–59), sec — секунда (0–61), wday — день недели (воскресенье = 1), yday — день в году и isdst — летнее время (boolean). Это последнее поле может отсутствовать, если информация недоступна.
Если format не » *t «, то date возвращает дату как строку, форматированную согласно правилам C функции strftime .
Когда вызвана без аргументов, date возвращает разумное представление даты и времени, зависящее от хостовой системы и текущей локали (т.е. os.date() эквивалентно os.date(«%c») ).
На не POSIX системах эта функция может не быть потокобезопасной, т.к. она использует C функции gmtime и localtime .
os.difftime (t2, t1)
Возвращает разницу, в секундах, от времени t1 до времени t2 (где значения времени возвращены os.time ). В POSIX, Windows и некоторых других системах это значение точно t2 — t1 .
os.execute ([command])
- » exit «: команда завершена нормально; следующее число это выходной статус команды.
- » signal «: команда была завершена сигналом; следующее число это сигнал, завершивший команду.
Когда вызвана без command , os.execute возвращет логическое значение, которое равно true, если оболочка (shell) доступна.
os.exit ([code [, close]])
Вызывает ISO C функцию exit для завершения хостовой программы. Если code = true, возвращается статус EXIT_SUCCESS ; если code = false, возвращается статус EXIT_FAILURE ; если code это число, возвращается статус равный этому числу. По умолчанию, code = true.
Если опциональный второй аргумент close = true, закрывает Lua состояние перед выходом.
os.getenv (varname)
Возвращает значение переменной окружения процесса varname , или nil, если переменная не определена.
os.remove (filename)
Удаляет файл (или пустую директорию, на POSIX системах) с переданным именем. Если функция терпит неудачу, она возвращает nil, сообщение об ошибке и код ошибки.
os.rename (oldname, newname)
Переименовывает файл или директорию oldname в newname . Если функция терпит неудачу, она возвращает nil, сообщение об ошибке и код ошибки.
os.setlocale (locale [, category])
Устанавливает текущую локаль для программы. locale — системозависимая строка, определяющая локаль; category — опциональная строка, описывающая какую категорию изменять: «all» , «collate» , «ctype» , «monetary» , «numeric» или «time» ; по умолчанию category = «all» . Функция возвращает имя новой локали, или nil, если запрос не может быть выполнен.
Если locale это пустая строка, текущая локаль устанавливается в засимую от реализации родную локаль. Если locale это строка » C «, текущая локаль устанавливается в стандартную C локаль.
Когда вызвана с nil в качестве первого аргумента, эта функция только возвращает имя текущей локали для данной категории.
Эта функция может не быть потокобезопасной, т.к. использует C функцию setlocale .
os.time ([table])
Возвращает текущее время, когда вызвана без аргуменов, или время, представляющее локальную дату и время определенные в переданной таблице. Эта таблица должна иметь поля year , month и day , и может иметь поля hour (по умолчанию, 12), min (по умолчанию, 0), sec (по умолчанию, 0) и isdst (по умолчанию, nil). Остальные поля игнорируются. Для описания этих полей, см. функцию os.date .
Значения этих полей могут не быть в своих правильных диапазонах. Например, если sec = -10, то это означает -10 секунд от времени, определенного другими полями; если hour = 1000, это означает +1000 часов от времени, определенного другими полями.
Возвращенное значение это число, значение которого зависит от вашей системы. В POSIX, Windows и некоторых других системах это количество секунд, прошедших с какого-то определенного времени («эпоха»). В других системах, значение не определено, и число, возвращенное функцией time , может использоваться только, как аргумент для os.date и os.difftime .
os.tmpname ()
Возвращает строку с именем файла, который может быть использован, как временный. Файл должен быть явно открыт перед использованием и явно удален, когда больше не нужен.
На POSIX системах эта функция также создает файл с этим именем, для избежания рисков беззопасности. (Кто-нибудь другой может создать файл с неправильными разрешениями в промежуток времени между получением имени файла и его созданием.) Вы по прежнему должны открыть файл для его использования и удалить его (даже если не использовали).
Когда возможно, предпочтительно использовать функцию io.tmpfile , которая автоматически удаляет файл при завершении программы.
6.10 – Библиотека отладки
Эта библиотека предоставляет Lua программам функциональность отладочного интерфейса (§4.9). Используя эту библиотеку, вы должны проявлять внимательность. Различные функции этой билиотеки нарушают базовые предположения о Lua коде (например, что локальные переменные функции не могут быть доступны снаружи; что метатаблицы пользовательских данных не могут изменяться Lua кодом; что Lua программы не падают) и следовательно могут скомпрометировать защищенный код. Кроме того, некоторые функции в этой библиотеке могут быть медленными.
Все функции в этой библиотеке предоставляются в таблице debug . Все функции, которые оперируют с потоком, имеют опциональный первый аргумент, определяющий поток. По умолчанию, это всегда текущий поток.
debug.debug ()
Входит в интерактивный режим с пользователем, запуская каждую строку, вводимую пользователем. Используя простые команды и другие отладочные возможности, пользователь может проверять глобальные и локальные переменные, изменять их значения, вычислять выражения и т.д. Строка, содержащая только слово cont , завершает эту функцию, так что вызывающий продожает своё исполнение.
Учтите, что команды для debug.debug не являются лексически вложенными ни в одну функцию и не имеют прямого доступа к локальным переменным.
debug.gethook ([thread])
Возвращает настройки текущего перехватчика потока, как три значения: текущая функция-перехватчик, текущая маска перехвата и текущий счетчик перехвата (как установлено функцией debug.sethook ).
debug.getinfo ([thread,] f [, what])
Возвращает таблицу с информацией о функции. Вы можете передать функцию напрямую или можете передать число, как значение f , которое означает функцию, выполняющуюся на уровне f стека вызовов данного потока thread: уровень 0 — текущая функция (непосредственно getinfo ); уровень 1 — функция, которая вызвала getinfo (за исключением хвостовых вызовов, которые не считаются на стеке); и так далее. Если число f больше количества активных функций, то getinfo возвращает nil.
Возвращенная таблица может содержать все поля возвращаемые lua_getinfo , со строкой what , описывающей какие поля заполнены. По умолчанию, what установлена для получения всей доступной информации, кроме таблицы значимых строк. Если передана, опция ‘ f ‘ добавляет поле func с функцией непосредственно. Если передана, опция ‘ L ‘ добавляет поле activelines с таблицей значимых строк.
Например, выражение debug.getinfo(1,»n»).name возвращает имя текущей функции, если разумное имя существует, и выражение debug.getinfo(print) возвращает таблицу со всей доступной информацией о функции print .
debug.getlocal ([thread,] f, local)
Эта функция возвращает имя и значение локальной переменной с индексом local функции на уровне f стека вызовов. Эта функция получает доступ не только к явным локальным переменным, но также к параметрам, временным переменныи и др.
Первый параметр или локальная переменная имеет индекс 1, и так далее, следуя порядку определения в коде, считаются только активные переменные в текущей области функции. Отрицательные индексы ссылаются на переменные (vararg) параметры; -1 первый переменный параметр. Функция возвращает nil, если нет переменной по данному индексу, и вызывает ошибку, когда вызвана с уровнем за пределами диапазона. (Вы можете вызвать debug.getinfo чтобы проверить, какой уровень допустим.)
Имена переменных, начинающиеся с ‘ ( ‘ (открывающая скобка) представляют переменные с неизвестными именами (внутренние переменные, такие как переменные управления циклом, и переменные из кусков, сохраненных без отладочной информации).
Параметр f также может быть функцией. В этом случае getlocal возвращает только имена параметров функции.
debug.getmetatable (value)
Возвращает метатаблицу переданного значения value или nil, если у значения нет метатаблицы.
debug.getregistry ()
Возвращает таблицу реестра (см. §4.5).
debug.getupvalue (f, up)
Эта функция возвращает имя и значение upvalue с индексом up функции f . Функция возвращает nil, если по данному индексу нет upvalue.
Имена переменных, начинающиеся с символа ‘ ( ‘ (открывающая скобка) , представляют переменные с неизвестными именами (переменные из кусков, сохраненных без отладочной информации).
debug.getuservalue (u)
Возвращает Lua значение, ассоциированное с u . Если u не пользовательские данные, возвращает nil.
debug.sethook ([thread,] hook, mask [, count])
- ‘ c ‘: перехватчик вызывается каждый раз, когда Lua вызывает функцию;
- ‘ r ‘: перехватчик вызывается каждый раз, когда Lua возвращается из функции;
- ‘ l ‘: перехватчик вызывается каждый раз, когда Lua входит на новую линию кода.
Кроме того, с count не равным нулю, перехватчик вызывается также через каждые count инструкций (count в значении «количество»).
Когда вызвана без аргументов, debug.sethook выключает перехват.
Когда вызван перехватчик, его первый параметр — это строка, описывающая событие, которое стало причиной вызова перехватчика: «call» (или «tail call» ), «return» , «line» и «count» . Для событий строк, перехватчик также получает номер строки во втором параметре. Внутри перехватчика вы можете вызвать getinfo с уровнем 2 для получения информации о запущенной функции (уровень 0 — это функция getinfo , уровень 1 — это функция-перехватчик).
debug.setlocal ([thread,] level, local, value)
Эта функция присваивает значение value локальной переменной по индексу local функции на уровне level в стеке вызовов. Функция возвращает nil, если локальная переменная с данным индексом не существует, и генерирует ошибку, когда вызвана с level вне диапазона. (Вы можете использовать getinfo чтобы проверить какой уровень допустим.) Иначе, возвращает имя локальной переменной.
См. debug.getlocal для дополнительной информации о именах и индексах переменных.
debug.setmetatable (value, table)
Устанавливает table метатаблицей для value ( table может быть равно nil). Возвращает value .
debug.setupvalue (f, up, value)
Эта функция присваивает значение value в upvalue с индексом up функции f . Функция возвращает nil, если по данному индексу нет upvalue. Иначе, возвращает имя upvalue.
debug.setuservalue (udata, value)
Устанавливает переданное значение value , как Lua значение, ассоциированное с udata . udata должно быть полными пользовательскими данными.
debug.traceback ([thread,] [message [, level]])
Если message передано, но не строка и не nil, эта функция возвращет message без дальнейшей обработки. Иначе, возвращает строку с трассировкой стека вызовов. Опциональная строка message добавляется в начале трассировки стека. Опциональное число level говорит, на каком уровне начинать трассировку (по умолчанию равен 1 — функция, вызвавшая traceback ).
debug.upvalueid (f, n)
Возвращает уникальный идентификатор (как лёгкие пользовательские данные) для upvalue под номером n из переданной функции.
Эти уникальные идентификаторы позволяют программе проверить, когда разные замыкания совместно используют одни upvalue. Lua замыкания, которые совместно используют upvalue (т.е. имеют доступ к одной внешней локальной переменной) вернут одинаковые идентификаторы для этих upvalue.
debug.upvaluejoin (f1, n1, f2, n2)
Заставляет n1 -е upvalue Lua замыкания f1 ссылаться на n2 -е upvalue Lua замыкания f2 .
7 – Интерпретатор Lua
Хотя Lua был разработан, как язык расширений, чтобы встраивать в хостовую C программу, он также часто используется, как автономный язык. Интерпретатор Lua, как автономного языка, называется просто lua и предоставляется в стандартном дистрибутиве. Автономный интерпретатор включает все стандартные библиотеки, в том числе отладочную библиотеку. Синтаксис командной строки:
- -e stat : запускает строку stat;
- -l mod : загружает (require) mod;
- -i : входит в интерактивный режим после запуска script;
- -v : печатает информацию о версии;
- -E : игнорирует переменные окружения;
- — : останавливает обработку опций;
- — : запускает stdin как файл и останавливает обработку опций.
После обработки опций, lua запускает переданный скрипт (script). Когда вызван без аргументов, lua ведет себя, как lua -v -i , когда стандартный ввод ( stdin ) это терминал; и как lua — иначе.
Когда вызван без опции -E , интерпретатор проверяет переменную окружения LUA_INIT_5_3 (или LUA_INIT , если предыдущая не определена) перед запуском аргументов. Если содержимое переменной имеет формат @filename , то lua запускает это файл. Иначе, lua запускает непосредственно эту строку.
Когда запущен с опцией -E , вместе с игнорированием LUA_INIT , Lua также игнорирует значения LUA_PATH и LUA_CPATH , устанавливая значения package.path и package.cpath путями по умолчанию, определенными в luaconf.h .
Все опции обрабатываются по порядку, кроме -i и -E . Например, вызов
сначала установит a = 1, затем напечатает значение a , и наконец запустит файл script.lua без аргументов. (Здесь $ — это приглашение командной строки. Ваше приглашение может отличаться.)
Перед запуском любого кода lua собирает все аргументы командной строки в глобальной таблице arg . Имя скрипта идет под индексом 0, первый аргумент после имени скрипта идет по индексу 1, и т.д. Все аргументы перед именем скрипта (т.е имя интерпретатора и его опции) находятся по отрицательным индексам. Например, вызов
Если в вызове нет скрипта, имя интерпретатора идет по индексу 0, далее идут другие аргументы. Например, вызов
напечатает » -e «. Если есть скрипт, то он вызывается с параметрами arg[1] , ···, arg[#arg] . (Как все куски в Lua, скрипт компилируется, как функция с переменным числом аргументов.)
В интерактивном режиме, Lua многократно выдает приглащение и ждет ввода строки. После ввода строки, Lua сначала пробует интерпретировать строку как выражение. В случае успеха, печатает её значение. Иначе, интерпретирует строку как оператор. Если вы напишете незавершенное выражение, интерпретатор будет ждать его завершения, выдывая приглашение.
В случае незащищенных ошибок в скрипте, интерпретатор пишет ошибку в стандартный поток ошибок. Если объект ошибки это не строка, но имеет метаметод __tostring , интерпретатор вызывает этот метаметод для выдачи финального сообщения. Иначе, интерпретатор конвертирует объект ошибки в строку и добавляет к нему трассировку стека.
При нормальном завершении интерпретатор закрывает своё главное Lua состояние (см. lua_close ). Скрипт может избежать этого шага, вызвав os.exit для завершения.
Чтобы использовать Lua, как интерпретатор скриптов в Unix системах, автономный интерпретатор пропускает первую линию куска, если он начинается с символа # . Следовательно, Lua скрипты могут быть сделаны исполняемыми программами, используя chmod +x и #! форму, например
(Конечно, расположение Lua интерпретатора может быть другим. Если lua в вашей переменной PATH , то
более портабельное решение.)
8 – Несовместимости с предыдущей версией
Здесь приведен список несовместимостей, которые вы можете встретить при портировании программы с Lua 5.2 в Lua 5.3. Вы можете избежать некоторые несовместимости, скомпилировав Lua с соответствующими опциями (см. файл luaconf.h ). Тем не менее, все эти опции совметимости будут убраны в будущем.
Версии Lua всегда могут изменить C API способами, которые не подразумевают изменение исходного кода программы, такие, как цифровые значения констант или реализация функций через макросы. Следовательно, вы не должны ожидать бинарной совметимости между разными версиями Lua. Всегда перекомпилируйте клиентов Lua API, когда используете новую версию.
Аналогично, версии Lua всегда могут изменить внутреннее представление скомпилированных кусков; скомпилированные куски не совместимы между разными версиями Lua.
Стандартные пути в официальном дистрибутиве могут меняться между версиями.
8.1 – Изменения в языке
- Главное различие между Lua 5.2 и Lua 5.3 это введение подтипа целых для чисел. Хотя это изменение не влияет на «нормальные» вычисления, некоторые вычисления (главным образом это некоторые типы переполнений) могут давать разные результаты.
8.2 – Изменения в библиотеках
- Библиотека bit32 стала нежелательной. Легко загрузить совместимую внешнюю библиотеку или лучше заменить её функции соответствующими битовыми операторами. (Помните, что bit32 оперирует с 32-битными целыми, а битовые операторы Lua 5.3 оперируют с целыми Lua, которые по умолчанию имеют 64 бита.)
- Табличная библиотека теперь уважает метаметоды для установки и получения элементов.
- Итератор ipairs теперь уважает метаметоды и его метаметод __ipairs стал нежелательным.
- Имена опций в io.read больше не имеют начального символа ‘ * ‘. Для совместимости Lua продолжит принимать (и игнорировать) этот символ.
- Следующие функции стали нежелательными в математической библиотеке: atan2 , cosh , sinh , tanh , pow , frexp и ldexp . Вы можете заменить math.pow(x,y) на x^y ; вы можете заменить math.atan2 на math.atan , который теперь принимает один или два параметра; вы можете заменить math.ldexp(x,exp) на x * 2.0^exp . Для других операций вы можете также использовать внешнюю библиотеку или реализовать их в Lua.
- Искатель для C загрузчиков, используемый require , изменил способ обработки имен с версиями. Сейчас версия должна идти после имени модуля (как обычно в большинстве других инструментов). Для совместимости, этот искатель все еще пытается использовать старый формат, если не может найти функцию открытия соответствующую новому стилю. (Lua 5.2 уже работает таким способом, но это не документировано.)
- Вызов collectgarbage(«count») сейчас возвращает только один результат. (Вы можете вычислить второй результат из дробной части первого результата.)
8.3 – Изменения в API
- Функции продолжения сейчас принимают как параметры то, что им нужно было получать через lua_getctx , так функция lua_getctx была удалена. Откорректируйте ваш код соответственно.
- Функция lua_dump имеет дополнительный параметр strip . Используйте 0 для этого параметра, чтобы получить старое поведение.
- Функции для вставки/получения беззнаковых целых ( lua_pushunsigned , lua_tounsigned , lua_tounsignedx , luaL_checkunsigned , luaL_optunsigned ) нежелательны. Используйте их знаковые эквиваленты с преобразованием типа.
- Макросы для получения нестандартных целых типов ( luaL_checkint , luaL_optint , luaL_checklong , luaL_optlong ) нежелательны. Используйте их эквиваленты с lua_Integer с преобразованием типов (или, когда возможно, используйте lua_Integer в вашем коде).
9 – Полный синтаксис Lua
Здесь приведен полный синтаксис Lua в БНФ. Как обычно в расширенной БНФ, означает 0 или более A, и [A] означает опциональное A. (Для приоритета операторов, см. §3.4.8; для описания терминалов Name, Numeral и LiteralString, см. §3.1.)
Last update: Wed Jun 10 18:31:15 BRT 2015 Last change: revised for Lua 5.3.1
Простой гайд: как настроить Visual Studio Code для запуска Lua файлов
Visual Studio Code (VS Code) — это популярный текстовый редактор, который обладает множеством возможностей и предоставляет удобную среду разработки для многих языков программирования, включая Lua. В данной статье мы расскажем, как настроить VS Code для запуска Lua файлов.
Шаг 1: Установка Visual Studio Code
Первым шагом является установка Visual Studio Code. Вы можете скачать его с официального веб-сайта https://code.visualstudio.com/ и установить на свой компьютер, следуя инструкциям, предоставляемым установщиком.
Шаг 2: Установка расширения для поддержки языка Lua
После установки IDE Visual Studio Code необходимо установить расширение для поддержки языка программирования Lua. Для этого следуйте инструкциям ниже:
- Откройте IDE Visual Studio Code.
- Нажмите на значок "Extensions" в боковой панели слева (или используйте комбинацию клавиш Ctrl+Shift+X ).
- Введите "Lua" в строке поиска и выберите расширение "Lua" от компании "sumneko".
- Нажмите кнопку "Install", чтобы установить расширение.
Шаг 3: Создание и настройка конфигурации запуска
Теперь, когда у нас есть установленное расширение Lua, мы можем настроить конфигурацию запуска Lua файлов. Это позволит нам запускать и отлаживать Lua-приложения из состава Visual Studio Code. Следуйте инструкциям ниже:
- Откройте панель "Run and Debug" в Visual Studio Code (или используйте комбинацию клавиш Ctrl+Shift+D ).
- Нажмите на значок с шестеренкой "Create a launch.json file". Если файл конфигурации уже создан, пропустите этот шаг.
- В появившемся выпадающем меню выберите тип "Lua".
- В открывшемся файле launch.json укажите путь к своему Lua-файлу в секции "program".
Шаг 4: Запуск и отладка Lua-файлов
Теперь, когда все настройки завершены, мы готовы запускать и отлаживать Lua-файлы. Следуйте инструкциям ниже:
- Откройте Lua-файл, который вы хотите запустить или отладить.
- Нажмите клавишу F5 или выберите "Start Debugging" в меню "Run and Debug".
- Ваш Lua-файл будет запущен, и вы сможете отслеживать выполнение кода, устанавливать точки останова и использовать другие инструменты отладки.
Заключение
Поздравляем! Вы успешно настроили Visual Studio Code для запуска и отладки Lua-файлов. Теперь вы можете наслаждаться удобством разработки на языке Lua в одной из самых популярных сред разработки.
1 – Getting Started
To keep with the tradition, our first program in Lua just prints «Hello World» : If you are using the stand-alone Lua interpreter, all you have to do to run your first program is to call the interpreter (usually named lua ) with the name of the text file that contains your program. For instance, if you write the above program in a file hello.lua , the following command should run it:
As a slightly more complex example, the following program defines a function to compute the factorial of a given number, asks the user for a number, and prints its factorial:
Lua 5.3 Руководство
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
перевел Ведерников Николай, Лысьва.
1 – Введение
Lua — язык программирования расширений, разработан для поддержки общего процедурного программирования с возможностью описания данных. Lua также предлагает хорошую поддержку объектно-ориентированного, функционального и управляемого данными (data-driven) программирования. Lua предлагается как мощный и лёгкий встраиваемый скриптовый язык для любой программы, которая в этом нуждается. Lua реализован как библиотека, написан на чистом C, общее подмножетво стандартного C и C++.
Как язык расширений, Lua не имеет понятия «главной» программы: он работает только как встроенный в основную программу клиент, встраивающая программа называется хост (host). Встраивающая программа может вызывать функции для запуска кусочков Lua кода, может писать и читать Lua переменные, может регистрировать C-функции чтобы вызывать их из Lua кода. Через использование С-функций Lua может быть расширен для решения различных задач, таким образом созданные адаптированные языки программирования имеют общую синтаксическую базу. Дистрибутив Lua включает простую хост-программу lua , которая использует библиотеку Lua для реализации полного независимого Lua интерпретатора, для интерактивного или пакетного использования.
Lua бесплатное программное обеспечение и предоставляется безо всяких гарантий. Официальный сайт www.lua.org .
Как и любое другое руководство, это руководство местами сухо. Описание решений принятых в основе дизайна Lua есть на технических страницах официального сайта. Детальное введение в программирование на Lua представлено в книге Роберто Иерусалимского Programming in Lua.
2 – Базовые концепции
Этот раздел описывает базовые концепции языка.
2.1 – Значения и типы
Lua динамически типизированный язык. Это означает, что значения не имеют типов; только значения. Язык не имеет определений типов. Все значения несут свой собственный тип.
Все значения в Lua первоклассные. Это означает что все значения могут быть сохранены в переменных, переданы как аргументы другим функциям, и возвращены как результаты.
В Lua существует восемь базовых типов: nil, boolean, number, string, function, userdata, thread и table.
Тип nil (нуль) имеет одно единственное значение, nil, его главное свойство это отличаться от любых других значений; обычно это означает отсутствие используемого значения.
Тип boolean (логический) имеет два значения: false (ложь) и true (истина). Оба nil и false означают false; любое другое значение означает true.
Тип number (число) представляет целые (integer) и вещественные (float) числа.
Тип string (строка) представляет неизменные последовательности байт. Строки в Lua могут содержать любое 8-битное значение, включая нули (‘ \0 ‘). Также Lua противник кодировок; никаких предположений о содержимом строки не делается.
Тип number использует два внутренних представления, или два подтипа, один называется integer (целое), второй float (число с плавающей запятой). Lua имеет явные правила о том, когда какое представление использовать, но при необходимости автоматически конвертирует значение между ними (см. §3.4.3). Следовательно, в большистве случаев программист может игнорировать разницу между целыми и реальными числами, или получить полный контроль над представлением каждого числа. Стандартный Lua использует 64-битные целые (integer) и вещественные числа двойной точности (double 64-bit), но также возможно скомпилировать Lua так, чтобы использовались 32-битные целые и/или вещественные числа одинарной точности (float 32-bit). Эта опция с 32 битами для целых и вещественных чисел особенно актуальна для малых машин и встроенных систем. (Смотри макрос LUA_32BITS в файле luaconf.h .)
Lua может вызывать и манипулировать функциями написанными на Lua и на С (см. §3.4.10). Оба типа функций в Lua представлены типом function (функция).
Тип userdata (пользовательские данные) предназначен для хранения произвольных С данных в Lua переменных. Значение userdata представляет блок памяти (raw memory). Существуют два типа пользовательских данных: full userdata (полные пользовательские данные) — объект с блоком памяти, которым управляет Lua, и light userdata (лёгкие пользовательские данные) — простой С указатель. Пользовательские данные не имеют предопределенных операторов в Lua, кроме оператора присвоения и сравнения на идентичность. Используя метатаблицы, программист может определить операции для значений full userdata (см. §2.4). Значения userdata не могут быть созданы или изменены в Lua, это возможно только через C API. Это гарантирует целостность данных, которыми владеет хост-программа.
Тип thread (поток) представляет независимый поток выполнения и используется для реализации сопрограмм (coroutine) (см. §2.6). Lua потоки это не реальные потоки операционной системы. Lua поддерживает сопрограммы на всех системах, даже на тех, где это не поддерживается операционной системой.
Тип table (таблица) реализует ассоциативные массивы, это значит, что массив может быть проиндексирован не только числами, но и любым Lua значением, кроме nil и NaN. (Not a Number специальное значение для представления неопределенных и непредставимых числовых результатов, таких как 0/0 .) Таблицы могут быть гетерогенными (разнородными); т.е. могут содержать значения всех типов (кроме nil). Любой ключ со значением nil не считается частью таблицы. И наоборот, любой ключ, не являющийся частью таблицы, имеет ассоциированное значение nil.
Таблицы единственный механизм структурирования данных в Lua; они могут использоваться для представления обычных массивов, последовательностей, таблиц символов, множеств, записей, графов, деревьев и т.п. Для представления записей, Lua использует имена полей как индекс. Язык поддерживает представление a.name , как синтаксическое украшение a[«name»] . Существуют различные пути создания таблиц в Lua (см. §3.4.9).
Мы используем термин последовательность (sequence) чтобы обозначить таблицу, где все ключи это натуральные числа <1..n> (1,2,3. ), где n — длина последовательности (см. §3.4.7).
Как и индексы, значения полей в таблице могут быть любого типа. В частности, т.к. функции это первоклассные значения, поля таблицы могут содержать функции. Такие таблицы также могут содержать методы (см. §3.4.11).
Индексирование в таблицах следует принципу «сырого» (raw) равенства в языке. Выражения a[i] и a[j] определяют один и тот же элемент таблицы, если и только если i и j равны (raw equal) (значит, равны без метаметодов). В частности, вещественные числа (float) с целыми значениями равны соответствующим целым (integer), т.е., 1.0 == 1 . Во избежание неоднозначностей, любое реальное число с целым значением, которое испльзуется как ключ, конвертируется в соответствующее ему целое число. Например, если написать a[2.0] = true , фактически в таблицу будет вставлен целочисленный (integer) ключ 2 . С другой стороны, 2 and » 2 » разные Lua значения и следовательно обозначают разные данные в таблице.
Таблицы, функции, потоки и пользовательские данные (userdata) — это объекты: переменные фактически не содержат их значений, только ссылки на них. Присвоение, передача параметров и возврат из функций всегда манипулируют ссылками на эти значения; эти операции не подразумевают никакого типа копирования.
Библиотечная функция type возвращает строку с названием переданного ей типа (см. §6.1).
2.2 – Окружения и глобальное окружение
Как будет описано в §3.2 и §3.3.3, любая ссылка на свободное имя (т.е., имя не связанное ни с каким определением) var синтаксически транслируется в _ENV.var . Кроме того, каждый кусок (chunk) компилируется в области внешней локальной переменной, называемой _ENV (см. §3.3.2), таким образом _ENV само никогда не бывает свободным именем в куске.
Несмотря на существование этой внешней переменной _ENV и трансляцию свободных имен, _ENV полностью регулярное имя. В частности, вы можете определить новые переменные и параметры с этим именем. Каждая ссылка на свободное имя использует _ENV , которая видима в данной точке программы, следуя обычным правилам видимости Lua (см. §3.5).
Любая таблица, используемая как значение переменной _ENV , называется окружение (environment).
Lua хранит особое окружение, называемое глобальное окружение. Это значение хранится по специальному индексу в С реестре (см. §4.5). В Lua, глобальная переменная _G инициализируется тем же значением. ( _G никогда не используется непосредственно.)
Когда Lua загружает кусок (chunk), по умолчанию его _ENV upvalue присваивается значение глобального окружения (см. load ). Следовательно, по умолчанию, свободные имена в Lua коде ссылаются на элементы в глобальном окружении (и, следовательно, они также называются глобальными переменными). Кроме того, все стандартные библиотеки загружаются в глобальное окружение и некоторые их функции действуют в этом окружении. Вы можете использовать load (или loadfile ) для загрузки куска с другим окружением. (В C, вы загружаете кусок и затем изменяете его первое upvalue.)
2.3 – Обработка ошибок
Так как Lua встроенный язык расширений, все Lua действия начинаются с C кода; код в хостовой программе вызывает функцию в Lua библиотеке. (При использовании автономного интерпретатора Lua, программа lua выступает в качестве хоста.) Всякий раз, когда происходит ошибка компиляции или выполнения куска Lua кода, управление возвращается хостовой программе, которая может предпринять соответствующие меры (такие как печать сообщения об ошибке).
Lua код может явно сгенерировать ошибку, вызвав функцию error . Если вы нуждаетесь в перехвате ошибок в Lua, вы можете использовать pcall или xpcall для вызова функции в защищенном режиме.
При каждой ошибке, создается объект ошибки (также называемый сообщением об ошибке) с информацией об ошибке. Самостоятельно Lua генерирует только те ошибки, где объект ошибки содержит строку, но программы могут генерировать ошибки с любым значением в объекте ошибки. Объекты ошибки (исключения) пробрасываются вверх в Lua или в хост для обработки.
Когда вы используете xpcall или lua_pcall , вы можете определить обработчик сообщений, который будет вызываться в случае ошибок. Эта функция вызывается с оригинальным сообщением об ошибке и возвращает новое сообщение об ошибке. Она вызывается до раскрутки стека, так она сможет получить больше информации об ошибке, например, проверяя стек и создавая историю стека (stack traceback). Этот обработчик сообщений остается защищенным в защищенном вызове; так, ошибка в обработчике сообщений лишь вызовет его снова. Если этот цикл будет достаточно длинным, Lua прервет его и вернет соответствующее сообщение.
2.4 – Метатаблицы и метаметоды
Каждое значение в Lua может иметь метатаблицу. Эта метатаблица обычная Lua таблица, которая определяет поведение оригинального значения в определенных специальных операциях. Вы можете изменять различные аспекты поведения в операциях со значением, изменяя специфические поля в метатаблице. Например, когда не цифровое значение является операндом в сложении, Lua проверяет есть ли в его метатаблице поле » __add » с функцией. И, если оно существует, Lua вызывает эту функцию для выполнения сложения.
Ключи в метатаблице это производные от имен событий; соответствующие им значения называются метаметоды. В предыдущем примере, событие — «add» (добавить) и метаметод — функция, которая выполняет сложение.
Вы можете запросить метатаблицу любого значения, используя функцию getmetatable .
Вы можете заменить метатаблицу таблицы, используя setmetatable . Нельзя изменять метатаблицы других типов из Lua кода (кроме, как используя библиотеку отладки (§6.10)); для этого вы должны использовать C API.
Таблицы и полные пользовательские данные (full userdata) имеют индивидуальные метатаблицы (хотя таблицы и пользовательские данные могут совместно использовать свои метатаблицы). Значения остальных типов используют одну метатаблицу на тип; т.е, существует одна метатаблица для всех чисел, одна для всех строк и т.д. По умолчанию, значения не имеют метатаблицу, но строковая библиотека создает метатаблицу для строкового типа (см. §6.4).
Метатаблица контролирует, как объект ведет себя в арифметических и битовых операциях, сравнениях при сортировке, конкатенации, определении длины, вызовах и индексировании. Метатаблица также может определять функцию, которая будет вызвана для таблицы или пользовательских данных при уничтожении сборщиком мусора (§2.5).
Детальное описание событий, контролируемых метатаблицами, представлено ниже. Каждая операция идентифицируется соответсвующим именем события. Ключ для каждого события это строка начинающаяся с двух подчеркиваний, ‘ __ ‘; например, ключ для операции «add» строка » __add «. Имейте ввиду, что запросы метаметодов всегда прямые; доступ к метаметоду не запускает других метаметодов
- «add»: + операция. Если любой операнд при сложении не число (и не строка, которую можно преобразовать в число), Lua попробует вызвать метаметод. Сначала, Lua проверит первый операнд (даже если он правильный). Если этот операнд не определяет метаметод для события » __add «, Lua проверит второй операнд. Если Lua найдет метаметод, он будет вызван с двумя операндами в качестве аргументов, и результат вызова (скорректированный до одного значения) будет результатом операции. Иначе будет сгенерирована ошибка.
- «sub»: — операция (вычитание). Аналогично операции «add».
- «mul»: * операция (умножение). Аналогично операции «add».
- «div»: / операция (деление). Аналогично операции «add».
- «mod»: % операция (остаток от деления). Аналогично операции «add».
- «pow»: ^ операция (возведение в степень). Аналогично операции «add».
- «unm»: — операция (одноместный минус). Аналогично операции «add».
- «idiv»: // операция (целочисленное деление). Аналогично операции «add».
- «band»: & операция (битовое И). Аналогично операции «add», за исключением того, что Lua будет использовать метаметод, если любой из операндов не целое и не значение приводимое к целому (см. §3.4.3).
- «bor»: | операция (битовое ИЛИ). Аналогично операции «band».
- «bxor»:
Как и для индексированного доступа, метаметод для этого события может быть функцией или таблицей. Если это функция, то она вызывается с table , key и value в качестве аргументов. Если таблица, Lua производит индексированное присваивание для этой таблицы с тем же ключом и значением. Это присваивание регулярное, не прямое, и оно также может вызывать срабатывание другого метаметода.
Хорошая практика, добавлять все необходимые метаметоды в таблицу перед тем, как назначить её метатаблицей какого-то объекта. В частности, метаметод » __gc » работает только если была соблюдена эта последовательность (см. §2.5.1).
2.5 – Сборка мусора
Lua выполняет автоматическое управление памятью. Это означает, что вы не должны беспокоиться о выделении памяти новым объектам или об освобождении памяти, когда объекты больше не нужны. Lua управляет памятью, запуская сборщик мусора для сборки всех мёртвых объектов (т.е., объектов более не доступных из Lua). Вся память, используемая Lua, подлежит автоматическому управлению: строки, таблицы, пользовательские данные, функции, потоки, внутренние структуры и т.д.
Lua реализует пошаговый отмечающий-и-очищающий сборщик. Для контроля циклов очистки мусора используются два числа: пауза сборщика мусора и множитель шагов сборщика мусора. Оба числа используют процентные пункты как единицы (т.е., значение 100 означает внутреннее значение 1).
Пауза сборщика мусора контролирует, как долго сборщик ждет перед началом нового цикла. Чем больше значение, тем менее агрессивен сборщик. Значения меньше 100 означают, что сборщик не останавливается перед началом нового цикла. Значение 200 означает, что сборщик, перед тем как начать новый цикл, ждет повышения использования общей памяти в два раза.
Множитель шагов сборщика мусора контролирует относительную скорость сборщика по отношению к скорости выделения памяти. Большие значения делают сборщик более агрессивным, но также увеличивают размер каждого шага. Вы не должны использовать значения меньше 100, т.к. они сделают сборщик настолько медленным, что он никогда не завершит цикл. По умолчанию, используется значение 200, которое означает, что сборщик выполняется в два раза быстрее скорости выделения памяти.
Если вы установите множитель шагов очень большым (больше чем 10% от максимального числа байт, которые может использовать программа), сборщик поведет себя как останавливающий мир. Если вы установите паузу 200, сборщик будет вести себя как в старых версиях Lua, производя полную очистку каждый раз, когда Lua удваивает использование памяти.
Вы можете изменять эти числа, вызывая lua_gc в C или collectgarbage в Lua. Вы также можете использовать эти функции для прямого контроля сборщика (т.е., его остановки и перезапуска).
2.5.1 – Метаметоды сборки мусора
Вы можете установить метаметоды сборки мусора для таблиц и, используя C API, для полных пользовательских данных (см. §2.4). Эти метаметоды также называются деструкторы (finalizers). Деструкторы позволяют координировать сборку мусора в Lua с внешним управлением ресурсами (таким как закрытие файлов, сетевый подключения, подключения к базам данных или освобождение вашей памяти).
Для объекта (таблицы или пользовательских данных) чтобы быть уничтоженным при сборке мусора, вы должны отметить его на уничтожение. Вы отмечаете объект на уничтожение, когда устанавливаете для него метатаблицу, содержащую поле » __gc «. Имейте ввиду, что если вы установите метатаблицу без поля __gc и затем создадите это поле в метатаблице, то объект не будет отмечен на уничтожение.
Когда отмеченный объект становится мусором, он не уничтожается напрямую сборщиком мусора. Вместо этого, Lua ложит его в список. После завершения сборки, Lua проходит по этому списку. Для каждого объекта в списке проверяется метаметод __gc : если это функция, Lua вызывает её с объектом в качестве единственного аргумента; если метаметод не функция, Lua просто игнорирует его.
В конце каждого цикла сборки мусора, деструкторы объектов вызываются в порядке обратном порядку их отметки на уничтожение; т.е., первым деструктор будет вызван для последнего отмеченного на уничтожение объекта. Выполнение каждого деструктора может произойти в любое время при выполнении основного кода.
Так как объект подлежащий уничтожению должен быть использован в деструкторе, этот объект (и остальные объекты доступные через него) должны быть воскрешены Lua. Обычно, это воскрешение нерезидентно, и память объекта освобождается при следующем цикле сборки мусора. Тем не менее, если деструктор сохраняет объект в каком-то глобальном месте (т.е. глобальной переменной), воскрешение постоянно. Более того, если деструктор отмечает уничтожаемый объект для уничтожения снова, его деструктор будет вызван снова в следующем цикле, где объект не доступен. В любом случае, память объекта освобождается только в цикле сборки мусора, где объект недоступен и не отмечен на уничтожение через деструктор.
Когда вы закрываете контекст (см. lua_close ), Lua вызывает деструкторы всех объектов отмеченных на уничтожение, следуя порядку обратному порядку их отметки на уничтожение. Если любой деструктор отмечает объекты для уничтожения в этой фазе, эти отметки не имеют никакого эффекта.
2.5.2 – Слабые таблицы
Слабая таблица (weak table) — это таблица, элементы которой это слабые ссылки (weak references). Слабая ссылка игнорируется сборщиком мусора. Другими словами, если на объект существуют только слабые ссылки, то объект будет уничтожен сборщиком мусора.
Слабая таблица может иметь слабые ключи, слабые значения или и то и другое. Таблица со слабыми значениями позволяет уничтожать её значения, но препятствует уничтожению её ключей. Таблица со слабыми значениями и ключами позволяет уничтожать и ключи и значения. В любом случае, если ключ или значение уничтожены, эта пара удаляется из таблицы. Слабость таблицы контролируется полем __mode в её метатаблице. Если поле __mode это строка содержащая символ ‘ k ‘, в таблице слабые ключи. Если поле __mode содержит ‘ v ‘, в таблице слабые значения.
Таблица со слабыми ключами и сильными значениями называется эфемерной таблицей (ephemeron table). В эфемерной таблице, значение достижимо только если его ключ достижим. В частности, если ссылка на ключ приходит через его значение, пара удаляется.
Любое изменение слабости таблицы будет иметь эффект только в следующем цикле сборки мусора. В частности, если вы сменили слабый на сильный режим, Lua может продолжить сбор некоторых элементов из этой таблицы, пока изменения не будут иметь эффект.
Только объекты, имеющие явную конструкцию, удаляются из слабых таблиц. Значения, такие как числа и легкие C функции, не являются субъектами для сборки мусора, и следовательно не удаляются из слабых таблиц (пока их ассоциированные значения не удалены). Хотя строки субъекты для сборки мусора, они не имеют явную конструкцию, и следовательно не удаляются из слабых таблиц.
Воскрешенные объекты (т.е., объекты подлежащие уничтожению и объекты достпупные через них) имеют специальное поведение в слабых таблицах. Они удаляются из слабых значений перед запуском их деструкторов, но удаляются из слабых ключей только в следующем цикле сборки, после запуска их деструкторов, когда эти объекты действительно освобождены. Это поведение позволяет деструктору получить доступ к свойствам, ассоциированным с объектом через слабые таблицы.
Если слабая таблица среди воскрешенных объектов в цикле сборки, она не может быть правильно очищена до следующего цикла сборки.
2.6 – Сопрограммы
Lua поддерживает сопрограммы, так называемую совместную многопоточность. Сопрограмма в Lua представляет независимый поток выполнения. В отличе от потоков в многопоточных системах, сопрограммма прерывает свое исполнение только явным вызовом функции yield (уступить).
Сопрограмма создается функцией coroutine.create . Единственный аргумент функции это главная функция сопрограммы. Функция create только создает сопрограмму и возвращает её описатель (объект типа thread — поток); она не запускает сопрограмму.
Сопрограмма запускается вызовом coroutine.resume . При первом вызове coroutine.resume , в качестве первого аргумента передается поток, возвращенный функцией coroutine.create , сопрограмма начинает свое исполнение с вызова своей главной функции. Дополнительные аргументы, переданные в coroutine.resume , передаются как аргументы этой функции. После запуска сопрограммы, она выполняется пока не будет завершена или не уступит (yield).
Сопрограмма может завершить свое исполнение двумя путями: нормально, когда её главная функция вернет управление (явно или не явно, после последней инструкции); и ненормально, если произойдет незащищенная ошибка. В случае нормального завершения, coroutine.resume вернет true и значения, возвращенные главной фунцией сопрограммы. В случае ошибок, coroutine.resume вернет false и сообщение об ошибке.
Сопрограмма уступает, вызывая coroutine.yield . Когда сопрограмма уступает, соответсвующая coroutine.resume немедленно возвращает управление, даже если уступка случилась внутри вложенной функции (т.е., не в главной функции, а в функции прямо или косвенно вызванной из главной функции). В случае уступки, coroutine.resume также возвращает true и значения, переданные в coroutine.yield . В следующий раз, возобновление этой же сопрограммы продолжает её выполнение с точки, где она уступила вызовом coroutine.yield , возвращающим дополнительные аргументы, переданные в coroutine.resume .
Как и coroutine.create , функция coroutine.wrap создает сопрограмму, но вместо сопрограммы возвращает функцию, вызов которой возобновляет сопрограмму. Аргументы, переданные этой функции, идут как дополнительные аргументы в coroutine.resume . coroutine.wrap возвращает все значения полученные от coroutine.resume , кроме первого (логический код ошибки). В отличие от coroutine.resume , coroutine.wrap не перехватывает ошибки; все ошибки передаются вызывающей стороне.
Для примера работы сопрограммы, рассмотрите следующий код:
Запустив его, вы получите следующий результат:
Вы также можете создавать и манипулировать сопрограммами через C API: см. функции lua_newthread , lua_resume и lua_yield .
3 – Язык
Этот раздел описывает лексику, синтаксис и семантику Lua. Другими словами, этот раздел описывает какие лексемы (tokens) правильны, как они могут быть скомбинированы, и что их комбинации означают.
Языковые конструкции будут объясняться используя обычную расширенную БНФ нотацию, в которой <a> означает 0 или больше a, и [a] означает опциональную a. Нетерминалы показаны как non-terminal, ключевые слова показаны как kword, и другие терминальные символы показаны как ‘=’. Полный синтасис Lua описан в §9 в конце руководства.
3.1 – Лексические соглашения
Lua — это язык свободной формы. Он игнорирует пробелы (включая переходы на новую строку) и комментарии между лексическими элементами, кроме разделителей между именами и ключевыми словами.
Имена (также называемые идентификаторами) в Lua могут быть любой строкой из букв, цифр и подчеркиваний, не начинающейся с цифры. Идентификаторы используются для именования значений, полей таблиц и меток (labels).
Следующие ключевые слова зарезервированы и не могут использоваться как имена:
Язык Lua чувствителен к регистру символов: and — зарезервированное слово, но And и AND — два разных, допустимых имени. Как соглашение, программы должны избегать создания имен, которые начинаются с подчеркивания и следующими за ним одной или несколькими прописными буквами (например, _VERSION ).
Следующие строки разделяют другие лексемы:
Литеральные строки могут быть ограничены сочетающимися одинарными или двойными кавычками, и могут содержать С-подобные управляющие последовательности: ‘ \a ‘ (bell), ‘ \b ‘ (backspace), ‘ \f ‘ (form feed), ‘ \n ‘ (newline), ‘ \r ‘ (carriage return), ‘ \t ‘ (horizontal tab), ‘ \v ‘ (vertical tab), ‘ \\ ‘ (backslash), ‘ \» ‘ (двойная кавычка) и ‘ \’ ‘ (апостроф [одинарная кавычка]). Обратный слеш, сопровождаемый реальным переходом на новую строку (newline), формирует переход строки (newline) в строке (string). Управляющая последовательность ‘ \z ‘ пропускает следующий за ней диапазон пробелов, включая переходы строки; это особенно полезно, чтобы разбить и отступить длинную литеральную строку на несколько линий без добавления переводов строки и пробелов в содержимое строки.
Строки в Lua могут содержать любое 8-битное значение, влючая встроенные нули, которые могут быть записаны как ‘ \0 ‘. Более того, возможно описать любой байт в литеральной строке его числовым значением. Это может быть сделано с помощью управляющей последовательности \xXX , где XX — это пара шестнадцатиричных цифр, или с помощью \ddd , где ddd — последовательность до трех десятичных цифр. (Обратите внимание, что если десятичная управляющая последовательность сопровождается цифрой, то она должна содержать ровно три цифры.)
Unicode-символ в кодировке UTF-8 может быть вставлен в литеральную строку с помощью последовательности \u<XXX> (обратите внимание на обязательные фигурные скобки), где XXX — это одна или больше шестнадцатиричных цифр описывающих код символа.
Литеральные строки также могут быть определены используя длинные скобки. Мы определяем открывающую длинную скобку уровня n, как открывающую квадратную скобку, следующие за ней n знаков = и ещё одну открывающую квадратную скобку. Так, открывающая длинная скобка уровня 0 запишется так: [[ , для уровня 1 — [=[ , и так далее. Закрывающая длинная скобка определяется аналогично; например, закрывающая длинная скобка уровня 4 запишется так: ]====] . Длинный литерал начинается с открывающей длинной скобки любого уровня и завершается на первой закрывающей длинной скобке того же уровня. Это позволяет содержать любой текст, кроме закрывающей скобки того же уровня. Литералы в такой скобочной форме могут занимать несколько линий (строк), управляющие последовательности в таких строках не работают, длинные скобки других уровней игнорируются. Любой вид последовательности завершения строки (\r, \n, \r\n или \n\r) конвертируется в простой перевод строки \n.
Любой байт в литеральной строке не подвержен влиянию правил своего представления. Тем не менее, Lua открывает файлы для парсинга в текстовом режиме, и функции системы могут иметь проблемы с некоторыми управляющими символами. Поэтому, для безопасного представления не текстовых данных в строке, следует использовать управляющие последовательности.
Для удобства, когда открывается длинная скобка с непосредственным переводом строки за ней, перевод строки не включается в результирующую строку. Например, в системе использующей ASCII (в которой ‘ a ‘ кодируется как 97, newline кодируется как 10 и ‘ 1 ‘ кодируется как 49), пять литеральных строк ниже кодируют одинаковые строки:
Числовая константа (или цифра) может быть записана с опциональной дробной частью и опциональной десятичной экспонентой, обозначенной буквой ‘ e ‘ или ‘ E ‘. Lua также поддерживает шестнадцатиричные константы, которые начинаются с 0x или 0X . Шестнадцатиричные константы также допускают использование дробной части и бинарной экспоненты, обозначеной буквой ‘ p ‘ или ‘ P ‘. Цифровая константа с разделительной точкой или экспонентой означает вещественное число; иначе она означает целое. Примеры допустимых целых чисел:
Примеры допустимых вещественных чисел:
Комментарии начинаются с двойного тире ( — ) в любом месте за пределами литеральной строки. Если текст, непосредственно следующий за — , не открывающая длинная скобка, то это короткий комментарий, который продолжается до конца строки. Иначе, это длинный комментарий, который продолжается до соответствующей закрывающей длинной скобки. Длинные комментарии часто используются для временного отключения кода.
3.2 – Переменные
Переменные — это место где хранятся значения. Существует три вида переменных: глобальные переменные, локальные переменные и поля таблиц.
Одно имя может означать глобальную или локальную переменную (или формальный параметр функции, который является частным случаем локальной переменной):
Name означает идентификаторы, как описано в §3.1.
Любое имя переменной предполагается глобальным, пока явно не определено локальным (см. §3.3.7). Локальные переменные лексически ограниченные: локальные переменные свободно доступны функциям, определенным внутри их области видимости (см. §3.5).
Перед первым присваиванием переменной, её значение равно nil.
Квадратные скобки используются для индексирования в таблице:
Значение доступа к полям таблицы может быть изменено через метатаблицы. Доступ к индексированной переменной t[i] эквивалентно вызову gettable_event(t,i) . (См. §2.4 для полного описания функции gettable_event . Эта функция не определена и не используется в Lua. Мы используем её только для пояснения.)
Синтаксис var.Name — это лишь семантическое украшение для var[«Name»] :
Доступ к глобальной переменной x эквивалентен _ENV.x . в силу того, что блоки компилируются, _ENV никогда не является глобальным именем (см. §2.2).
3.3 – Выражения
Lua поддерживает почти стандартный набор выражений, подобный наборам в Pascal или C. Этот набор включает в себя присваивания, управляющие структуры, вызовы функций и определения переменных.
3.3.1 – Блоки
Блок — это список выражений, которые выполняются последовательно:
Lua допускает пустые выражения, что позволяет вам разделять выражения с помощью точки с запятой (;), начинать блок с точки с запятой или писать две точки с запятой подряд:
Вызовы функций и присваивания могут начинаться с открывающейся скобки. Эта возможность ведет к неоднозначности в грамматике Lua. Рассмотрим следующий фрагмент:
Грамматика может рассматривать это двумя путями:
Текущий парсер всегда рассматривает такие констркции первым путем, интерпретируя открывающуюся скобку, как начало аргументов для вызова. Для избежания этой неоднозначности, лучше всегда ставить точку с запятой (;) перед выражениями начинающимися со скобок:
Блок может быть явно выделен для создания единственного выражения:
Явные блоки полезны для контроля за областью видимости переменных. Явные блоки также иногда используются для добавления выражения return в середину другого блока (см. §3.3.4).
3.3.2 – Куски
Единица компиляции в Lua называется куском (chunk). Синтаксически, кусок это простой блок:
Lua обрабатывает кусок, как тело анонимной функции с переменным числом аргументов (см. §3.4.11). Как таковой, кусок может определять локальные переменные, получать аргументы и возвращать значения. Более того, такая анонимная функция компилируется в области видимости внешней локальной переменной _ENV (см. §2.2). Результирующая функция всегда имеет _ENV , как только свою upvalue, даже если не использует эту переменную.
Кусок может храниться в файле или в строке внутри хостовой программы. Для запуска куска, Lua сперва загружает его (load), прекомпилируя код куска в инструкции виртуальной машины, и затем запускает скомпилированный код.
Кусок также может быть прекомпилирован в бинарную форму; смотри программу luac и функцию string.dump . Программы в исходном коде и в скомпилированной форме взаимозаменяемы; Lua автоматически определяет тип файла и действует соответственно (см. load ).
3.3.3 – Присваивание
Lua позволяет множественные присваивания. Синтаксис присваивания определяет список переменных с левой строны и список выражений с правой стороны. Элементы в обоих списках разделяются запятыми:
Выражения обсуждаются в §3.4.
Перед присваиванием, список значений корректируется до длины списка переменных. Если значений больше чем нужно, лишние значения отбрасываются. Если значений меньше чем нужно, список расширяется добавлением необходимого числа значений nil. Если список выражений заканчивается вызовом функции, все значения, возвращенные этой функцией, попадают в список значений перед присваиванием. (кроме вызова заключенного в скобки; см. §3.4).
Оператор присваивания сперва вычисляет все свои выражения и лишь затем выполняет присваивание. Таким образом код
устанавливает a[3] равным 20, не изменяя a[4] , т.к. i в a[i] вычисляется (= 3) до присваивания ему 4. Аналогично, строка
меняет местами значения x и y , и
циклически переставляет значения x , y и z .
Значение присваиваний глобальным переменным и полям таблиц может быть изменено через метатаблицы. Присваивание индексированной переменной t[i] = val эквивалентно settable_event(t,i,val) . (См. §2.4 для полного описания функции settable_event . Эта функция не определена и не используется в Lua. Мы используем её только для пояснения.)
Присванивание глобальной переменной x = val эквивалентно присваиванию _ENV.x = val (см. §2.2).
3.3.4 – Управляющие конструкции
Управляющие конструкции if, while и repeat имеют обычное значение и знакомый синтаксис:
Lua также имеет две формы оператора for (см. §3.3.5).
Условное выражение в управляющей конструкции может возвращать любое значение. False и nil рассматриваются как false. Все значения, отличные от nil и false, рассматриваются как true (в частности, число 0 и пустая строка это тоже true).
В цикле repeat–until, внутренний блок заканчивается после всего условия, а не на ключевом слове until. Так, условие может ссылаться на локальные переменные объявленные внутри цикла.
Оператор goto передает управление на метку. По синтаксическим причинам, метки в Lua тоже считаются выражениями:
Метка видна в блоке где объявлена, за исключением вложенных блоков, где определена метка с таким же именем и вложенных функций. Goto может переходить на любую видимую метку, так далеко, пока не войдет в область видимости локальной переменной.
Метки и пустые выражения называются пустыми выражениями, так как они не производят дейтсвий.
Выражение break завершает исполнение цикла while, repeat или for, пропуская оставшиеся команды цикла:
break завершает самый внутренний цикл.
Выражение return используется для возврата значений из функции или куска (который является анонимной функцией). Функции могут возвращать несколько значений, поэтому синтаксис для выражения return следующий:
Выражение return может быть написано только, как последнее в блоке. Если действительно необходимо иметь return в середине блока, тогда можно использовать явный внутренний блок, как идиома do return end , теперь return это последнее выражение в его (внутреннем) блоке.
3.3.5 – Конструкция For
Конструкция for имеет две формы: цифровую и общую.
Цифровой цикл for повторяет блок кода, пока управляющая переменная изменяется в арифметической прогрессии. Он имеет следующий синтаксис:
block повторяется для name начиная с первого значения exp, пока не достигнет значения втрого exp, шагами равными третьему exp. Более точно, выражение for
эквивалентно следующему коду:
- Все три управляющие выражения вычисляются только один раз, перед тем как начнется цикл. Их результаты должны быть числами.
- var , limit и step — невидимые переменные. Имена показаны здесь только для пояснения.
- Если третье выражение (шаг) отсутствует, тогда используется шаг 1.
- Для выхода из цикла for вы можете использовать break и goto.
- Переменная цикла v является локальной для тела цикла. Если необходимо использовать её значение после цикла, сохраните его в другой переменной перед выходом из цикла.
Общий for работает через функции, называемые итераторами. На каждой итерации, функция-итератор вызывается чтобы выдать новое значение, остановка происходит, когда новое значение равно nil. Общий цикл for имеет следующий синтаксис:
Выражение for
эквивалентно следующему коду:
- explist вычисляется только один раз. Его результат это функция итератор, состояние и начальное значение для первой итерируемой переменной.
- f , s и var — невидимые переменные. Имена показаны здесь только для пояснения.
- Для выхода из цикла for вы можете использовать break.
- Переменная цикла var_i является локальной для тела цикла. Если необходимо использовать её значение после цикла, сохраните его в другой переменной перед выходом из цикла.
3.3.6 – Вызовы функций как выражения
Чтобы позволить побочные эффекты, вызовы функций могут запускаться как выражения:
В этом случае все возвращенные значения отбрасываются. Вызовы функций рассматриваются в §3.4.10.
3.3.7 – Локальные определения
Локальные переменные могут быть объявлены в любой части блока. Определение может содержать начальное присваивание (инициализацию):
Если есть начальное присваивание, то оно имеет семантику схожую с множественным присваиванием (см. §3.3.3). Иначе, все переменные инициализируются значением nil.
Кусок также является блоком (см. §3.3.2), и следовательно локальные переменные могут быть объявлены в куске вне всякого явного блока.
Правила видимости локальных переменных рассматриваются в §3.5.
3.4 – Выражения
Базовые выражения в Lua следующие:
Числа и литеральные строки рассматриваются в §3.1; переменные рассматриваются в §3.2; определения функций рассматриваются в §3.4.11; вызовы функций рассматриваются в §3.4.10; конструкторы таблиц описаны в §3.4.9. Выражения с переменными аргументами, обозначенными тремя точками (‘ . ‘), могут быть использованы только внутри функции с переменным числом аргументов; они описываются в §3.4.11.
Бинарные операторы, включая арифметические (см. §3.4.1), битовые операторы (см. §3.4.2), операторы сравнения (см. §3.4.4), логические операторы (см. §3.4.5), и оператор конкатенации (см. §3.4.6). Одноместные операторы, включая одноместный минус (см. §3.4.1), одноместный битовый НЕ (см. §3.4.2), одноместный логический not (см. §3.4.5), и одноместный оператор длины (см. §3.4.7).
Функции и выражения с переменным числом аргументов могут возвращать несколько значений. Если вызов функции используется как выражение (см. §3.3.6), он возвращает список скорректированный до нуля элементов, т.е. отброшены все возвращенные значения. Если выражение используется последним элементом в списке выражений (или оно только одно), то корректировка не производится (если выражение не заключено в скобки). Во всех остальных случаях Lua корректирует список результатов до одного элемента, отбрасывая все значения кроме первого, или добавляя один nil, если значений нет.
Здесь несколько примеров:
Любое выражение, заключенное в скобки, всегда возвращает только одно значение. Т.е., (f(x,y,z)) всегда одно значение, даже если f возвращает несколько значений. (Значение (f(x,y,z)) это первое из значений возвращенных f или nil, если f не вернет ни одного значения.)
3.4.1 – Арифметические операторы
- + : сложение
- — : вычитание
- * : умножение
- / : деление
- // : целочисленное деление
- % : модуль
- ^ : возведение в степень
- — : одноместный минус
За исключением возведения в степень и деления, арифметические операторы работают следующим образом: Если оба операнда целые, операция производится над целыми и результатом является целое. Иначе, если оба операнда числа или строки, которые могут быть сконвертированы в числа (см. §3.4.3), они конвертируются в числа с плавающей запятой (float), операции производятся согласно обычным правилам арифметики вещественных чисел (обычно стандарт IEEE 754), и результатом будет число с плавающей запятой.
Возведение в степень и деление ( / ) всегда конвертирует операнды в вещественные числа и результат вещественное число. Возведение в степень использует функцию pow из ISO C, она работает и для не целых экспонент тоже.
Целочисленное деление ( // ) — это деление, которое округляет частное по отношению к минус беспонечности, т.е. нижнее от деления операндов.
Модуль определено как остаток от деления, которое округляет частное по отношению к минус беспонечности (целочисленное деление).
В случае переполнения целочисленной арифметики, все операции циклически переходят, в соответствии с обычными правилами арифметики двоичного дополнения. (Другими словами, они возвращают уникальное представимое целое, которое равно по модулю 2 64 математическому результату.)
3.4.2 – Битовые операторы
- & : битовое И
- | : битовое ИЛИ
Все битовые операторы преобразуют свои операнды в целые (см. §3.4.3), оперируют всеми битами этих целых и результат тоже целое.
Правый и левый сдвиги заполняют свободные биты нулями. Отрицательное смещение сдвигает в противоположном направлении; смещения с абсолютными значениями большими (или равными), чем число бит в целом, дают результат ноль (все биты сдвинуты наружу).
3.4.3 – Приведения и преобразования
Lua производит некоторые автоматические преобразования между типами и представлениями во время выполнения. Битовые операторы всегда конвертируют вещественные операнды в целые. Возведение в степень и деление всегда конвертируют целые операнды в вещественные. Все остальные арифметические операции, примененные к смешанным числам (целые и вещественные), преобразуют целые цисла в вещественные; это называется обычное правило. C API также конвертирует целые в вещественные и вещественные в целые, при необходимости. Более того, конкатенация строк принимает числа, как аргументы между строками.
Lua также конвертирует строки в числа, когда ожидается число.
В преобразовании целого в вещественное, если целое значение имеет точное представление как вещественное, это представление и будет результатом. Иначе, преобразование получает ближайшее большее или ближайшее меньшее представимое значение. Этот тип преобразования всегда успешен.
Преобразование вещественного в целое проверяет, что вещественное имеет точное представление как целое (т.е., вещественное имеет целое значение и в диапазоне представления целых). Если это так, то это представление будет результатом. Иначе, преобразование терпит неудачу.
Преобразование строк в числа идет следующим образом: Первое, строка преобразуется в целое или вещественное, следуя синтаксису и правилам лексера Lua. (Строка может содержать начальные и конечные пробелы и знак.) Затем, получившееся число (целое или вещественное) преобразуется в тип (целое или вещественное), требуемый в данном контексте (т.е., требуемый операцией которая конвертирует принудительно).
Преобразование чисел в строки использует не определенный читабельный формат. Для полного контроля над тем, как числа конвертируются в строки, используйте функцию format из строковой библиотеки (см. string.format ).
3.4.4 – Операторы сравнения
- == : равенство
Эти операторы всегда возвращают false или true.
Равенство ( == ) сперва сравнивает типы операндов. Если типы разные, то результат false. Иначе, сравниваются значения операндов. Строки сравниваются очевидным способом. Числа равны, если они обозначают одинаковые математические значения.
Таблицы, пользовательские данные и потоки сравниваются по ссылке: два объекта считаются равными только, если это один и тот же объект. Всегда, когда вы создаете новый объект (таблицу, пользовательские данные или поток), этот новый объект отличен от любого существующего объекта. Замыкания (closure) с одинаковыми ссылками всегда равны. Замыкания с любыми обнаруживаемыми различиями (разное поведение, разное определение) всегда различны.
Используя метаметод «eq», вы можете изменить способ, которым Lua сравнивает таблицы и пользовательские данные (см. §2.4).
Проверка на равенство не конвертирует строки в числа и наоборот. Так, «0»==0 вернет false, t[0] и t[«0»] означают разные элементы в таблице.
= это явное отрицание равенства ( == ).
Операторы упорядочения работают следующим образом. Если оба аргумента числа, то они сравниваются согласно их математическим значениям. (независимо от их подтипов). Иначе, если оба аргумента строки, то их значения сравниваются согласно текущей локали. Иначе, Lua пытается вызвать метаметоды «lt» или «le» (см. §2.4). Сравнение a > b транслируется в b < a и a >= b транслируется в b <= a .
Следуя стандарту IEEE 754, NaN рассматривается как никакой: не меньший, не больший, не равный ни одному значению (включая себя самого).
3.4.5 – Логические операторы
В Lua существуют следующие логические операторы: and (И), or (ИЛИ) и not (НЕ). Как и управляющие структуры (см. §3.3.4), все логические операторы считают false и nil как false, а все остальное как true.
Оператор отрицания not всегда возвращает false или true. Оператор конъюнкции and возвращает свой первый аргумент, если его значение false или nil; иначе, and возвращает второй аргумент. Оператор дизъюнкции or возвращает свой первый аргумент, если его значение отлично от nil и false; иначе, or возвращает второй аргумент. Оба and и or используют ленивое вычисление; т.е., второй операнд вычисляется только если необходимо. Несколько примеров:
(В этом руководстве, —> означает результат предыдущего выражения.)
3.4.6 – Конкатенация
Конкатенация строк в Lua обозначается двумя точками (‘ .. ‘). Если оба операнда строки или числа, они конвертируются в строки согласно правилам, описанным в §3.4.3. Иначе, вызывается метаметод __concat (см. §2.4).
3.4.7 – Оператор длины
Оператор длины обозначается одноместным префиксом # . Длина строки это число байт в ней (т.е., обычное значение длины строки, когда каждый символ размером 1 байт).
Программа может модифицировать поведение оператора длины для любого значения, кроме строк, используя метаметод __len (см. §2.4).
Пока метаметод __len не определен, длина таблицы t определена только, если таблица t последовательность, т.е., набор её положительных числовых ключей равен для какого-то положительного целого n. В этом случае, n это длина. Имейте ввиду, таблица как
это не последовательность, т.к. она имеет ключ 4 , но не имеет ключ 3 . (Так, там нет n, который в множестве равен набору положительных числовых ключей этой таблицы.) Тем не менее, эти не числовые ключи не создают помех с независимой последовательностью в таблице.
3.4.8 – Приоритет
Приоритет операторов в Lua представлен далее, с меньшего к большему приоритету:
Как обычно, чтобы изменить приоритет в выражении, вы можете использовать скобки. Операторы конкатенации (‘ .. ‘) и возведения в степень (‘ ^ ‘) имеют правую ассоциативность. Все остальные бинарные операторы имеют левую ассоциативность.
3.4.9 – Конструкторы таблиц
Конструкторы таблиц — это выражения, которые создают таблицы. При каждом запуске конструктора создается новая таблица. Конструктор может использоваться для создания пустой таблицы или для создания таблицы с инициализацией некоторых её полей. Общий синтаксис конструкторов следующий:
Каждое поле вида [exp1] = exp2 добавляет новый элемент таблицы с ключем exp1 и значением exp2 . Поле вида name = exp эквивалентно записи [«name»] = exp . Поля вида exp эквивалентны [i] = exp , где i последовательные целые, начинающиеся с 1; поля в других форматах не влияют на этот счет. Например,
Порядок присваиваний в конструкторе не определен. (Этот порядок важен только для повторяющихся ключей.)
Если последнее поле в списке имеет вид exp и выражение это вызов функции или обозначение множества аргументов (. ), то все значения, возвращенные этим выражением, последовательно включаются в список (см. §3.4.10).
Список полей может иметь опциональный конечный разделитель, для удобства машинно-сгенерированного кода.
3.4.10 – Вызовы функций
Вызов функции в Lua имеет следующий синтаксис:
При вызове функции, сперва вычисляются prefixexp и args. Если значение prefixexp имеет тип function, то вызывается эта функция с данными аргументами. Иначе, для объекта prefixexp вызывается метаметод «call», в качестве первого параметра передается значение prefixexp, затем остальные аргументы вызова. (см. §2.4).
может быть использована для вызова «методов». Вызов v:name(args) это синтаксическое украшение для v.name(v,args) , за исключением того, что v вычисляется только один раз.
Аргументы имеют следующий синтаксис:
Все выражения в аргументах вычисляются перед вызовом.
Вызов вида f<fields> это синтаксическое украшение для f(<fields>) ; т.е. в качестве аргумента передается одна новая таблица.
Вызов вида f’string‘ (или f»string» или f[[string]] ) это синтаксическое украшение для f(‘string‘) ; т.е. в качестве аргумента передается одна литеральная строка.
Вызов вида return functioncall называется хвостовым вызовом (tail call). Lua реализует соответствующие хвостовые вызовы (proper tail call) (или соответствующую хвостовую рекурсию): в хвостовом вызове, вызванная функция повторно использует элементы стека вызывающей функции. Следовательно, не существует лимита на число вложенных хвостовых вызовов, выполняемых программой. Тем не менее, хвостовой вызов затирает любую отладочную информацию о вызывающей функции. Имейте ввиду, что хвостовой вызов происходит только с конкретным синтаксисом, где return имеет только один вызов функции в качестве аргумента; при таком синтаксисе вызывающая функция возвращает тоже, что и вызванная функция. Так, в следующих примерах хвостовой вызов не происходит:
3.4.11 – Определения функций
Синтаксис для определения функции:
Следующее синтаксическое украшение упрощает определение функций:
(Это имеет значение, когда тело функции содержит ссылки на f .)
Определение функции — это исполняемое выражение, значение которого имеет тип function. Когда Lua предкомпилирует кусок, все тела функций в нем прекомпилируются тоже. Затем, всякий раз, когда Lua запускает определение функции, функция инстанцируется (или замыкается). Этот экземпляр функции (или замыкание [closure]) будет финальным значением выражения.
Параметры действуют как локальные переменные, инициализированные значениями аргументов:
Когда функция вызывается, список аргументов корректируется до длины списка параметров, пока функция это не функция с переменным числом аргументов (vararg function); переменные аргументы указываются тремя точками (‘ . ‘) в конце списка параметров. Функция с переменным числом аргументов не корректирует свой список аргументов; взамен, она коллекционирует все дополнительные аргументы и передает их в функцию через vararg-выражение, которое также обозначается тремя точками. Значение этого выражения это список всех фактических дополнительных аргументов, подобно функции с множественными возвращаемыми значениями. Если vararg-выражение используется внутри другого выражения или в середине списка выражений, то его результат корректируется до одного элемента. Если vararg-выражение используется как последний элемент в списке выражений, то корректировка не производится (если последнее выражение не заключено в скобки).
Например, рассмотрим следующие определения:
Мы получим следующее соответствие аргументов параметрам и vararg-выражению:
Результаты возвращаются выражением return (см. §3.3.4). Если управление достигает конца функции без выражения return, то функция не возвращает результатов.
Существует системозависимый предел числа значений, которые может вернуть функция. Этот предел гарантированно больше 1000.
Синтаксис двоеточия используется для определения методов, т.е. функций, которые имеют явный дополнительный параметр self . Таким образом, выражение
это синтаксическое украшение для
3.5 – Правила видимости
Lua — язык с лексическими областями видимости. Область видимости локальной переменной начинается с первого выражения после её определения и продолжается до последнего не пустого выражения внутреннего блока, включающего определение. Рассмотрим следующий пример:
Учтите, что в определении вида local x = x , новый x пока вне зоны видимости и, таким образом, второй x ссылается на внешнюю переменную.
Согласно правилам видимости, локальные переменные могут быть свободно доступны функциям, определенным в их зоне видимости. Локальная переменная, которая используется внутренней функцией, внутри данной функции называется upvalue или внешняя локальная переменная.
Обратите внимание, каждое выполнение выражения local определяет новую локальную переменную. Рассмотрим следующий пример:
Цикл создает 10 замыканий (т.е., 10 экземпляров анонимной функции). Каждое из этих замыканий использует разные переменные y и общую для всех x .
4 – Программный интерфейс (API)
Этот раздел описывает C API для Lua, т.е. набор C функций, доступный хостовой программе для взаимодействия с Lua. Все API функции и связанные типы и константы определены в заголовочном файле lua.h .
Каждый раз, когда мы используем термин «функция», любая возможность в API может быть реализована как макрос. Везде, где не оговорено обратное, все такие макросы используют каждый свой аргумент только один раз (исключая первый аргумент, который всегда является контекстом Lua) и не генерируют ни каких скрытых побочных эффектов.
Как и в большинстве C библиотек, функции Lua API не проверяют свои аргументы на корректность и согласованность. Тем не менее, вы можете изменить это поведение, скомпилировав Lua с включенным определением LUA_USE_APICHECK .
4.1 – Стек
Чтобы передавать значения из и в С Lua использует виртуальный стек. Каждый элемент этого стека представляет Lua значение (nil, number, string и др.).
Кажды раз, когда Lua вызывает C, вызванная функция получает новый стек, который независим от предыдущих стеков и стеков активных в данный момент C функций. Этот стек изначально содержит все аргументы для C функции, туда же C функция ложит свои результаты, чтобы вернуть вызывающей стороне (см. lua_CFunction ).
Для удобства, большинство операций запроса в API не следуют строгой стековой дисциплине. Напротив, они могут ссылаться на любой элемент в стеке, используя его индекс: Положительный индекс представляет абсолютную позицию в стеке (начиная с 1); отрицательный индекс представляет смещение относительно вершины стека. Точнее, если стек имеет n элементов, индекс 1 представляет первый элемент (т.е., элемент, который был положен на стек первым) и индекс n представляет последний элемент; индекс -1 также представляет последний элемент (т.е., элемент на вершине стека) и индекс -n представляет первый элемент.
4.2 – Размер стека
Когда вы работаете с Lua API, вы ответственны за гарантирование согласованности. В частности, вы ответственны за контроль над переполнением стека. Вы можете использовать функцию lua_checkstack чтобы проверять, что стек имеет достаточно места для новых элементов.
Каждый раз, когда Lua вызывает C, он убеждается, что стек имеет место для как минимум LUA_MINSTACK дополнительных слотов. LUA_MINSTACK определен равным 20, так обычно вы не должны беспокоиться о размере стека, пока ваш код не содержит циклы, помещающие элементы в стек.
Когда вы вызываете Lua функцию без определенного числа результатов (см. lua_call ), Lua гарантирует, что стек имеет достаточно места для помещения всех результатов, но не гарантирует любое дополнительное пространство. Так, перед тем как положить что-либо на стек после вызова функции, вы должны использовать lua_checkstack .
4.3 – Правильные и допустимые индексы
Любая API функция, получающая стековые индексы, работает только с правильными индексами или допустимыми индексами.
Правильный индекс — это индекс, который ссылается на позицию, содержащую модифицируемое Lua значение. Допустимый диапазон включает стековые индексы между 1 и вершиной стека ( 1 ≤ abs(index) ≤ top ) плюс псевдоиндексы, которые представляют некоторые позиции, доступные для C кода, но не находящиеся в стеке. Псевдоиндексы используются для доступа к реестру (см. §4.5) и к внешним локальным переменным (upvalue) C функции (см. §4.4).
Функции, не нуждающиеся в специфической изменяемой позиции, а нуждающиеся только в значении (т.е., функции запросов), могут быть вызваны с допустимыми индексами. Допустимым индексом может быть любой правильный индекс, но это также может быть любой положительный индекс после вершины стека внутри пространства, выделенного для стека, т.е., индексы выше размера стека. (Учтите, что 0 это всегда недопустимый индекс.) Если не оговорено иное, API функции работают с допустимыми индексами.
Допустимые индексы служат для избежания дополнительных тестов вершины стека при запросах. Например, C функция может запросить свой третий аргумент без проверки его существования, т.е., без проверки того, что индекс 3 является правильным.
Для функций, которые могут быть вызваны с допустимыми индексами, любой не правильный индекс, трактуется как индекс к значению виртуального типа LUA_TNONE , которое ведет себя как значение nil.
4.4 – C замыкания
Когда C функция создана, можно ассоциировать с ней несколько значений, таким образом создав C замыкание (closure) (см. lua_pushcclosure ); эти значения называются upvalue и доступны функции во время вызова.
При каждом вызове C функции, её upvalue располагаются по специфическим псевдоиндексам. Псевдоиндексы создаются макросом lua_upvalueindex . Первое upvalue, ассоциированное с функцией, располагается по индексу lua_upvalueindex(1) , и так далее. Любое обращение к lua_upvalueindex(n) , где n больше количества upvalue текущей функции (но не больше 256), создает допустимый, но не правильный индекс.
4.5 – Реестр
Lua предоставляет реестр, предопределенную таблицу, которая доступна C коду для хранения любых Lua значений. Таблица рееста всегда расположена по псевдоидексу LUA_REGISTRYINDEX . Любая C библиотека может хранить данные в этой таблице, но она должна заботиться о выборе уникальных ключей, чтобы избежать коллизий с другими библиотеками. Обычно, вы должны использовать в качестве ключа строку содержащую имя библиотеки, или легкие пользовательские данные (light userdata) с адресом C объекта в вашем коде, или любой Lua объект созданный вашим кодом. Как и имена переменных, ключи, начинающиеся с подчеркивания со следующими за ним прописными буквами, зарезервированы для Lua.
Целочисленные ключи в реестре используются механизмом ссылок (см. luaL_ref ) и некоторыми предопределенными значениями. Следовательно, целочисленные ключи не должны использоваться для других целей.
- LUA_RIDX_MAINTHREAD : По этому индексу в реестре расположен главный поток контекста. (Главный поток создается при создании контекста.)
- LUA_RIDX_GLOBALS : По этому индексу в реестре расположено глобальное окружение.
4.6 – Обработка ошибок в C
Внутри, для обработки ошибок Lua использует C longjmp . (Lua будет использовать исключения, если вы скомпилируете его как C++; для подробностей ищите LUAI_THROW в исходном коде.) Когда Lua сталкивается с любой ошибкой (такой как ошибка выделения памяти, ошибки типов, синтаксические ошибки и ошибки времени выполнения), он возбуждает ошибку; т.е., делает длинный переход (long jump). Защищенное окружение использует setjmp для установки точки восстановления; любая ошибка переходит к самой последней точке восстановления.
Если ошибка случается за пределами защищенного окружения, Lua вызывает функцию паники (см. lua_atpanic ) и затем вызывает abort , завершая хостовое приложение. Ваша функция паники может избежать завершения приложения, если не вернет управление (т.е., сделает длинный переход [long jump] на вашу точку восстановления вне Lua).
Функция паники запускается как обработчик сообщений (см. §2.3); в частности, сообщение об ошибке лежит на вершине стека. Тем не менее, это не гарантирует стековое пространство. Чтобы положить что-либо на стек, функция паники должна сперва проверить доступное место (см. §4.2).
Большинство API функций могут возбуждать ошибки, например при выделении памяти. Описание для каждой функции предупреждает, что она может возбуждать ошибки.
Внутри C функции вы можете сгенерировать ошибку вызовом lua_error .
4.7 – Обработка уступок в C
Внутри, для приостановки сопрограммы Lua использует C longjmp . Следовательно, если C функция foo вызывает функцию API и эта API функция уступает (прямо или опосредованно, вызывая другую функцию, которая уступает), Lua больше не может вернуться к foo , потому что longjmp удаляет свой фрейм из C стека.
Чтобы избежать такой тип проблем, Lua возбуждает ошибку каждый раз, когда происходит уступка через вызов API, за исключением трех функций: lua_yieldk , lua_callk и lua_pcallk . Все эти функции получают функцию продолжения (как параметр k ) чтобы продолжить исполнение после уступки.
Чтобы рассмотреть продолжения установим некоторую терминологию. Мы имеем C функцию вызванную из Lua, назовем её оригинальной функцией. Эта оригинальная функция затем вызывает одну из этих трех API функций, которые мы будем называть вызываемой функцией, которая затем уступает текущий поток. (Это может случиться, когда вызываемая функция это lua_yieldk , или когда вызываемая функция любая из lua_callk или lua_pcallk и вызванная ими функция уступает.)
Допустим, выполняющийся поток уступает во время выполнения вызываемой функции. Затем поток продолжается, это в конечном счете завершит вызываемую функцию. Тем не менее, вызываемая функция не может вернуться в оригинальную, т.к. её фрейм в C стеке был уничтожен уступкой. Взамен, Lua вызывает функцию продолжения, которая передается как аргумент вызываемой функции. Как подразумевается, продолжающая функция должна продолжить выполнение задачи оригинальной функции.
Как иллюстрацию, рассмотрим следующую функцию:
Сейчас мы хотим позволить Lua коду, запущенному через lua_pcall , уступать. Сначала, перепишем нашу функцию как показано ниже:
В этом коде, новая функция k это функция продолжения (с типом lua_KFunction ), которая должна делать всю работу, которую оригинальная функция делала после вызова lua_pcall . Мы должны проинформировать Lua о том, что если Lua код, запущенный lua_pcall , будет прерван (ошибки или уступка), то необходимо вызвать k ; переписываем код, заменяя lua_pcall на lua_pcallk :
Обратите внимание на внешний явный вызов продолжения: Lua будет вызывать продолжение только при необходимости, т.е. в случае ошибок или возобновления после уступки. Если вызванная функция возвратится нормально, без уступок, lua_pcallk (и lua_callk ) также возвратятся нормально. (Конечно, в этом случае вместо вызова продолжения, вы можете выполнить эквивалентную работу прямо внутри оригинальной функции.)
Рядом с Lua состоянием, функция продолжения имеет два других параметра: конечный статус вызова и контекстное значение ( ctx ), которое изначально передается в lua_pcallk . (Lua не использует это контекстное значение; только передает его из оригинальной функции в функцию продолжения.) Для lua_pcallk , статус это тоже значение, которое будет возвращено функцией lua_pcallk , за исключением того, что после выполнения уступки это будет LUA_YIELD , (взамен LUA_OK ). Для lua_yieldk и lua_callk , когда Lua вызывает продолжение, статус всегда будет равен LUA_YIELD . (Для этих двух функций в случае ошибок Lua не вызовет продолжение, т.к. они не обрабатывают ошибки.) Аналогично, когда используется lua_callk , вы должны вызывать функцию продолжения со статусом LUA_OK . (Для lua_yieldk , нет смысла в прямом вызове функции продолжения, т.к. lua_yieldk обычно не возвращается.)
Lua обрабатывает функцию продолжения так, как будто это оригинальная функция. Функция продолжения получает тот же Lua стек из оригинальной функции, в том же состоянии, как если бы вызываемая функция вернулась. (Например, после lua_callk функция и её аргументы удалены из стека и заменены результатами вызова.) Она также будет иметь те же upvalue. Результаты, которые она вернет, будут обработаны Lua так, как будто их вернула оригинальная функция.
4.8 – Функции и типы
Здесь представлен список всех функций и типов из C API в алфавитном порядке. Каждая функция имеет индикатор вида: [-o, +p, x]
Первое поле, o , показывает сколько элементов функция снимает со стека. Второе поле, p , показывает сколько элементов функция ложит на стек. (Функции всегда ложат свои результаты после того, как снимут аргументы со стека.) Поле вида x|y означает, что функция может ложить (или снимать) x или y элементов, в зависимости от ситуации; знак вопроса ‘ ? ‘ означает, что по аргументам функции невозможно определить сколько элементов функция ложит/снимает (т.е. функция может зависеть от того, что лежит в стеке). Третье поле, x , показыает может ли функция генерировать ошибки: ‘ — ‘ означает, что функция никогда не генерирует ошибки; ‘ e ‘ означает, что функция может генерировать ошибки; ‘ v ‘ означает, что фунция предназначена для генерации ошибки.
lua_absindex
Конвертирует допустимый индекс idx в эквивалентный абсолютный индекс (который не зависит от вершины стека).
lua_Alloc
Тип функции выделения памяти, которая используется состоянием Lua. Функция выделения памяти должна предоставлять функциональность подобную функции realloc , но не точно такую же. Её аргументы ud — непрозрачный указатель, передаваемый в lua_newstate ; ptr — указатель на блок для выделения/перераспределения/освобождения; osize — оригинальный размер блока или код, определяющий под что выделяется память; nsize — новый размер блока.
Когда ptr не NULL , osize это размер блока по указателю ptr , т.е. размер полученный при выделении или перераспределении.
Когда ptr = NULL , osize кодирует тип объекта, для которого выделяется память. osize может быть равен LUA_TSTRING , LUA_TTABLE , LUA_TFUNCTION , LUA_TUSERDATA и LUA_TTHREAD , когда (и только когда) Lua создает новый объект данного типа. Когда osize какое-то другое значение, Lua выделяет память для чего-то другого.
Lua предполагает следующее поведение функции выделения памяти:
Когда nsize = 0, функция должна действовать как free и возвращать NULL .
Когда nsize != 0, функция должна действовать как realloc . Функция возвращает NULL только, если не может выполнить запрос. Lua предполагает, что функция выделения памяти не может выдать ошибку при osize >= nsize .
Здесь представлена простая реализация функции выделения памяти. Она используется во вспомогательной библиотеке функцией luaL_newstate .
Учтите, что стандартный C гарантирует, что free(NULL) не производит действий и realloc(NULL,size) эквивалентно malloc(size) . Этот код предполагает, что realloc не вызывает ошибок при уменьшении блока. (Хотя стандартный C не предполагает такого поведения, кажется, это безопасное предположение.)
lua_arith
Выполняет арифметическую или битовую операцию над двумя значениями (или одним, в случае отрицаний), находящимися на вершине стека, значение на вершине является вторым операндом, удаляет эти значения со стека и ложит результат операции. Функция следует семантике соответствующего оператора (т.е., может вызывать метаметоды).
- LUA_OPADD : сложение ( + )
- LUA_OPSUB : вычитание ( — )
- LUA_OPMUL : умножение ( * )
- LUA_OPDIV : деление ( / )
- LUA_OPIDIV : целочисленное деление ( // )
- LUA_OPMOD : модуль ( % )
- LUA_OPPOW : возведение в степень ( ^ )
- LUA_OPUNM : математическое отрицание (одноместный — )
- LUA_OPBNOT : битовое отрицание (
lua_atpanic
Устанавливает новую функцию паники и возвращает старую (см. §4.6).
lua_call
Для вызова функции вы должны использовать следующий протокол: первое, вызываемая функция должна быть помещена в стек; затем, на стек ложатся аргументы в прямом порядке; т.е., первый аргумент ложится первым. Наконец, производится вызов lua_call ; nargs — количество аргументов на стеке. Когда функция вызывается, все аргументы и функция снимаются со стека. Результаты ложатся на стек, когда функция возвращается. Количество результатов корректируется до nresults , если nresults не равно LUA_MULTRET . В этом случае, все результаты из функции ложатся на стек. Lua заботится, чтобы возвращенным значениям хватило места в стеке. Результаты функции ложатся в стек в прямом порядке (первый результат ложится первым), так что после вызова последний результат будет на вершине стека.
Любая ошибка внутри вызванной функции распространяется вверх (с longjmp ).
Следующий пример показывает, как хостовая программа может выполнить действия эквивалентные этому Lua коду:
Обратите внимание, что код выше сбалансирован: после его выполнения стек возвращается в первоначальное состояние. Это хорошая практика програмирования.
lua_callk
Эта функция аналогична lua_call , но позволяет вызываемой функции уступать (см. §4.7).
lua_CFunction
Тип для C функций.
Для правильного взаимодействия с Lua, C функция должна использовать следующий протокол, который определяет как передаются параметры и результаты: C функция получает аргументы из Lua в своём стеке в прямом порядке (первый аргумент ложится первым). Так, когда функция стартует, lua_gettop(L) возвращает количество аргументов, полученных функцией. Первый аргумент (если существует) находится по индексу 1, последний аргумент находится по индексу lua_gettop(L) . Для возврата значений в Lua, C функция просто ложит их на стек в прямом порядке (первый результат ложится первым) и возвращает число результатов. Любое другое значение в стеке ниже результатов будет сброшено Lua. Как и Lua функция, C функция, вызванная Lua, может возвращать несколько результатов.
Например, следующая функция получает переменное количество числовых аргументов и возвращает их среднее и их сумму:
lua_checkstack
Проверяет, что стек имеет место для как минимум n дополнительных слотов. Функция возвращает false, если не может выполнить запрос, потому что размер стека больше фиксированного максимума (обычно несколько тысяч элементов) или поскольку не может выделить память для дополнительных слотов. Эта функция никогда не уменьшает стек; если стек уже больше чем новый размер, он остаётся без изменений.
lua_close
Уничтожает все объекты в Lua состоянии (вызываются соответствующие метаметоды сборки мусора, если существуют) и освобождает всю динамическую память, использованную этим состоянием. На некоторых платформах, вы можете не вызывать эту функцию, т.к. все ресурсы освобождаются при завершении хостовой программы. С другой стороны, долго работающие программы, которые создают множество состояний, такие как демоны или веб-серверы, вероятно будут нуждаться в закрытии состояний, когда они станут ненужными.
lua_compare
Сравнивает два Lua значения. Возвращает 1, если значение по индексу index1 удовлетворяет op , когда сравнивается со значением по индексу index2 , следуя семантике соответствующего оператора Lua (т.е., могут вызываться метаметоды). Иначе возвращает 0. Также, возвращает 0, если любой из индексов не правильный.
- LUA_OPEQ : равенство ( == )
- LUA_OPLT : меньше ( < )
- LUA_OPLE : меньше или равно ( <= )
lua_concat
Производит конкатенацию n значений на вершине стека, снимает их со стека и оставляет результат на вершине стека. Если n = 1, результат это одно значение на стеке (т.е., функция ничего не делает); если n = 0, результат пустая строка. Конкатенация выполняется следуя обычной семантике Lua (см. §3.4.6).
lua_copy
Копирует элемент по индексу fromidx в правильный индекс toidx , заменяя значение на этой позиции. Значения в других позициях не изменяются.
lua_createtable
Создает новую пустую таблицу и ложит её на стек. Параметр narr — подсказка, сколько элементов в таблице будет как последовательность; параметр nrec — подсказка, сколько других элементов будет в таблице. Lua может использовать эти подсказки для предварительного выделения памяти для таблицы. Это предварительное выделение памяти полезно для производительности, когда вы заранее знаете сколько элементов будет в таблице. Иначе вы можете использовать функцию lua_newtable .
lua_dump
Сохраняет функцию как бинарный кусок. Получает Lua функцию на вершине стека и выдает её скомпилированной, при повторной загрузке куска, результаты эквивалентны результатам компилируемой функции. По мере выдачи частей куска, для его записи, lua_dump вызывает функцию writer (см. lua_Writer ) с полученной переменной data .
Если strip = true, бинарное представление может не включать всю отладочную информацию о функции, для уменьшения размера.
Возвращаемое значение: код ошибки, возвращенный при последнем вызове функции writer; 0 означает нет ошибок.
Эта функция не убирает Lua функцию со стека.
lua_error
Генерирует ошибку Lua, используя значение на вершине стека, как объект ошибки. Эта функция производит длинный переход (long jump) и никогда не возвращается (см. luaL_error ).
lua_gc
Управляет сборщиком мусора.
- LUA_GCSTOP : останавливает сборщик мусора.
- LUA_GCRESTART : перезапускает сборщик мусора.
- LUA_GCCOLLECT : производит полный цикл сборки мусора.
- LUA_GCCOUNT : возвращает текущий объем памяти (в килобайтах), используемый Lua.
- LUA_GCCOUNTB : возвращает остаток от деления текущего объема памяти, используемой Lua, в байтах на 1024.
- LUA_GCSTEP : производит шаг очистки мусора.
- LUA_GCSETPAUSE : устанавливает data , как новое значение для паузы сборщика (см. §2.5), и возвращает предыдущее значение паузы.
- LUA_GCSETSTEPMUL : устанавливает data , как новое значение для множителя шагов сборщика (см. §2.5), и возвращает предыдущее значение множителя шагов.
- LUA_GCISRUNNING : возвращает логическое значение, которое говорит, что сборщик запущен (т.е., не остановлен).
Для более подробного описания опций, см. collectgarbage .
lua_getallocf
Возвращает функцию выделения памяти для данного Lua состояния. Если ud не NULL , Lua записывает в *ud непрозрачный указатель, полученный когда устанавливалась функция выделения памяти.
lua_getfield
Ложит в стек значение t[k] , где t — значение по индексу index. Как и в Lua, эта функция может запускать метаметод для события «index» (см. §2.4).
Возвращает тип положенного на стек значения.
lua_getextraspace
Возвращает указатель на область «сырой» (raw) памяти, ассоциированную с данным Lua состоянием. Приложение может использовать эту область для любых целей; Lua не использует эту область.
Каждый новый поток имеет такую область, инициализированную копией области главного потока.
По умолчанию, эта область имеет размер пустого указателя [ sizeof(void*) ], но вы можете перекомпилировать Lua с другим размером для этой области (см. LUA_EXTRASPACE в luaconf.h ).
lua_getglobal
Ложит в стек значение глобальной переменной name . Возвращает тип этого значения.
lua_geti
Ложит в стек значение t[i] , где t — значение по индексу index. Как и в Lua, эта функция может запускать метаметод для события «index» (см. §2.4).
Возвращает тип положенного на стек значения.
lua_getmetatable
Если значение по индексу index имеет метатаблицу, функция ложит эту метатаблицу на стек и возвращает 1. Иначе, функция возвращает 0 и ничего не ложит на стек.
lua_gettable
Ложит на стек значение t[k] , где t — значение по индексу index и k — значение на вершине стека.
Эта функция снимает ключ со стека и ложит результирующее значение на его место. Как и в Lua, эта функция может запускать метаметод для события «index» (см. §2.4).
Возвращает тип положенного на стек значения.
lua_gettop
Возвращает индекс элемента на вершине стека. Т.к. индексы начинаются с 1, результат равен количеству элементов в стеке; в частности, 0 означает, что стек пуст.
lua_getuservalue
Ложит на стек Lua значение ассоциированное с пользовательскими данными (userdata), находящимися по индексу index.
Возвращает тип положенного на стек значения.
lua_insert
Перемещает верхний элемент стека в полученный правильный индекс, сдвигая вверх элементы выше этого индекса. Эта функция не может быть использована с псевдоиндексом, т.к. псевдоиндекс не обозначает актуальной позиции на стеке.
lua_Integer
Тип целых в Lua.
По умолчанию, это тип long long , (обычно 64-битное целое), но это может быть изменено в long или int (обычно 32-битное целое). (см. LUA_INT_TYPE в luaconf.h .)
Lua также определяет константы LUA_MININTEGER и LUA_MAXINTEGER , с минимальным и максимальным значениями для этого типа.
lua_isboolean
Возвращает 1, если значение по индексу index имеет тип boolean, иначе возвращает 0.
lua_iscfunction
Возвращает 1, если значение по индексу index это C функция, иначе возвращает 0.
lua_isfunction
Возвращает 1, если значение по индексу index это функция (любая C или Lua), иначе возвращает 0.
lua_isinteger
Возвращает 1, если значение по индексу index это целое (т.е., это число и оно представлено как целое [integer]), иначе возвращает 0.
lua_islightuserdata
Возвращает 1, если значение по индексу index это легкие пользовательские данные (light userdata), иначе возвращает 0.
lua_isnil
Возвращает 1, если значение по индексу index это nil, иначе возвращает 0.
lua_isnone
Возвращает 1, если полученный индекс не правильный, иначе возвращает 0.
lua_isnoneornil
Возвращает 1, если полученный индекс не правильный или значение по индексу это nil, иначе возвращает 0.
lua_isnumber
Возвращает 1, если значение по индексу index это число или строка конвертируемая в число, иначе возвращает 0.
lua_isstring
Возвращает 1, если значение по индексу index это строка или число (которое всегда можно преобразовать в строку), иначе возвращает 0.
lua_istable
Возвращает 1, если значение по индексу index это таблица, иначе возвращает 0.
lua_isthread
Возвращает 1, если значение по индексу index это поток (thread), иначе возвращает 0.
lua_isuserdata
Возвращает 1, если значение по индексу index это пользовательские данные (любые полные или легкие), иначе возвращает 0.
lua_isyieldable
Возвращает 1, если данная сопрограмма может уступить (yield), иначе возвращает 0.
lua_KContext
Тип для контекста функции продолжения. Он должен быть числовым типом. Этот тип определен как intptr_t , когда intptr_t доступен, так что может содержать и указатели. Иначе, тип определен как ptrdiff_t .
lua_KFunction
Тип для функций продолжения (см. §4.7).
lua_len
Возвращает длину значения по индексу index. Это эквивалент Lua оператору ‘ # ‘ (см. §3.4.7) и может вызывать метаметод для события «length» (см. §2.4). Результат ложится на стек.
lua_load
Загружает Lua кусок без запуска его на исполнение. Если ошибок нет, lua_load ложит на стек скомпилированный кусок, как Lua функцию. Иначе, ложит на стек сообщение об ошибке.
- LUA_OK : нет ошибок;
- LUA_ERRSYNTAX : синтаксическая ошибка при компиляции;
- LUA_ERRMEM : ошибка выделения памяти;
- LUA_ERRGCMM : ошибка при выполнении метаметода __gc . (Эта ошибка не имеет отношения к загружаемому куску. Она генерируется сборщиком мусора.)
Функция lua_load использует пользовательскую функцию reader для чтения куска (см. lua_Reader ). Аргумент data — это непрозрачный указатель, передаваемый функции reader.
Аргумент chunkname дает куску имя, которое используется для сообщений об ошибках и в отладочной информации (см. §4.9).
lua_load автоматически определяет, когда кусок текст или бинарные данные, и соответственно загружает его (см. программу luac ). Строка mode работает как и в функции load , с добавлением того, что значение NULL эквивалентно строке » bt «.
lua_load использует стек непосредственно, поэтому функция reader всегда должна оставлять его неизменным после возвращения.
Если результирующая функция имеет внешние локальные переменные (upvalue), её первое upvalue устанавливается в значение глобального окружения, записанное в реестре по индексу LUA_RIDX_GLOBALS (см. §4.5). При загрузке главных кусков, это upvalue будет переменной _ENV (см. §2.2). Остальные upvalue инициализируются значением nil.
lua_newstate
Создает новый поток, выполняющийся в новом независимом состоянии. Возвращает NULL , если не может создать поток или состояние (из-за нехватки памяти). Аргумент f — функция выделения памяти; Lua выполняет всё выделение памяти для данного состояния через эту функцию. Второй аргумент, ud — это непрозрачный указатель, который Lua передает в функцию выделения памяти при каждом вызове.
lua_newtable
Создает новую пустую таблицу и ложит её на стек. Эквивалентно вызову lua_createtable(L, 0, 0) .
lua_newthread
Создает новый поток, ложит его на стек и возвращает указатель на lua_State , который представляет этот новый поток. Новый поток использует одно глобальное окружение с оригинальным потоком, но имеет независимый стек исполнения.
Не существует явной функции для закрытия или уничтожения потока. Потоки это субъект для сборки мусора, как и любой Lua объект.
lua_newuserdata
Функция выделяет новый блок памяти размером size, ложит на стек новый объект full userdata (полные пользовательские данные) с адресом этого блока, и возвращает этот адрес. Хостовая программа может свободно использовать эту память.
lua_next
Снимает ключ со стека, ложит пару ключ-значение из таблицы, находящейся по индексу index («следующая» пара после данного ключа). Если в таблице больше нет элементов, lua_next возвращает 0 (и ничего не ложит на стек).
Типичный перебор элементов таблицы выглядит так:
Когда производится перебор таблицы, не вызывайте lua_tolstring прямо на ключе, пока не убедитесь, что ключ действительно строка. Помните, что lua_tolstring может изменить значение на полученном индексе; это собьет следующий вызов lua_next .
Смотри функцию next для предостережений о модификации таблицы во время её перебора.
lua_Number
Тип вещественных чисел в Lua.
По умолчанию, это тип double, но он может быть изменен в single float или long double (см. LUA_FLOAT_TYPE в luaconf.h ).
lua_numbertointeger
Преобразует вещественное Lua в целое Lua. Этот макрос предполагает, что n имеет целое значение. Если это значение входит в диапазон целых Lua, оно конвертируется в целое и назначается в *p . Макрос возвращает логическое значение, указывающее, что преобразование успешно. (Учтите, что из-за округлений эта проверка диапазона может быть мудрёной, чтобы сделать её корректно без этого макроса.)
Этот макрос может вычислять свои аргументы несколько раз.
lua_pcall
Вызывает функцию в защищенном режиме.
Оба nargs и nresults имеют тоже значение, что и в lua_call . Если в течение вызова нет ошибок, lua_pcall действует точно как lua_call . Тем не менее, в случае любых ошибок, lua_pcall перехватывает их, ложит одно значение на стек (собщение об ошибке) и возвращает код ошибки. Как и lua_call , lua_pcall всегда удаляет функцию и её аргументы со стека.
Если msgh = 0, сообщение об ошибке, возвращенное на стек, это оригинальное сообщение об ошибке. Иначе, msgh — это стековый индекс обработчика ошибок. (Этот индекс не может быть псевдоиндексом.) В случае ошибок выполнения, эта функция будет вызвана с сообщением об ошибке и значение, которое она вернет, будет возвращено на стеке функцией lua_pcall .
Обычно обработчик ошибок используется чтобы добавить больше отладочной информации в сообщение об ошибке, такой как трассировка стека. Эта информация не может быть получена после возврата из lua_pcall , поскольку стек будет ракручен.
- LUA_OK (0): успех.
- LUA_ERRRUN : ошибка выполнения.
- LUA_ERRMEM : ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик ошибок.
- LUA_ERRERR : ошибка при выполнении обработчика ошибок.
- LUA_ERRGCMM : ошибка при выполнении метаметода __gc . (Эта ошибка обычно не имеет отношения к вызываемой функции.)
lua_pcallk
Функция аналогична lua_pcall , но позволяет вызванной функции уступать (см. §4.7).
lua_pop
Снимает n элементов со стека.
lua_pushboolean
Ложит на стек логическое значение (boolean) равное b .
lua_pushcclosure
Ложит на стек новое C замыкание.
Когда C функция создана, можно ассоциировать с ней несколько значений, таким образом создав C замыкание (closure) (см. §4.4); эти значения доступны функции во время вызова. Чтобы ассоциировать эти значениея с C функцией, сначала эти значения нужно положить на стек (первое значение ложится первым). Затем вызвать lua_pushcclosure для создания C функции на стеке, с аргументом n , сообщающим сколько значений будет ассоциировано с функцией. lua_pushcclosure снимает эти значения со стека.
Максимальное значение для n это 255.
Когда n = 0, эта функция создает лёгкую C функцию, которая является лишь указателем на C функцию. В этом случае, она никогда не вызывает ошибку памяти.
lua_pushcfunction
Ложит C функцию на стек. Эта функция принимает указатель на C функцию и ложит в стек Lua значение типа function , которое при вызове запускает соответствующую C функцию.
Любая функция, чтобы быть работоспособной в Lua, должна следовать корректному протоколу приема параметров и возврата результатов (см. lua_CFunction ).
lua_pushfstring
- Вы не выделяете место для результата: результат Lua строка и Lua заботится о выделении памяти (и её освобождении, через сборку мусора).
- Спецификаторы преобразований ограничены. Здесь нет флагов, ширины или точности. Спецификаторы могут быть только следующими: ‘ %% ‘ (вставляет символ ‘ % ‘), ‘ %s ‘ (вставляет строку завершаемую нулем, без ограничений по размеру), ‘ %f ‘ (вставляет lua_Number ), ‘ %I ‘ (вставляет lua_Integer ), ‘ %p ‘ (вставляет указатель как шестнадцатиричное число), ‘ %d ‘ (вставляет int ), ‘ %c ‘ (вставляет int как однобайтовый символ), ‘ %U ‘ (вставляет long int как байтовую последовательность UTF-8).
lua_pushglobaltable
Ложит глобальное окружение в стек.
lua_pushinteger
Ложит на стек целое равное n .
lua_pushlightuserdata
Ложит на стек легкие пользовательские данные (light userdata).
Пользовательские данные представляют C значения в Lua. Легкие пользовательские данные предсталяют указатель, void* . Это значение (как число): вы не создаете его, оно не имеет индивидуальной метатаблицы, и не уничтожается сборщиком (т.к. никогда не создаётся). Легкие пользовательские данные равны «любым» легким пользовательским данным с тем же C адресом.
lua_pushliteral
Этот макрос аналогичен lua_pushstring , но должен использоваться только, когда s это литеральная строка.
lua_pushlstring
Ложит на стек строку, указанную s , размером len . Lua создает (или использует снова) внутреннюю копию данной строки, так что после завершения функции память по адресу s может быть освобождена или использована снова. Строка может содержать любые бинарные данные, в том числе встроенные нули.
Возвращает указатель на внутреннюю копию строки.
lua_pushnil
Ложит на стек значение nil.
lua_pushnumber
Ложит на стек вещественное число равное n .
lua_pushstring
Ложит на стек завершаемую нулем строку, указанную s . Lua создает (или использует снова) внутреннюю копию данной строки, так что после завершения функции память по адресу s может быть освобождена или использована снова.
Возвращает указатель на внутреннюю копию строки.
Если s = NULL , ложит nil и возвращает NULL .
lua_pushthread
Ложит на стек поток, представленный Lua состоянием L . Возвращает 1, если поток является главным потоком состояния.
lua_pushvalue
Ложит на стек копию элемента по индексу index.
lua_pushvfstring
Аналогично lua_pushfstring , за исключением того, что фунцкция получает va_list вместо переменного числа аргументов.
lua_rawequal
Возвращает 1, если два значения по индексам index1 и index2 примитивно равны (т.е. без вызова метаметодов). Иначе возвращает 0. Также возвращает 0, если любой из индексов не правильный.
lua_rawget
Аналогично lua_gettable , но производит «сырой» доступ (т.е. без вызова метаметодов).
lua_rawgeti
Ложит на стек значение t[n] , где t — таблица по индексу index. Доступ «сырой», т.е. без вызова метаметодов.
Возвращает тип положенного на стек значения.
lua_rawgetp
Ложит на стек значение t[k] , где t — таблица по индексу index, k — указатель p , представленный как лёгкие пользовательские данные. Доступ «сырой», т.е. без вызова метаметодов.
Возвращает тип положенного на стек значения.
lua_rawlen
Возвращет сырую «длину» значения по индексу index: для строк это длина строки; для таблиц это результат оператора длины (‘ # ‘) без метаметодов; для пользовательских данных это размер выделенного блока памяти; для остальных значений это 0.
lua_rawset
Аналогично lua_settable , но производит «сырое» присваивание (т.е. без вызова метаметодов).
lua_rawseti
Действие аналогично t[i] = v , где t — таблица по индексу index, v — значение на вершине стека.
Эта функция снимает значение со стека. Присваивание «сырое», т.е. без вызова метаметодов.
lua_rawsetp
Действие аналогично t[p] = v , где t — таблица по индексу index, p — кодируется как легкие пользовательские данные, v — значение на вершине стека.
Эта функция снимает значение со стека. Присваивание «сырое», т.е. без вызова метаметодов.
lua_Reader
Функция reader использется в lua_load . Каждый раз, когда требуется следующая часть куска, lua_load вызывает функцию reader, передавая ей свой параметр data . Функция reader должна возвращать указатель на блок памяти с новой частью куска и устанавливать size равным размеру блока. Блок должен существовать, пока функция reader не будет вызвана снова. Для сигнала о конце куска, функция должна вернуть NULL или установить size равным 0. Функция reader может возвращать части любого размера больше нуля.
lua_register
Устанавливает C функцию f в качестве нового значения глобальной переменной name . Функция определена как макрос:
lua_remove
Удаляет элемент по данному правильному индексу, сдвигая вниз элементы выше этого индекса, чтобы заполнить промежуток. Эта функция не может быть вызвана с псевдоиндексом, т.к. псевдоиндекс не является действительной позицией в стеке.
lua_replace
Перемещяет элемент с вершины стека в позицию по правильному индексу index без сдвига элементов (следовательно, заменяя значение по данному индексу) и затем снимает вехний элемент со стека.
lua_resume
Запускает и продолжает сопрограмму в данном потоке L .
Для запуска подпрограммы, вы ложите в стек потока главную функцию и её аргументы; затем вызываете lua_resume , nargs — количество аргументов. Этот вызов возвращается, когда сопрограмма приостанавливается или завершается. Когда функция возвращается, стек содержит все значения, переданные в lua_yield , или все значения, возвращенные телом функции. lua_resume возвращает LUA_YIELD — если сопрограмма уступила, LUA_OK — если сопрограмма завершила свое исполнение без ошибок, или код ошибки в случае ошибок (см. lua_pcall ).
В случае ошибок, стек не раскручивается, так вы можете использовать отладочные API на нём. Сообщение об ошибке находится на вершине стека.
Чтобы продолжить сопрограмму, вы удаляете все результаты из последнего lua_yield , ложите в её стек только значения, передаваемые в качестве результатов из yield , и затем вызываете lua_resume .
Параметр from представляет сопрограмму, которая продолжает L . Если такой сопрограммы нет, этот параметр может быть равен NULL .
lua_rotate
Вращает элементы стека между правильным индексом idx и вершиной стека. Элементы вращаются на n позиций по направлению к вершине стека, для позитивного n ; или -n позиций в направлении дна стека, для отрицательного n . Абсолютное значение n должно быть не больше чем размер вырезки для вращения. Эта функция не может быть вызвана с псевдоиндексом, т.к. псевдоиндекс не является действительной позицией в стеке.
lua_setallocf
Заменяет функцию выделения памяти данного состояния на функцию f с пользовательскими данными ud .
lua_setfield
Действие аналогично t[k] = v , где t — таблица по индексу index, v — значение на вершине стека.
Эта функция снимает значение со стека. Как и в Lua, эта функция может запускать метаметод для события «newindex» (см. §2.4).
lua_setglobal
Снимает значение со стека и устанавливает его в качестве нового значения глобальной переменной name .
lua_seti
Действие аналогично t[n] = v , где t — значение по индексу index, v — значение на вершине стека.
Эта функция снимает значение со стека. Как и в Lua, эта функция может запускать метаметод для события «newindex» (см. §2.4).
lua_setmetatable
Снимает таблицу со стека и устанавливает её в качестве новой метатаблицы для значения по индексу index.
lua_settable
Действие аналогично t[k] = v , где t — значение по индексу index, v — значение на вершине стека, k — значение следующее за верхним.
Эта функция снимает со стека ключ и значение. Как и в Lua, эта функция может запускать метаметод для события «newindex» (см. §2.4).
lua_settop
Принимает любой индекс или 0, и устанавливает вершину стека равной этому индексу. Если новая вершина больше предыдущей, новые элементы заполняются значением nil. Если index = 0, то все элементы стека удаляются.
lua_setuservalue
Снимает значение со стека и устанавливает его в качестве нового значения, ассоциированного с пользовальскими данными (userdata) по индексу index.
lua_State
Непрозрачная структура, которая указывает на поток и косвенно (через поток) на целое состояние интерпретатора Lua. Библиотека Lua полностью повторно входимая: она не имеет глобальных переменных. Вся информация о состоянии доступна через эту структуру.
Указатель на эту структуру должен передаваться, как первый аргумент, в каждую функцию в библиотеке, за исключением lua_newstate , которая создает Lua состояние.
lua_status
Возвращает состояние потока L .
Статус может быть 0 ( LUA_OK ) — для нормального потока, код ошибки — если поток завершил выполнение lua_resume с ошибкой, или LUA_YIELD — если поток приостановлен.
Вы можете вызывать функции только в потоках со статусом LUA_OK . Вы можете продолжать потоки со статусом LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для продолжения сопрограммы).
lua_stringtonumber
Преобразует завершаемую нулем строку s в число, ложит это число на стек и возвращает общий размер строки, т.е. её длину + 1. Результатом преобразования может быть целое или вещественное число, в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак. Если строка не правильное число, функция возвращает 0 и ничего не ложит на стек. (Имейте ввиду, что результат может быть использован как логическое значение, если преобразование успешно, то результат true.)
lua_toboolean
Преобразует Lua значение по индексу index в C boolean (0 или 1). Как и все проверки в Lua, lua_toboolean возвращает true для любого Lua значения отличного от false и nil; иначе, возвращает false. (Если вы хотите принимать только значения типа boolean, используйте lua_isboolean для проверки.)
lua_tocfunction
Преобразует Lua значение по индексу index в C функцию. Это значение должно быть C функцией; иначе, возвращает NULL .
lua_tointeger
Эквивалент lua_tointegerx с isnum = NULL .
lua_tointegerx
Преобразует Lua значение по индексу index в целое со знаком типа lua_Integer . Lua значение должно быть целым, или числом или строкой, преобразуемой в целое (см. §3.4.3); иначе, lua_tointegerx возвращает 0.
Если isnum != NULL , он указывает на логическое значение, которое показывает успешность операции.
lua_tolstring
Преобразует Lua значение по индексу index в C строку. Если len != NULL , она также устанавливает *len равным длине строки. Lua значение должно быть строкой или числом; иначе, функция возвращает NULL . Если значение число, то lua_tolstring также изменяет действительное значение в стеке в строку. (Это изменение сбивает lua_next , когда lua_tolstring применяется к ключам при переборе таблицы.)
lua_tolstring возвращает полностью выровненный указатель на строку внутри Lua состояния. Эта строка всегда имеет завершающий ноль (‘ \0 ‘) после последнего символа (как в C), но может содержать другие нули в своем теле.
Т.к. в Lua есть сборка мусора, нет гарантии, что указатель, возвращенный lua_tolstring , будет действителен после удаления соответствующего Lua значения из стека.
lua_tonumber
Эквивалент lua_tonumberx с isnum = NULL .
lua_tonumberx
Преобразует Lua значение по индексу index в C тип lua_Number (см. lua_Number ). Lua значение должно быть числом или строкой, преобразуемой в число (см. §3.4.3); иначе, lua_tonumberx возвращает 0.
Если isnum != NULL , он указывает на логическое значение, которое показывает успешность операции.
lua_topointer
Преобразует Lua значение по индексу index в пустой C указатель ( void* ). Значение может быть пользовательскими данными, таблицей, потоком или функцией; иначе, lua_topointer возвращает NULL . Разные объекты дадут разные указатели. Не существует способа сконвертировать указатель обратно в оригинальное значение.
Обычно эта функция используется для хеширования и отладочной информации.
lua_tostring
Эквивалент lua_tolstring с len = NULL .
lua_tothread
Преобразует Lua значение по индексу index в Lua поток (представленный как lua_State* ). Это значение должно быть потоком; иначе, функция возвращает NULL .
lua_touserdata
Если значение по индексу index это полные пользовательские данные, возвращает адрес их блока. Если значение это легкие пользовательские данные, возвращает их указатель. Иначе, возвращает NULL .
lua_type
Возвращает тип значения по правильному индексу index, или LUA_TNONE для не правильного (но допустимого) индекса. Типы, возвращаемые lua_type , кодируются следующими константами (определены в lua.h ): LUA_TNIL (0), LUA_TNUMBER , LUA_TBOOLEAN , LUA_TSTRING , LUA_TTABLE , LUA_TFUNCTION , LUA_TUSERDATA , LUA_TTHREAD и LUA_TLIGHTUSERDATA .
lua_typename
Возвращает имя типа, кодированного значением tp , которое должно быть одним из возвращаемых lua_type .
lua_Unsigned
lua_upvalueindex
Возвращает псевдоиндекс, который представляет i -е upvalue запущенной функции (см. §4.4).
lua_version
Возвращает адрес номера версии, хранящейся в ядре Lua. Когда вызвана с правильным lua_State , возвращает адрес версии, использованной для создания этого состояния. Когда вызвана с NULL , возвращает адрес версии выполнившей вызов.
lua_Writer
Тип функции writer, используемой в lua_dump . Каждый раз, когда производится очередная часть куска, lua_dump вызывает функцию writer, передавая ей буфер для записи ( p ), его размер ( sz ) и параметр data , переданный в lua_dump .
Функция writer возвращает код ошибки; 0 означает нет ошибок; любое другое значение означает ошибку и останавливает lua_dump от последующих вызовов writer.
lua_xmove
Обмен значениями между разными потоками одного состояния.
Эта функция снимает со стека from n значений и ложит их в стек to .
lua_yield
Функция аналогична lua_yieldk , но она не имеет продолжения (см. §4.7). Следовательно, когда поток продолжается, он продолжает функцию, которая вызвала lua_yield .
lua_yieldk
Устапает сопрограмму (поток).
Когда C функция вызывает lua_yieldk , вызывающая сопрограмма приостанавливает свое исполнение, и вызов lua_resume , который запустил эту сопрограмму, возвращается. Параметр nresults — это количество значений в стеке, которые будут переданы как результаты в lua_resume .
Когда сопрограмма снова возобновится, Lua вызывает переданную функцию продолжения k , для продолжения выполнения C функции, которая уступила (см. §4.7). Эта функция продолжения получает тот же стек из предыдущей функции, но n результатов будут удалены и заменены аргументами, переданными в lua_resume . Кроме того, функция продолжения получает значение ctx , переданное в lua_yieldk .
Обычно эта функция не возвращается; когда сопрограмма в конечном счете возобновляется, она выполняет фукнцию продолжения. Тем не менее, есть один специальный случай, который случается когда функция вызвана из построчного перехватчика (см. §4.9). В этом случает, lua_yieldk должна быть вызвана без продолжения (вероятно в форме lua_yield ), и перехватчик должен вернуться непосредственно после вызова. Lua уступит и, когда сопрограмма вновь возобновится, она продолжит нормальное исполнение (Lua) функции, которая инициировала перехват.
Эта функция может вызывать ошибку, если вызвана из потока с незаконченным C вызовом без функции продолжения, или если вызвана из потока, который не запущен внутри сопрограммы (т.е., главный поток).
4.9 – Отладочный интерфейс
Lua не имеет встроенных отладочных средств. Взамен, он предлагает специальный интерфейс функций и перехватчиков (hook). Этот интерфейс позволяет строить различные типы отладчиков, профилировщиков и других инструментов, нуждающихся во «внутренней информации» интерпретатора.
lua_Debug
Структура, используемая для хранения различных частей информации о функции или о записи активации. lua_getstack заполняет только приватную часть этой структуры, для последующего использования. Для заполнения остальных полей lua_Debug полезной информацией, вызовите lua_getinfo .
- source : имя куска, который создал функцию. Если source начинается с ‘ @ ‘, это означает, что функция была определена в файле, где имя файла следует за символом ‘ @ ‘. Если source начинается с ‘ = ‘, остаток его содержимого описывает источник в определяемой пользователем форме. Иначе, функция была определена в строке, где source — эта строка.
- short_src : «выводимая» (printable) версия source , для использования в сообщениях об ошибках.
- linedefined : номер строки, где начинается определение функции.
- lastlinedefined : номер строки, где заканчивается определение функции.
- what : строка «Lua» — если функция это Lua функция, «C» — если это C функция, «main» — если это главная часть куска.
- currentline : текущая строка, где полученная функция исполняется. Когда информация о строках не доступна, currentline устанавливается равным -1.
- name : разумное имя полученной функции. Т.к. функции в Lua это первоклассные значения, они не имеют фиксированных имен: некоторые функции могут быть значениями множества глобальных переменных, тогда как другие могут храниться только в полях таблицы. Чтобы найти подходящее имя lua_getinfo проверяет как функция была вызвана. Если она не может найти имя, то name устанавливается равным NULL .
- namewhat : поясняет поле name . Значение namewhat может быть «global» , «local» , «method» , «field» , «upvalue» или «» (пустая строка), в соответствии с тем как была вызвана функция. (Lua использует пустую строку, когда не может применить ни какую другую опцию.)
- istailcall : истина, если этот вызов функции хвостовой (tail call). В этом случае, вызывающий этого уровня не на стеке.
- nups : количество upvalue у функции.
- nparams : количество фиксированных параметров у функции (всегда 0 для C функций).
- isvararg : истина, если функция имеет переменное число аргументов (всегда истина для C функций).
lua_gethook
Возвращает текущую функцию перехватчик.
lua_gethookcount
Возвращает количество перехватчиков.
lua_gethookmask
Возвращает текущую маску перехватов.
lua_getinfo
Предоставляет информацию о специфической функции или о вызове функции.
Для получения информации о вызове функции, параметр ar должен быть правильной записью активации, которая заполняется вызовом lua_getstack или передается как аргумент в перехватчик (см. lua_Hook ).
Для получения информации о функции, нужно положить её в стек и начать строку what символом ‘ > ‘. (В этом случае, lua_getinfo снимет функцию с вершины стека.) Например, чтобы узнать в которой строке определена функция f , вы можете написать следующий код:
- ‘ n ‘: заполняет поля name и namewhat ;
- ‘ S ‘: заполняет поля source , short_src , linedefined , lastlinedefined и what ;
- ‘ l ‘: заполняет поле currentline ;
- ‘ t ‘: заполняет поле istailcall ;
- ‘ u ‘: заполняет поля nups , nparams и isvararg ;
- ‘ f ‘: ложит в стек функцию, которая запущена на данном уровне;
- ‘ L ‘: ложит в стек таблицу, индексы которой — это номера значимых строк функции. (Значимая строка — это строка с некоторым кодом, т.е. строка, где можно поставить точку останова [break point]. Не значащие строки — это пустые строки и комментарии.)
Эта функция возвращает 0 при ошибке (например, при неправильной опции в строке what ).
lua_getlocal
Предоставляет информацию о локальной переменной данной записи активации или функции.
В первом случае, параметр ar должен быть правильной записью активации, которая заполнена предыдущим вызовом lua_getstack или передана как аргумент перехватчику (см. lua_Hook ). Индекс n выбирает локальную переменную для проверки; см. debug.getlocal для подробностей о индексах и именах переменных.
lua_getlocal ложит в стек значение переменной и возвращает её имя.
Во втором случае, ar должен быть NULL , и функция для проверки должна находиться на вершине стека. В этом случае, видны только параметры Lua функций (т.к. здесь нет информации о том, какие переменные активны) и значения в стек не ложатся.
Возвращает NULL (и ничего не ложит на стек), когда индекс больше чем количество активных локальных переменных.
lua_getstack
Предоставляет информацию о исполняемом (runtime) стеке интерпретатора.
Эта функция заполняет части структуры lua_Debug с индентификацией записи активации функции, выполняемой на данном уровне (level). Уровень 0 — это текущая выполняющаяся функция, уровень n+1 — это функция которая вызывает уровень n (за исключением хвостовых вызовов, которые не считаются на стеке). Когда ошибок нет, lua_getstack возвращает 1; когда вызвана с уровнем больше чем глубина стека, возвращает 0.
lua_getupvalue
Предоставляет информацию о n -ном upvalue замыкания по индексу funcindex . Функция ложит на стек значение upvalue и возвращает его имя. Возвращает NULL (и ничего не ложит на стек), когда индекс n больше количества upvalue.
Для C функций, эта функция использует пустую строку «» в качестве имени для всех upvalue. (Для Lua функций, upvalue — это внешние локальные переменные, которые использует функция, и которые, следовательно, включены в её замыкание.)
Upvalue не имеют конкретного порядка, как они активны внутри функции. Они нумеруются в произвольном порядке.
lua_Hook
Тип для отладочных функций перехватчиков.
Всякий раз, когда вызывается перехватчик, его аргумент ar имеет поле event , установленное согласно событию, вызвавшему срабатывание перехватчика. Lua идентифицирует эти события следующими константами: LUA_HOOKCALL , LUA_HOOKRET , LUA_HOOKTAILCALL , LUA_HOOKLINE и LUA_HOOKCOUNT . Более того, для событий строк устанавливается поле currentline . Для получения значений остальных полей в ar , перехватчик должен вызвать lua_getinfo .
Для событий вызова, event может быть LUA_HOOKCALL — нормальное значение, или LUA_HOOKTAILCALL — для хвостового вызова; в этом случае, соответствующего события возврата не будет.
Пока Lua выполняет перехватчик, все остальные перехватчики отключаются. Следовательно, если перехватчик вызывает Lua для выполнения функции или куска, это выполнение произойдет без вызова перехватчиков.
Функции перехватчики не могут иметь продолжений, т.е. они не могут вызывать lua_yieldk , lua_pcallk или lua_callk с не нулевым k .
Функции перехватчики могут уступать при следующих условиях: только счетные и события строк могут уступать; для уступки, функция перехватчик должна завершить свое исполнение, вызвав lua_yield с nresults = 0 (т.е. без значений).
lua_sethook
Устанавливает отладочную функцию-перехватчик.
- Перехватчик вызова (call hook): вызывается, когда интерпретатор вызывает функцию. Перехватчик вызывается сразу после того, как Lua войдет в новую функцию, перед тем как функция получит свои аргументы.
- Перехватчик возврата (return hook): вызывается, когда интерпретатор возвращается из функции. Перехватчик вызывается перед тем, как Lua покинет функцию. Здесь нет стандартного пути для доступа к возвращаемым функцией значениям.
- Перехватчик строки (line hook): вызывается, когда интерпретатор начинает выполнение новой строки кода, или когда он переходит назад в код (даже в ту же строку). (Это событие случается только пока Lua выполняет Lua функцию.)
- Счетный перехватчик (count hook): вызывается после того, как интерпретатор запустит count инструкций. (Это событие случается только пока Lua выполняет Lua функцию.)
Перехват отключается установкой mask = 0.
lua_setlocal
Устанавливает значение локальной переменной в данной записи активации (ar). Устанавливает переменной значение с вершины стека и возвращает её имя, затем удаляет значение из стека.
Возвращает NULL (и ничего не удаляет со стека), когда индекс больше количества активных локальных переменных.
Параметры ar и n такие же, как в функции lua_getlocal .
lua_setupvalue
Устанавливает значение для upvalue замыкания. Устанавливает upvalue равным значению с вершины стека и возвращает её имя, затем удаляет значение из стека
Возвращает NULL (и ничего не удаляет со стека), когда индекс больше количества upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue .
lua_upvalueid
Возвращает уникальный идентификатор для upvalue под номером n из замыкания по индексу funcindex .
Эти уникальные идентификаторы позволяют программе проверить, когда замыкания совместно используют upvalue. Lua замыкания, которые совместно используют upvalue (т.е., обращаются к одной внешней локальной переменной), вернут одинаковые идентификаторы для индексов своих upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue , но n не может быть больше количества upvalue.
lua_upvaluejoin
Делает n1 -ое upvalue Lua замыкания по индексу funcindex1 ссылкой на n2 -ое upvalue Lua замыкания по индексу funcindex2 .
5 – Вспомогательная библиотека
Вспомогательная библиотека предоставляет различные удобные функции для взаимодействия C с Lua. Когда базовые API предоставляют примитивные функции для всех взаимодействий между C и Lua, вспомогательная библиотека предоставляет высокоуровневые функции для некоторых общих задач.
Все функции и типы вспомогательной библиотеки определены в заголовочном файле lauxlib.h и имеют префикс luaL_ .
Все функции вспомогательной библиотеки строятся из базовых API, и так они не предоставляют ничего, чего нельзя было бы сделать с помощью этих API. Тем не менее, использование вспомогательной библиотеки гарантирует большую стабильность вашему коду.
Различные функции вспомогательной библиотеки используют внутри несколько дополнительных слотов. Когда функция вспомогательной библиотеки использует меньше пяти слотов, она не проверяет размер стека; она просто предполагает, что там достаточно слотов.
Различные функции вспомогательной библиотеки используются для проверки аргументов C функций. Так как сообщение об ошибке формируется для аргументов (т.е., » bad argument #1 «), вы не должны использовать эти функции для других значений стека.
Функции luaL_check* всегда генерируют ошибку, если проверка не удовлетворена.
5.1 – Функции и типы
Здесь представлен список всех функций и типов вспомогательной библиотеки в алфавитном порядке.
luaL_addchar
Добавляет байт c в буфер B (см. luaL_Buffer ).
luaL_addlstring
Добавляет строку по указателю s длиной l в буфер B (см. luaL_Buffer ). Строка может содержать встроенные нули.
luaL_addsize
Добавляет в буфер B (см. luaL_Buffer ) строку длиной n , прежде скопированную в область буфера (см. luaL_prepbuffer ).
luaL_addstring
Добавляет завершаемую нулем строку по указателю s в буфер B (см. luaL_Buffer ).
luaL_addvalue
Добавляет значение с вершины стека в буфер B (см. luaL_Buffer ). Снимает значение со стека.
Только эта функция для строковых буферов может (и должна) вызываться с дополнительным аргументом на стеке, являющимся значением для добавления в буфер.
luaL_argcheck
Проверяет когда cond истина. Если это не так, генерирует ошибку со стандартным сообщением (см. luaL_argerror ).
luaL_argerror
Генерирует ошибку, сообщающую о проблеме с аргументом arg для C функции, которая вызвала luaL_argerror. Используется стандартное сообщение, включающее extramsg как комментарий:
Эта функция никогда не возвращается.
luaL_Buffer
Тип для строкового буфера.
- Сначала объявляется переменная b типа luaL_Buffer .
- Затем она инициализируется вызовом luaL_buffinit(L, &b) .
- Затем части строки добавляются в буфер вызовами функций luaL_add* .
- Завершается вызовом luaL_pushresult(&b) . Этот вызов оставляет финальную строку на вершине стека.
- Сначала объявляется переменная b типа luaL_Buffer .
- Затем вызовом luaL_buffinitsize(L, &b, sz) она инициализируется, и для неё выделяется память размером sz .
- Затем в эту область копируется строка.
- Завершается вызовом luaL_pushresultsize(&b, sz) , где sz — размер результирующей строки, скопированной в эту область.
При нормальном управлении, строковый буфер использует переменное число слотов стека. Так, пока используется буфер, вы не можете предполагать, что вы знаете где вершина стека. Вы можете использовать стек между успешными вызовами буферных операций, пока он сбалансирован; т.е., когда вы вызываете буферную операцию, стек должен быть на том же уровне, что и непосредственно после предыдущей буферной операции. (Существует только одно исключение, это luaL_addvalue .) После вызова luaL_pushresult стек возвращается на тот уровень, когда был инициализирован буфер, плюс результирующая строка на вершине.
luaL_buffinit
Инициализирует буфер B . Эта функция не выделяет память; буфер должен быть определен как переменная (см. luaL_Buffer ).
luaL_buffinitsize
luaL_callmeta
Если объект по индексу obj имеет метатаблицу и его метатаблица имеет поле e , эта функция вызывает это поле, передавая объект в качестве первого аргумента. В этом случае функция возвращает true и ложит в стек значение, возвращенное вызовом метаметода. Если метатаблицы или метаметода не существует, функция возвращает false (и ничего не ложит на стек).
luaL_checkany
Проверяет, что функция имеет аргумент любого типа (включая nil) по индексу arg .
luaL_checkinteger
Проверяет, что аргумент функции arg это целое (или может быть преобразован в целое), и возвращает это целое, как lua_Integer .
luaL_checklstring
Проверяет, что аргумент функции arg это строка, и возвращает эту строку; если l не NULL , пишет в *l длину строки.
Эта функция использует lua_tolstring для получения результата, так все преобразования и предостережения этой функции относятся и сюда.
luaL_checknumber
Проверяет, что аргумент функции arg это число, и возвращает это число.
luaL_checkoption
Проверяет, что аргумент функции arg это строка, и ищет эту строку в массиве lst (который должен завершаться NULL-символом). Возвращает индекс в массиве, где найдена строка. Генерирует ошибку, если аргумент не строка или строка не найдена в массиве.
Если def не NULL , функция использует def как значение по умолчанию, когда нет аргумента arg или он равен nil.
Эта функция полезна для отображения строк в C перечисления (enum). (Обычно, для выбора опций в Lua библиотеках принято использовать строки вместо чисел.)
luaL_checkstack
Увеличивает размер стека до top + sz элементов, вызывает ошибку, если стек не может быть увеличен до этого размера. msg — это дополнительный текст для сообщения об ошибке (или NULL , если его нет).
luaL_checkstring
Проверяет, что аргумент функции arg это строка, и возвращает эту строку.
Эта функция использует lua_tolstring для получения результата, так все преобразования и предостережения этой функции относятся и сюда.
luaL_checktype
Проверяет, что аргумент функции arg имеет тип t . См. lua_type для кодировок типов t .
luaL_checkudata
Проверяет, что аргумент функции arg это пользовательские данные типа tname (см. luaL_newmetatable ), и возвращает адрес пользовательских данных (см. lua_touserdata ).
luaL_checkversion
Проверяет, что ядро, выполняющее вызов, ядро, создавшее Lua состояние, и код, производящий вызов, все используют одну версию Lua. Также проверяет, что ядро, выполняющее вызов, и ядро, создавшее Lua состояние, используют одно адресное пространство.
luaL_dofile
Загружает и запускает данный файл. Определена как макрос:
Возвращает false, если ошибок нет, или true в случае ошибок.
luaL_dostring
Загружает и запускает переданную строку. Определена как макрос:
Возвращает false, если ошибок нет, или true в случае ошибок.
luaL_error
Генерирует ошибку. Сообщение об ошибке форматируется строкой fmt и дополнительными аргументами, следует тем же правилам, что и lua_pushfstring . Также добавляет в начало сообщения имя файла и номер строки, где произошла ошибка, если эта информация доступна.
Эта функция никогда не возвращается, но её идиома для использования в C функциях: return luaL_error(args) .
luaL_execresult
Эта функция выдает возвращаемые значения для связанных с процессами функций стандартной библиотеки ( os.execute и io.close ).
luaL_fileresult
Эта функция выдает возвращаемые значения для связанных с файлами функций стандартной библиотеки ( io.open , os.rename , file:seek и др.).
luaL_getmetafield
Ложит на стек поле e из метатаблицы объекта по индексу obj и возвращает тип положенного на стек значения. Если объект не имеет метатаблицы или в метатаблице нет этого поля, ничего не ложит на стек и возвращает LUA_TNIL .
luaL_getmetatable
Ложит на стек метатаблицу, ассоциированную с именем tname в реестре (см. luaL_newmetatable ) (nil, если метатаблицы с таким именем нет). Возвращает тип положенного на стек значения.
luaL_getsubtable
Гарантирует, что значение t[fname] это таблица, и ложит эту таблицу на стек; t — это значение по индексу idx . Возвращает true, если находит существующую таблицу, и false, если создает новую.
luaL_gsub
Создает копию строки s , заменяя все вхождения строки p на строку r . Ложит на стек результирующую строку и возвращает её.
luaL_len
Возвращает «длину» значения по индексу index как число; эквивалентна Lua оператору ‘ # ‘ (см. §3.4.7). Генерирует ошибку, если результат операции не целое. (Это может случиться только через метаметоды.)
luaL_loadbuffer
Эквивалентно luaL_loadbufferx с mode = NULL .
luaL_loadbufferx
Загружает буфер как Lua кусок. Эта функция использует lua_load для загрузки куска в буфер buff размером sz .
Функция возвращает те же результаты, что и lua_load .
name — имя куска, используемое для отладочной информации и сообщений об ошибках. Строка mode работает как в функции lua_load .
luaL_loadfile
Эквивалентно luaL_loadfilex с mode = NULL .
luaL_loadfilex
Загружает файл как Lua кусок. Эта функция использует lua_load для загрузки куска из файла filename . Если filename = NULL , загружает кусок из потока стандартного ввода. Первая линия файла игнорируется, если она начинается с # .
Строка mode работает как в функции lua_load .
Эта функция возвращает те же результаты, что и lua_load , но имеет дополнительный код ошибки LUA_ERRFILE , если не может открыть/прочитать файл или файл имеет неверный режим.
Как и lua_load , эта функция только загружает кусок; но не запускает его.
luaL_loadstring
Загружает строку как Lua кусок. Эта функция использует lua_load для загрузки завершаемой нулем строки s .
Эта функция возвращает те же результаты, что и lua_load .
Как и lua_load , эта функция только загружает кусок; но не запускает его.
luaL_newlib
Создает новую таблицу и регистрирует в ней функции из списка l .
Реализована как макрос:
Массив l должен быть фактическим массивом, не указателем на него.
luaL_newlibtable
Создает новую таблицу с размером, оптимизированным для хранения всех записей массива l (но фактически не сохраняет их). Она предполагается для использования в связке с luaL_setfuncs (см. luaL_newlib ).
Реализована как макрос. Массив l должен быть фактическим массивом, не указателем на него.
luaL_newmetatable
Если реестр уже содержит ключ tname , возвращает 0. Иначе, создает новую таблицу для использования в качестве метатаблицы пользовательских данных, добавляет в эту новую таблицу пару __name = tname , добавляет в реестр пару [tname] = new table , и возвращает 1. (Элемент __name используется некоторыми функциями, сообщающими об ошибках.)
В обоих случаях ложит на стек финальное значение ассоциированное с tname в реестре.
luaL_newstate
Создает новое Lua состояние. Вызывает lua_newstate с функцией выделения памяти, базирующейся на стандартной C функции realloc , и затем устанавливает функцию паники (см. §4.6), которая в случае фатальных ошибок печатает сообщение об ошибке в стандартный поток вывода.
Возвращает новое состояние, или NULL , если не удалось выделить память.
luaL_openlibs
Открывает все стандартные библиотеки Lua в данное состояние.
luaL_optinteger
Если аргумент функции arg это целое (или может быть преобразован в целое), возвращает это целое. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
luaL_optlstring
Если аргумент функции arg это строка, возвращает эту строку. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
Если l не NULL , записывает в *l длину результата.
luaL_optnumber
Если аргумент функции arg это число, возвращает это число. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
luaL_optstring
Если аргумент функции arg это строка, возвращает эту строку. Если аргумент отсутствует или равен nil, возвращает d . Иначе, генерирует ошибку.
luaL_prepbuffer
Эвивалентно luaL_prepbuffsize с предопределенным размером LUAL_BUFFERSIZE .
luaL_prepbuffsize
Возвращает адрес пространства размером sz , куда вы можете скопировать строку, чтобы добавить в буфер B (см. luaL_Buffer ). После копирования строки в это пространство, вы должны вызвать luaL_addsize с размером строки, для фактического добавления её в буфер.
luaL_pushresult
Завершает использование буфера B , оставляя финальную строку на вершине стека.
luaL_pushresultsize
luaL_ref
Создает и возвращает ссылку (reference) в таблице по индексу t , для объекта на вершине стека (и снимает этот объект со стека).
Ссылка это уникальный целый ключ. Пока вы не добавляете целые ключи в таблицу t , luaL_ref гарантирует уникальность возвращаемых ключей. Вы можете извлечь объект по ссылке r , вызвав lua_rawgeti(L, t, r) . Функция luaL_unref освобождает ссылку и ассоциированный с ней объект.
Если объект на вершине стека равен nil, luaL_ref возвращает константу LUA_REFNIL . Константа LUA_NOREF всегда отлична от любой другой ссылки, возвращаемой luaL_ref .
luaL_Reg
Тип для массивов функций для регистрации функцией luaL_setfuncs . name — имя функции, func — указатель на функцию. Любой массив luaL_Reg должен завершаться ключевым элементом, в котором name и func = NULL .
luaL_requiref
Если modname ещё не присутствует в package.loaded , вызывает функцию openf со строкой modname в качестве аргумента и пишет результат вызова в package.loaded[modname] , как если бы эта функция была бы вызвана через require .
Если glb = true, также сохраняет модуль в глобальную modname .
Оставляет копию модуля на стеке.
luaL_setfuncs
Регистрирует все функции в массиве l (см. luaL_Reg ) в таблицу на вершине стека (ниже опциональных upvalue, см. далее).
Когда nup != 0, все функции создаются, разделяющими nup upvalue, которые должны быть предварительно положены на стек поверх таблицы библиотеки. После регистрации эти значения снимаются со стека.
luaL_setmetatable
Устанавливает метатаблицей объекта на вершине стека метатаблицу, ассоциированную с именем tname в реестре (см. luaL_newmetatable ).
luaL_Stream
Стандартное представление для описателей файлов (handle), которые используются стандартной библиотекой ввода-вывода.
Описатель файла реализован как полные пользовательские данные, с метатаблицей называемой LUA_FILEHANDLE (где LUA_FILEHANDLE — это макрос с фактическим именем метатаблицы). Метатаблица создается библиотекой ввода-вывода (см. luaL_newmetatable ).
Эти пользовательские данные должны начинаться со структуры luaL_Stream ; они могут содержать другие данные после этой начальной структуры. Поле f — указывает на соответствующий C поток (ими может быть NULL для индикации не полностью созданного описателя). Поле closef — указывает на Lua функцию, которая будет вызвана для закрытия потока, при закрытии или сборке описателя; эта функция получает описатель файла в качестве единственного аргумента и должна вернуть true (в случае успеха) или nil с сообщением об ошибке (в случае ошибки). Как только Lua вызывает это поле, его значение меняется на NULL для сигнализации, что описатель закрыт.
luaL_testudata
Эта функция работает как luaL_checkudata , за исключением того, что когда проверка неудачна, она возвращает NULL , вместо генерирования ошибки.
luaL_tolstring
Конвертирует любое Lua значение по индексу idx в C строку в разумном формате. Результирующая строка ложится на стек и также возвращается функцией. Если len не NULL , функция пишет в *len длину строки.
Если значение имеет метатаблицу с полем «__tostring» , то luaL_tolstring вызывает соответствующий метаметод со значением в качестве аргумента и использует результат вызова, как свой результат.
luaL_traceback
Создает и ложит на стек трассировку стека L1 . Если msg не NULL , оно добавляется в начало трассировки. Параметр level указывает на каком уровне начинать трассировку.
luaL_typename
Возвращает имя типа для значения по индексу index.
luaL_unref
Освобождает ссылку ref из таблицы по индексу t (см. luaL_ref ). Элемент удаляется из таблицы, так что ассоциированный объект может быть собран сборщиком мусора. Ссылка ref также освобождается для повторного использования.
Если ref = LUA_NOREF или LUA_REFNIL , luaL_unref ничего не делает.
luaL_where
Ложит на стек строку, идентифицирующую текущую позицию на управляющем уровне lvl в стеке вызовов. Обычно эта строка имеет следующий формат:
Уровень 0 — это текущая выполняемая функция, уровень 1 — это функция, которая вызвала текущую, и так далее.
Эта функция используется для формирования префикса сообщений об ошибках.
6 – Стандартные библиотеки
Стандартные библиотеки Lua предоставляют полезные функции, реализованные напрямую через C API. Некоторые из этих функций предоставляют существенные службы языка (например, type и getmetatable ); другие предоставляют доступ к «внешним» сервисам (например, I/O); и другие могут быть реализованы в Lua самостоятельно, но очень полезны и имеют критические требования к производительности, что заслуживает реализации в C (например, table.sort ).
- базовая библиотека (§6.1);
- библиотека сопрограмм (§6.2);
- библиотека пакетов (§6.3);
- манипуляции со строками (§6.4);
- базовая поддержка UTF-8 (§6.5);
- манипуляции с таблицами (§6.6);
- математические функции (§6.7) (sin, log и др.);
- ввод и вывод (§6.8);
- средства операционной системы (§6.9);
- отладочные средства (§6.10).
За исключением базовой и пакетной библиотек, каждая библиотека предоставляет все свои функции, как поля глобальной таблицы или методы её объектов.
Для получения доступа к этим библиотекам хоствая C программа должна вызвать функцию luaL_openlibs , которая открывает все стандартные библиотеки. Либо, хостовая программа может открыть их индивидуально, используя luaL_requiref для вызова luaopen_base (для базовой библиотеки), luaopen_package (для библиотеки пакетов), luaopen_coroutine (для библиотеки сопрограмм), luaopen_string (для строковой библиотеки), luaopen_utf8 (для библиотеки UTF8), luaopen_table (для табличной библиотеки), luaopen_math (для математической библиотеки), luaopen_io (для библиотеки ввода-вывода), luaopen_os (для библиотеки операционной системы) и luaopen_debug (для отладочной библиотеки). Все эти функции определены в lualib.h .
6.1 – Базовые функции
Базовая библиотека предоставляет функции ядра для Lua. Если вы не включите эту библиотеку в ваше приложение, вы должны проявлять осторожность, когда будете нуждаться в предоставлении реализаций для некоторых её возможностей.
assert (v [, message])
Вызывает error , если значение аргумента v = false (т.е., nil или false); иначе, возвращает все свои аргументы. В случае ошибки, message — это объект ошибки; когда он отсутствует, его значение по умолчанию » assertion failed! «
collectgarbage ([opt [, arg]])
- » collect «: выполняет полный цикл очистки мусора. Это опция по умолчанию.
- » stop «: останавливает автоматическое выполнение сборщика мусора. Сборщик будет запущен, только когда явно вызван, до вызова его перезапуска.
- » restart «: перезапускает автоматическое выполнение сборщика мусора.
- » count «: возвращает общее количество используемой Lua памяти в килобайтах. Это значение имеет дробную часть, так что его произведение на 1024 дает точное количство байт, используемых Lua (за исключением переполнений).
- » step «: выполняет шаг сборки мусора. «Размер» шага контролируется аргументом arg . С нулевым значением сборщик выполнит один базовый (неделимый) шаг. Для не нулевых значений, сборщик выполнит, как если это количество памяти (в килобайтах) было выделено Lua. Возвращает true, если шаг завершил цикл сборки.
- » setpause «: устанавливает arg в качестве нового значения для паузы сборщика (см. §2.5). Возвращает предыдущее значение паузы.
- » setstepmul «: устанавливает arg в качестве нового значения для множителя шагов сборщика (см. §2.5). Возвращает предыдущее значение шага.
- » isrunning «: возвращает логическое значение, говорящее запущен ли сборщик (т.е. не остановлен).
dofile ([filename])
error (message [, level])
Обычно error добавляет информацию о позиции ошибки в начало сообщения, если сообщение (message) это строка. Аргумент level определяет как получить позицию ошибки. Когда level = 1 (по умолчанию) — позиция ошибки там, где вызвана функция error . Level = 2 — указывает ошибку там, где вызвана функция, вызвавшая error ; и так далее. Передача level = 0 — позиция ошибки не влючается в сообщение.
getmetatable (object)
Если object не имеет метатаблицы, возвращает nil. Иначе, если метатаблица объекта имеет поле «__metatable» , возвращает ассоциированное с этим полем значение. Иначе, возвращает метатаблицу переданного объекта.
ipairs (t)
Возвращет три значения (функцию итератор, таблицу t и 0), так что конструкция
будет перебирать пары ключ–значение ( 1,t[1] ), ( 2,t[2] ), . до первого значения nil.
load (chunk [, chunkname [, mode [, env]]])
Если chunk это строка, кусок будет этой строкой. Если chunk это функция, load многократно вызывает её, чобы получить части куска. Каждый вызов chunk должен возвращать строку, которая присоединяется к предыдущим результатам. Возврат пустой строки, nil или ничего сигнализирует о конце куска.
Если в куске нет синтаксических ошибок, возвращает скомпилированный кусок, как функцию; иначе, возвращает nil и сообщение об ошибке.
Если результирующая функция имеет upvalue, первое upvalue устанавливается равным env , если этот параметр передан, или в значение глобального окружения. Остальные upvalue инициализируются значением nil. (Когда вы загружаете главный кусок, результирующая функция всегда будет иметь только одно upvalue, переменную _ENV (см. §2.2). Тем не менее, когда вы загружаете бинарный кусок, созданный из функции (см. string.dump ), результирующая функция может иметь произвольное количество upvalue.) Все upvalue свежие, т.е. они не разделяются между любыми другими функциями.
chunkname — используется как имя куска, для сообщений об ошибках и отладочной информации (см. §4.9). Когда отсутствует, его значение по умолчанию это сам chunk , если chunk это строка, или » =(load) » иначе.
Строка mode — управляет каким может быть кусок, текстовым или бинарным (т.е. прекомпилированным). Она может быть » b » (только бинарные куски), » t » (только текстовые куски) или » bt » (текстовые и бинарные куски). Значение по умолчанию это » bt «.
Lua не проверяет правильность бинарных кусков. Злонамеренно созданный бинарный кусок может разрушить интерпретатор.
loadfile ([filename [, mode [, env]]])
Аналогично load , но получает кусок из файла filename или из стандартного потока ввода, если имя файла не передано.
next (table [, index])
Позволяет программе просмостреть все поля таблицы. Её первый аргумент — это таблица, второй аргумент — индекс в этой таблице. next возвращает следующий индекс таблицы и ассоциированное с ним значение. Когда вызывается с nil в качестве второго аргумента, next возвращает начальный индекс и ассоциированое с ним значение. Когда вызывается с последним индексом, или с nil для пустой таблицы, next возвращает nil. Если второй аргумет отсутствует, то он интерпретируется как nil. В частности, вы можете использовать next(t) для проверки, что таблица пустая.
Порядок перечисления индексов не определен, даже для числовых индексов. (Для просмотра таблицы в числовом порядке, используйте числовой for.)
Поведение next неопределено, если во время просмотра вы присваиваете любое значение несуществующему полю в таблице. Тем не менее вы можете модифицировать существующие поля. В частности, вы можете очищать существующие поля.
pairs (t)
Если t имеет метаметод __pairs , вызывает его с аргументом t и возвращает первые три результата вызова.
Иначе, возвращает три значения: функцию next , таблицу t и nil, так что конструкция
будет перебирать все пары ключ–значение в таблице t .
См. функцию next для предострежений о модификации таблицы во время просмотра.
pcall (f [, arg1, ···])
Вызывает функцию f с переданными аргументами в защищенном режиме. Это значит, что любая ошибка внутри f не распространяется; взамен, pcall перехватывает ошибку и возвращает код статуса. Её первый результат — код статуса (логическое значение), которое равно true, если вызов успешен. В этом случае pcall также возвращает все результаты из вызова, после первого результата. В случае ошибки pcall возвращает false и сообщение об ошибке.
print (···)
rawequal (v1, v2)
rawget (table, index)
rawlen (v)
rawset (table, index, value)
Эта функция возвращает table .
select (index, ···)
Если index это число, возвращает все аргументы после аргумента номер index ; негативное число индексируется с конца (-1 последний аргумент). Иначе, если index строка «#» , select вернет общее количество дополнительных аргументов.
setmetatable (table, metatable)
Устанавливает метатаблицу для данной таблицы. (Вы не можете изменять метатаблицы других типов из Lua, только из C.) Если metatable = nil, удаляет метатаблицу переданной таблицы. Если оригинальная метатаблица имеет поле «__metatable» , генерирует ошибку.
Эта функция возвращает table .
tonumber (e [, base])
Когда вызвана без аргумента base , tonumber пытается конвертировать аргумент в число. Если аргумент уже число или строка, которую можно преобразовать в число, то tonumber возвращает это число; иначе, возвращает nil.
Преобразование строк может выдавать в результате целые или вещественные числа, в соответствии с лексическими соглашениями Lua (см. §3.1). (Строка может иметь начальные и конечные пробелы и знак.)
Когда вызвана с аргументом base , то аргумент e должен быть строкой, которая интерпретируется как целое в данной системе счисления. base может быть любым целым от 2 до 36, включительно. При base > 10, символ ‘ A ‘ (в верхнем или нижнем регистре) представляет 10, ‘ B ‘ представляет 11 и так далее, с ‘ Z ‘ представляющим 35. Если строка e не правильное число в данной системе счисления, функция возвращает nil.
tostring (v)
Если метатаблица v имеет поле «__tostring» , то tostring вызывает соответствующее значение с v в качестве аргумента и использует результат вызова, как свой результат.
type (v)
_VERSION
xpcall (f, msgh [, arg1, ···])
Эта функция похожа на pcall , но она устанавливает новый обработчик сообщений msgh .
6.2 – Работа с сопроцессами
Эта библиотека содержит операции для манипуляции с сопроцессами, которые хранятся в таблице coroutine . См. §2.6 для общего описания сопроцессов.
coroutine.create (f)
Создает новый сопроцесс, с телом f . f должен быть функцией. Возвращает этот новый сопроцесс, как объект с типом «thread» .
coroutine.isyieldable ()
Возвращает true, когда запущенный сопроцесс может уступить.
Запущенный сопроцесс может уступать, если это не главный поток и он не внутри неприостанавливаемой C функции.
coroutine.resume (co [, val1, ···])
Начинает или продолжает выполнение сопроцесса co . При первом возобновлении сопроцесса запускает его тело. Значение val1 , . передаются как аргументы телу сопроцесса (его функции). Если сопроцесс был приостановлен, resume перезапускает его; значниния val1 , . передаются как результаты из yield.
Если сопроцесс запущен без ошибок, resume возвращает true и все значения, переданные в yield (когда сопроцесс уступает) или все значения, возвращенные функцией сопроцесса (когда сопроцесс завершается). В случае ошибок, resume возвращает false и сообщение об ошибке.
coroutine.running ()
Возвращает запущенный сопроцесс и логическое значение; true, если сопроцесс это главный поток.
coroutine.status (co)
Возвращает статус сопроцесса co , как строку: «running» — сопроцесс запущен (т.е. он вызвал status ); «suspended» — сопроцесс приостановлен в вызове yield или еще не запущен; «normal» — сопроцесс активен, но не выполняется (т.е. он был продолжен другим сопроцессом); «dead» — сопроцесс завершил своё тело или был остановлен с ошибкой.
coroutine.wrap (f)
Создает новый сопроцесс с телом f . f должен быть функцией. Возвращает функцию, которая возобновляет сопроцесс при каждом её вызове. Все аргументы, переданные этой функции, ведут себя как дополнительные аргументы в resume . Возвращает те же значения, что и resume , за исключением первого логического значения. В случае ошибки, распространяет ошибку.
coroutine.yield (···)
Приостанавливает выполнение вызывающего сопроцесса. Все аргументы yield передаются, как дополнительные результаты в resume .
6.3 – Модули
Эта пакетная библиотека предоставляет базовые возможности для загрузки модулей в Lua. Она экспортирует одну функцию напрямую в глобальное окружение: require . Всё остальное экспортируется в таблице package .
require (modname)
Загружает переданный модуль. Функция начинает с просмотра таблицы package.loaded для определения, что модуль modname уже загружен. Если это так, то require возвращает значение, хранящееся в package.loaded[modname] . Иначе, пробует найти загрузчик для модуля.
При поиске загрузчика require руководствуется последовательностью package.searchers . Изменяя эту последовательность, вы можете изменить то, как require ищет модуль. Следующее объяснение базируется на конфигурации по умолчанию для package.searchers .
Сначала require запрашивает package.preload[modname] . Если это значение существует, то это значение (которое может быть функцией) это загрузчик. Иначе require ищет Lua загрузчик, используя путь, хранящийся в package.path . Если это тоже неудачно, она ищет C загрузчик, используя путь, хранящийся в package.cpath . Если и это неудачно, пробует все в одном загрузчик (см. package.searchers ).
Как только загрузчик найден, require вызывает загрузчик с двумя аргументами: modname и дополнительное значение, зависящее от того, как получен загрузчик. (Если загрузчик пришел из файла, это дополнительное значение будет именем файла.) Если загрузчик возвращает не-nil значение, require записывает возвращенное значение в package.loaded[modname] . Если загрузчик не вернул не нулевое значение и package.loaded[modname] не присвоено никакое значение, то require пишет туда true. В любом случае, require возвращает финальное значение package.loaded[modname] .
Если во время загрузки или запуска модуля происходит ошибка, или если не найден ни один загрузчик для модуля, require генерирует ошибку.
package.config
- Первая строка — это строка разделитель директорий. По умолчанию, это ‘ \ ‘ для Windows и ‘ / ‘ для всех остальных систем.
- Вторая строка — символ, который разделяет шаблоны в пути. По умолчанию это ‘ ; ‘.
- Третья строка — это строка, которая обозначает точки замены в шаблоне. По умолчанию это ‘ ? ‘.
- Четвертая строка — это строка, которая в пути в Windows, заменяется на директорию исполняемого файла. По умолчанию это ‘ ! ‘.
- Пятая строка — это метка для игнорирования всего текста после неё, когда формируется имя функции luaopen_ . По умолчанию это ‘ — ‘.
package.cpath
Этот путь используется require для поиска C загрузчика.
Lua инициализирует C путь package.cpath также, как и Lua путь package.path , используя переменную окружения LUA_CPATH_5_3 или переменную окружения LUA_CPATH или путь по умолчанию, определенный в luaconf.h .
package.loaded
Таблица, используемая require для контроля за тем, какие модули уже загружены. Когда вы загружаете модуль modname и package.loaded[modname] не false, require просто возвращает хранящееся там значение.
Эта переменная только ссылка на реальную таблицу; присваивание этой переменной не изменяет таблицу, используемую функцией require .
package.loadlib (libname, funcname)
Динамически связывает (link) хостовую программу с C библиотекой libname .
Если funcname , то она только связывает с библиотекой, делая экспортируемые библиотекой символы доступными для других динамических библиотек. Иначе, она ищет функцию funcname внутри библиотеки и возвращает эту функцию, как C функцию. Так, funcname должна соответствовать прототипу lua_CFunction (см. lua_CFunction ).
Это низкоуровневая функция. Она полностью обходит систему пакетов и модулей. В отличие от require , она не производит поисков пути и не добавляет расширения автоматически. libname должен быть завершенным именем файла C библиотеки, включая, если необходимо, путь и расширение. funcname должен быть точным именем, экспортируемым C библиотекой (которое может зависеть от используемого C компилятора и компоновщика).
Эта функция не поддерживается стандартным C. Т.к., она доступна только для некоторых платформ (Windows, Linux, Mac OS X, Solaris, BSD и другие Unix системы, которые поддерживаю стандарт dlfcn ).
package.path
Этот путь используется require для поиска Lua загрузчика.
Во время запуска Lua инициализирует эту переменную значением переменной окружения LUA_PATH_5_3 или переменной окружения LUA_PATH , или значением по умолчанию, определенным в luaconf.h , если эти переменные окружения не определены. Любое » ;; » в значении переменной окружения заменяется путем по умолчанию.
package.preload
Таблица для хранения загрузчиков для специфических модулей (см. require ).
Эта переменная только ссылается на реальную таблицу; присваиваение этой переменной не изменяет таблицу, используемую функцией require .
package.searchers
Таблица, используемая require для контроля над тем, как загружать модули.
Каждый элемент в этой таблице это функция искатель (searcher). Когда ищется модуль, require вызывает каждую из этих функций в возрастающем порядке, с именем модуля (аргумент переданный в require ) в качестве единственного параметра. Функция может вернуть другую функцию (загрузчик модуля) и дополнительное значение, которое будет передано загрузчику, или строку, объясняющую, почему модуль не найден (или nil если нечего сказать).
Lua инициализирует эту таблицу четырьмя функциями искателями.
первый искатель просто ищет загрузчик в таблице package.preload .
Втрой искатель ищет загрузчик для Lua библиотеки, используя путь package.path . Поиск производится как описано в функции package.searchpath .
Третий искатель ищет загрузчик для C библиотеки, используя путь package.cpath . Поиск производится как описано в функции package.searchpath . Например, если C путь это строка
искатель для модуля foo будет пробовать открыть файлы ./foo.so , ./foo.dll , и /usr/local/foo/init.so , в этом порядке. Когда он найдет C библиотеку, сначала он использует средства динамического связывания с библиотекой. Затем попытается найти в библиотеке C функцию для использования в качестве загрузчика. Имя этой C функции это строка » luaopen_ «, склеенная с копией имени модуля, где каждая точка заменена на подчеркивание. Более того, если имя модуля имеет дефис, его суффикс после первого дефиса удаляется (дефис тоже удаляется). Например, если имя модуля a.b.c-v2.1 , имя функции будет luaopen_a_b_c .
Четвертый искатель пробует все в одном загрузчик. Он ищет C путь для библиотеки с корневым путем переданного модуля. Например, когда требуется a.b.c , он будет искать C библиотеку a . Если существует, он заглянет в нее для открытия функции подмодуля; в нашем примере, это будет luaopen_a_b_c . С этой возможностью, пакет может упаковывать различные C подмодули в одной библиотеке, где каждый подмодуль имеет свою оригинальную функцию открытия.
Все искатели, за исключением первого (preload), возвращают имя файла, где найден модуль, как дополнительное значение, возвращаемое package.searchpath . Первый искатель не возвращает дополнительное значение.
package.searchpath (name, path [, sep [, rep]])
Ищет имя name в пути path .
Путь — это строка, содержащая последовательность шаблонов, разделенных точкой с запятой (;). Для каждого шаблона, функция заменяет каждый знак вопроса (если существует) копией name , где все случаи sep (точка, по умолчанию) заменяются на rep (системный разделитель директорий, по умолчанию), и пытается открыть результирующее имя файла.
Например, если путь это строка
поиск имени foo.a будет пытаться открыть файлы ./foo/a.lua , ./foo/a.lc и /usr/local/foo/a/init.lua , в этом порядке.
Возвращает результирующее имя первого файла, который можно открыть в режиме чтения (после закрытия файла), или nil и сообщение об ошибке, если ничего не удалось. (Это сообщение об ошибке перечисляет все имена файлов, которые пыталась открыть функция.)
6.4 – Работа со строками
Эта библиотека предоставляет общие функции для работы со строками, такие как поиск, извлечение подстрок и сопоставление шаблонов. Когда индексируются строки в Lua, первый символ находится на позиции 1 (не на 0, как в C). Допускаются негативные индексы, они интерпретируются как индексирование обратно (задом наперед), с конца строки. Таким образом, последний символ находится на позиции -1 и так далее.
Строковая библиотека предоставляет все свои функции в таблице string . Она также устанавливает метатаблицу для строк, где поле __index указывает на таблицу string . Следовательно, вы можете использовать строковые функции в объектно-ориентированном стиле. Например, выражение string.byte(s,i) может быть записано как s:byte(i) .
Строковая библиотека предполагает кодирование символов одним байтом.
string.byte (s [, i [, j]])
Цифровые коды не обязательно портабельны между платформами.
string.char (···)
Цифровые коды не обязательно портабельны между платформами.
string.dump (function [, strip])
Возвращает строку содержащую бинарное представление (бинарный кусок) переданной функции, так что load для этой строки возвращает копию функции (но с новыми upvalue). Если strip = true, бинарное представление может не включать всю отладочную информацию о функции, для уменьшения размера.
Функции с upvalue сохраняют только количество upvalue. При загрузке, эти upvalue получают свежие экземпляры, содержащие nil. (Вы можете использовать отладочную библиотеку, чтобы сохранить и перезагрузить upvalue функции в том виде, как вам нужно.)
string.find (s, pattern [, init [, plain]])
Ищет первое совпадение шаблона pattern (см. §6.4.1) в строке s . Если совпадение найдено, то find возвращает индексы s , где совпадение начинается и заканчивается; иначе, возвращает nil. Третий опциональный цифровой аргумент init определяет, где начинать поиск; по умолчанию он равен 1 и может быть отрицательным. Значение true в качестве четвертого опционального аргумента plain выключает возможности поиска шаблонов, так функция выполняет плоский поиск подстроки, без магических символов в pattern . Учтите, что если передан plain , то должен быть передан и init .
Если шаблон имеет захваты (capture), то при успешном совпадении захваченные значения также возвращаются, после двух индексов.
string.format (formatstring, ···)
Возвращает форматированную версию переменного количества аргументов, следуя описанию в первом аргументе (должен быть строкой). formatstring — следует тем же правилам, что и в функции sprintf в ISO C. Только отличается тем, что опции/модификаторы * , h , L , l , n и p не поддерживаются, и тем, что имеет дополнительную опцию q . Опция q форматирует строку между двойными кавычками и использует управляющие символы, когда необходимо гарантировать, что строка может быть прочитана Lua интерпретатором обратно. Например, вызов
может выдать строку:
Опции A , a , E , e , f , G и g — все ожидают цифровой аргумент. Оции c , d , i , o , u , X и x — ожидают целое. Опция q — ожидает строку. Опция s — ожидает строку без встроенных нулей; если аргумент не строка, он конвертируется следуя тем же правилам, что и в tostring .
Когда Lua скомпилирована с не C99 компилятором, опции A и a (шестнадцатиричные вещественные числа) не поддерживают модификаторы (флаги, ширина, длина).
string.gmatch (s, pattern)
Например, следующий цикл будет перебирать все слова из строки s , печатая по одному в строке:
Следующий пример собирает в таблице все пары key=value из строки:
Для этой функции, символ ‘ ^ ‘ в начале шаблона не работает как якорь, т.к. это мешает итерации.
string.gsub (s, pattern, repl [, n])
Если repl это строка, то её значение используется для замены. Символ % работает, как управляющий символ: любая последовательность в repl в виде %d , с d между 1 и 9, соответствует d-ой захваченной подстроке. Последовательность %0 соответствует полному совпадению. Последовательность %% соответствует одному символу % .
Если repl это таблица, то таблица запрашивается для каждого совпадения, используя первое захваченное значение, как ключ.
Если repl это функция, то эта функция вызывается для каждого совпадения, все захваченные подстроки передаются в качестве аргументов, по порядку.
В любом случае, если шаблон не имеет захватов, то он ведет себя так, будто весь шаблон находится в захвате.
Если значение, возвращенное из табличного запроса или из функции, это строка или число, то оно используется, как замещающая строка; иначе, если это false или nil, то замена не производится (т.е. оригинальное содержимое совпадения сохраняется в строке).
string.len (s)
string.lower (s)
string.match (s, pattern [, init])
string.pack (fmt, v1, v2, ···)
Возвращает бинарную строку, содержащую значения v1 , v2 и т.д. упакованными (т.е. записанными в бинарной форме) согласно форматной строке fmt (см. §6.4.2).
string.packsize (fmt)
Возвращает размер результирующей строки из string.pack с переданным форматом. Форматная строка не может иметь опций переменной длины ‘ s ‘ или ‘ z ‘ (см. §6.4.2).
string.rep (s, n [, sep])
string.reverse (s)
string.sub (s, i [, j])
Если после трансляции отрицательных индексов i j больше длины строки, он корректируется до этой длины. Если после этих преобразований i > j , функция возвращает пустую строку.
string.unpack (fmt, s [, pos])
Возвращает значения, упакованные в строке s (см. string.pack ) согласно форматной строке fmt (см. §6.4.2). Опциональный параметр pos отмечает, где начинать чтение в s (по умолчанию 1). После чтения значений, эта функция также возвращает индекс первого не прочитанного байта в s .
string.upper (s)
6.4.1 – Шаблоны
Шаблоны в Lua описываются регулярными строками, которые интерпретируются, как шаблоны, функциями сопоставления шаблонов string.find , string.gmatch , string.gsub и string.match . Этот раздел описывает синтаксис и значение (сопоставление) этих строк.
Символьный класс:
- x: (где x — не один из магических символов ^$()%.[]*+-? ) представляет символ x непосредственно.
- . : (точка) представляет все символы.
- %a : представляет все буквы.
- %c : представляет все управляющие символы.
- %d : представляет все цифры.
- %g : представляет все печатаемые символы, кроме пробела.
- %l : представляет все буквы в нижнем регистре.
- %p : представляет все знаки пунктуации.
- %s : представляет все пробельные символы.
- %u : представляет все буквы в верхнем регистре.
- %w : представляет все алфавитно-цифровые символы.
- %x : представляет все шестнадцатиричные символы.
- %x : (где x — не алфавитно-цифровой символ) представляет символ x. Это стандартный способ кодирования магических символов. Любой не алфавитно-цифровой символ (включая все знаки пунктуации, даже не магические) могут предваряться ‘ % ‘, когда используются для представления себя в шаблоне.
- [набор] : представляет класс, который является объединением всех символов в наборе. Диапазон символов может быть определен отделением конечного символа диапазона, в восходящем порядке, символом ‘ — ‘. Все классы % x, описанные выше, также могут быть включены в набор, как компоненты. Все остальные символы в наборе представляют непосредственно себя. Например, [%w_] (или [_%w] ) представляет все алфавитно-цифровые символы и подчеркивание, [0-7] представляет восьмиричные цифры, [0-7%l%-] представляет восьмиричные цифры, буквы в нижнем регистре и символ ‘ — ‘.
Для всех классов, представленных одним символом ( %a , %c и др.), соответствующие представления с буквой в верхнем регистре отрицают класс. Например, %S представляет все не пробельные символы.
Определения букв, пробелов и других групп символов зависят от текущей локали. В частности, класс [a-z] может не быть эквивалентом %l .
Элемент шаблона:
- односимвольный класс, который соответствует одному символу в классе;
- односимвольный класс с последующим символом ‘ * ‘, который соответствует нулю или более повторам символов в классе. Этот повтор элементов всегда будет соответствовать самой длинной возможной последовательности;
- односимвольный класс с последующим символом ‘ + ‘, который соответствует одному или более повторам символов в классе. Этот повтор элементов всегда будет соответствовать самой длинной возможной последовательности;
- односимвольный класс с последующим символом ‘ — ‘, который соответствует нулю или более повторам символов в классе. В отличие от ‘ * ‘, этот повтор элементов всегда будет соответствовать самой короткой возможной последовательности;
- односимвольный класс с последующим символом ‘ ? ‘, который соответствует нулю или одному случаю символа в классе. Он всегда соответсвует одному вхождению, если возможно;
- %n , для n между 1 и 9; этот элемент соответствует подстроке равной n-й захваченной строке (см. ниже);
- %bxy , где x и y два четких символа; этот элемент соответствует строкам, которые начинаются с x и заканчиваются на y, и где x и yсбалансированы. Это значит, что если при чтении строки слева направо, считать +1 для x и -1 для y, завершающий y это первый y, где счет достигнет 0. Например, элемент %b() соответсвует выражениям в сбалансированных скобках.
- %f[набор] , граничный шаблон; этот элемент соответствует пустой строке в любой позиции такой, что следующий символ принадлежит набору и предыдущий символ не принадлежит набору. Набор интерпретируется, как описано выше. Начало и конец субъекта обрабатывается, как если там символ ‘ \0 ‘.
Шаблон:
Шаблон — это последовательность элементов шаблона. Символ ‘ ^ ‘ в начале шаблона фиксирует его в начале строки. Символ ‘ $ ‘ в конце шаблона фиксирует его в конце строки. В остальных позициях ‘ ^ ‘ и ‘ $ ‘ не имеют специального значения и представляют сами себя.
Захваты (capture):
Шаблон может содержать подшаблоны заключенные в скобки; они описывают захваты. Когда совпадение успешно, подстроки, которые соответсвуют захватам (захваченные), сохраняются для последующего использования. Захваты нумеруются соответственно их левым скобкам. Например, в шаблоне «(a*(.)%w(%s*))» , часть строки, соответствующая «a*(.)%w(%s*)» , сохраняется как первый захват (и следовательно имеет номер 1); соответствие » . » захватывается с номером 2, и часть соответствующая » %s* » имеет номер 3.
Специальный случай, пустой захват () захватывает текущую позицию в строке (число). Например, если мы применим шаблон «()aa()» к строке «flaaap» , будет сделано два захвата: 3 и 5.
6.4.2 – Формат строк для string.pack и string.unpack
Первый аргумент в string.pack , string.packsize и string.unpack это строка формата, которая описывает формат создаваемой или читаемой структуры.
- < : устанавливает прямой порядок байт (little endian)
- > : устанавливает обратный порядок байт (big endian)
- = : устанавливает исконный порядок байт
- ![n] : устанавливает максимальное выравнивание равным n (по умолчанию, исконное выравнивание)
- b : знаковый байт ( char )
- B : беззнаковый байт ( char )
- h : знаковый short (исконный размер)
- H : беззнаковый short (исконный размер)
- l : знаковый long (исконный размер)
- L : беззнаковый long (исконный размер)
- j : lua_Integer
- J : lua_Unsigned
- T : size_t (исконный размер)
- i[n] : знаковый int с n байт (по умолчанию, исконный размер)
- I[n] : беззнаковый int с n байт (по умолчанию, исконный размер)
- f : float (исконный размер)
- d : double (исконный размер)
- n : lua_Number
- cn : строка фиксированного размера с n байт
- z : завершаемая нулем строка
- s[n] : строка с предваряющим её размером, кодированным как беззнаковое целое с n байт (по умолчанию, это size_t )
- x : один байт заполнения
- Xop : пустой элемент, который выравнивает в соответствии с опцией op (которая в противном случае игнорируется)
- ‘ ‘: (пустое пространство) игнорируется
(» [n] » означает опциональную целую цифру.) Кроме заполнения, пробелов и конфигураций (опции » xX <=>! «), каждая опция соответствует аргументу (в string.pack ) или результату (в string.unpack ).
Для опций » !n «, » sn «, » in » и » In «, n может быть целым от 1 до 16. Все целые опции проверяют переполнения; string.pack проверяет, что переданное значение поместится в переданный размер; string.unpack проверяет, что прочитанное значение поместится в целое Lua.
Любая строка формата начинается так, будто содержит префикс » !1= «, т.е. с максимальным выравниванием 1 (без выравнивания) и исконным порядком байт.
Выравнивание работает так: для каждой опции формат получает дополнительное заполнение, пока не начнутся данные по смещению, которое равно произведению минимума между размером опции и максимального выравнивания; этот минимум должен быть степенью 2. Опции » c » и » z » не выравниваются; опция » s » следует выравниванию её начального целого.
Все заполнения заполняются нулями в string.pack (и игнорируются в string.unpack ).
6.5 – Поддержка UTF-8
Эта библиотека предоставляет базовую поддержку для кодировки UTF-8. Она предоставляет все свои функции в таблице utf8 . Эта библиотека не предоставляет другой поддержки для Unicode, кроме обработки кодировки. Все операции, нуждающиеся в значении символа, такие как классификация символов, не входят в эту область.
Пока не установлено иначе, все функции, которые ожидают позицию байта, как параметр, предполагают, что переданная позиция является также началом последовательности байт или позиция плюс длина строки. Как и в строковой библиотеке, отрицательные индексы отсчитываются с конца строки.
utf8.char (···)
utf8.charpattern
utf8.codes (s)
Возвращает значения такие, что конструкция
будет перебирать все символы в строке s , где p — позиция (в байтах) и c — кодовая точка для каждого символа. Функция вызывает ошибку, если встретит неправильную последовательность байт.
utf8.codepoint (s [, i [, j]])
utf8.len (s [, i [, j]])
utf8.offset (s, n [, i])
Специальный случай, когда n = 0, функция возвращает начало закодированного символа, который содержит i -й байт строки s .
Эта функция предполагает, что s это правильная строка UTF-8.
6.6 – Работа с таблицами
Эта библиотека предоставляет базовые функции для работы с таблицами. Она предоставляет все свои функции в таблице table .
Помните, что когда операция нуждается в длине таблицы, таблица должа содержать соответсвующую последовательность или иметь метаметод __len (см. §3.4.7). Все функции игнорируют не цифровые ключи в таблицах, полученных как аргументы.
table.concat (list [, sep [, i [, j]]])
Получает список list, где все элементы строки или числа, возвращает строку list[i]..sep..list[i+1] ··· sep..list[j] . По умолчанию, sep это пустая строка, i = 1 и j = #list . Если i > j , возвращает пустую строку.
table.insert (list, [pos,] value)
Вставляет элемент value на позицию pos в список list , сдвигая элементы вверх list[pos], list[pos+1], ···, list[#list] . По умолчанию, pos = #list+1 , так вызов table.insert(t,x) вставляет x в конец списка t .
table.move (a1, f, e, t [,a2])
Перемещает элементы из таблицы a1 в таблицу a2 . Эта функция эквивалентна множественному присваиванию: a2[t],··· = a1[f],···,a1[e] . По умолчанию, a2 = a1 . Целевой диапазон может перекрываться с диапазоном источником. Количество элементов для перемещения должно помещаться в целое Lua.
table.pack (···)
Возвращает новую таблицу, в которой все параметры сохранены с ключами 1, 2 и т.д. и поле » n » содержит количество параметров. Учтите, что результирующая таблица может не быть последовательностью.
table.remove (list [, pos])
Удаляет из списка list элемент на позиции pos , возвращая значение этого элемента. Когда pos это целое между 1 и #list , функция сдвигает элементы вниз list[pos+1], list[pos+2], ···, list[#list] и стирает элемент list[#list] ; Индекс pos может быть 0, когда #list = 0, или #list + 1 ; в этих случаях функция стирает элемент list[pos] .
По умолчанию, pos = #list , так вызов table.remove(l) удаляет последний элемент списка l .
table.sort (list [, comp])
Сортирует элементы полученного списка, на месте, от list[1] до list[#list] . Если передан параметр comp , он должен быть функцией, которая получает два элемента списка и возвращает true, когда первый элемент должен находиться перед вторым в финальном упорядочении (так выражение not comp(list[i+1],list[i]) будет истинным после сортировки). Если параметр comp не передан, то взамен Lua использует стандартный оператор < .
Алгоритм сортировки не стабилен; т.е. элементы, считающиеся равными в этом упорядочении, в результате сортировки могут изменить свои относительные позиции.
table.unpack (list [, i [, j]])
Возвращает элементы из полученного списка. Эта функция эквивалентна
По умолчанию, i = 1 и j = #list .
6.7 – Математические функции
Эта библиотека предоставляет базовые математические функции. Она предоставляет все свои функции и константы в таблице math . Функции с комментарием » integer/float » выдают целые результаты для целых аргументов и вещественные результаты для вещественных (или смешанных) аргументов. Функции округления ( math.ceil , math.floor и math.modf ) возвращают целое, когда результат помещается в диапазон целых, или вещественное иначе.
math.abs (x)
Возвращает абсолютное значение x . (integer/float)
math.acos (x)
Возвращает арккосинус x (в радианах).
math.asin (x)
Возвращает арксинус x (в радианах).
math.atan (y [, x])
Возвращает арктангенс y/x (в радианах), но использует знаки обоих параметров для поиска квадранта результата. (Также корректно обрабатывает случай, когда x = 0.)
По умолчанию x = 1, так вызов math.atan(y) возвращает арктангенс y .
math.ceil (x)
Возвращает наименьшее целое значение, которое больше или равно x .
math.cos (x)
Возвращает косинус x (в радианах).
math.deg (x)
Преобразует угол x из радиан в градусы.
math.exp (x)
Возвращает значение e x (где e — основание натурального логарифма).
math.floor (x)
Возвращает наибольшее значение, которое меньше или равно x .
math.fmod (x, y)
Возвращает остаток от деления x на y , который округляет частное к нулю. (integer/float)
math.huge
Вещественное значение HUGE_VAL , которое больше любого другого числового значения.
math.log (x [, base])
Возвращает логарифм x по основанию base . По умолчанию, base = e (так функция возвращает натуральный логарифм x ).
math.max (x, ···)
Возвращает аргумент с максимальным значением, в соответствии с Lua оператором < . (integer/float)
math.maxinteger
math.min (x, ···)
Возвращает аргумент с минимальным значением, в соответствии с Lua оператором < . (integer/float)
math.mininteger
math.modf (x)
Возвращает целую и дробную часть x . Второй результат всегда вещественное число.
math.pi
math.rad (x)
Преобразует угол x из градусов в радианы.
math.random ([m [, n]])
Когда вызвана без аргументов, возвращает псевдослучайное вещественное число с однородным распределением в диапазоне [0,1). Когда вызвана с двумя целыми m и n , math.random возвращает псевдослучайное целое с однородным распределением в диапазоне [m, n]. (Значение m-n не может быть отрицательным и должно помещаться в целое Lua.) Вызов math.random(n) эквивалентен вызову math.random(1,n) .
Эта функция является интерфейсом к генератору псевдослучайных чисел, предоставляемому C. Нет гарантий для его статистических свойств.
math.randomseed (x)
Устанавливает x как «затравку» (seed) для генератора псевдослучайных чисел: одинаковые затравки производят одинаковые последовательности чисел.
math.sin (x)
Возвращает синус x (в радианах).
math.sqrt (x)
Возвращает квадратный корень x . (Для вычисления этого значения вы также можете использовать выражение x^0.5 .)
math.tan (x)
Возвращает тангенс x (в радианах).
math.tointeger (x)
Если значение x можно преобразовать в целое, возвращает целое. Иначе, возвращает nil.
math.type (x)
Возвращает » integer » — если x целое, » float » — если x вещественное, или nil — если x не число.
math.ult (m, n)
Возвращает логическое значение, true, если целое m ниже целого n , когда они сравниваются как беззнаковые целые.
6.8 – Средства ввода-вывода
Библиотека ввода-вывода предоставляет два разных стиля для файловых манипуляций. Первый использует подразумевающиеся описатели файлов (handle); т.е. там есть операции установки файла ввода и файла вывода по умолчанию, и все операции ввода-вывода используют эти файлы. Второй стиль использует явные описатели файлов.
При использовании неявных описателей файлов, все операции предоставляются в таблице io . При использовании явных описателей, операция io.open возвращает описатель файла и затем все операции предоставляются, как методы этого описателя.
Таблица io также предоставляет три предопределенных файловых описателя с обычными значениями из C: io.stdin , io.stdout и io.stderr . Библиотека ввода-вывода никогда не закрывает эти файлы.
Пока не установлено иначе, все функции ввода-вывода возвращают nil при ошибке (и сообщение об ошибке, как второй результат, и зависящий от системы код ошибки, как третий) и отличное от nil значение при успехе. На не POSIX системах, формирование сообщения об ошибке и кода ошибки может не быть потокобезопасным, т.к. они полагаются на глобальную C переменную errno .
io.close ([file])
Эквивалентно file:close() . Без file , закрывает выходной файл по умолчанию.
io.flush ()
io.input ([file])
Когда вызвана с именем файла, открывает данный файл (в текстовом режиме), и устанавливает его описатель, как файл ввода по умолчанию. Когда вызвана с описателем файла, просто устанавливает этот описатель, как файл ввода по умолчанию Когда вызвана без параметров, возвращает текущий файл ввода по умолчанию.
В случае ошибок эта функция генерирует ошибку, вместо возвращения кода ошибки.
io.lines ([filename ···])
Открывает переданный файл в режиме чтения и возвращает функцию итератор, которая работает подобно file:lines(···) для открытого файла. Когда итератор доходит до конца файла, он ничего не возвращает (для завершения цикла) и автоматически закрывает файл.
Вызов io.lines() (без имени файла) эквивалентно io.input():lines(«*l») ; т.е. он перебирает линии файла ввода по умолчанию. В этом случае он не закрывает файл при завершении цикла.
В случае ошибок эта функция генерирует ошибку, вместо возвращения кода ошибки.
io.open (filename [, mode])
Функция открывает файл в режиме, определяемым строкой mode . Возвращает новый описатель файла, или, в случае ошибок, возвращает nil и сообщение об ошибке.
- » r «: режим чтения (по умолчанию);
- » w «: режим записи;
- » a «: режим добавления;
- » r+ «: режим обновления, все предыдущие данные сохраняются;
- » w+ «: режим обновления, все предыдущие данные стираются;
- » a+ «: режим добавления и обновления, предыдущие данные сохраняются, запись разрешена только в конец файла.
Строка mode также может содержать ‘ b ‘ в конце, это нужно на некоторых системах для открытия файла в бинарном режиме.
io.output ([file])
Подобно io.input , но для файла вывода по умолчанию.
io.popen (prog [, mode])
Эта функция зависит от системы и не доступна на некоторых платформах.
Запускает программу prog в отдельном процессе и возвращает описатель файла, который вы можете использовать для чтения данных из этой программы (если mode = «r» , по умолчанию) или для записи данных в программу (если mode = «w» ).
io.read (···)
io.tmpfile ()
Возвращает описатель для временного файла. Этот файл открывается в режиме обновления и автоматически удаляется по завершении программы.
io.type (obj)
Проверяет, что независимый obj это правильный описатель файла. Возвращает строку «file» — если obj открытый описатель файла, «closed file» — если obj закрытый описатель файла, или nil — если obj не является описателем файла.
io.write (···)
file:close ()
Закрывает file . Учтите, что файлы закрываются автоматически, когда их описатели собраны сборщиком мусора, но это может занять неопределенное количество времени.
Когда закрываемый описатель файла создан функцией io.popen , file:close возвращает те же значения, что и os.execute .
file:flush ()
Сохраняет все записанные данные в file .
file:lines (···)
Возвращает функцию итератор, которая при каждом вызове читает файл в соответствии с переданными форматами. Когда формат не передан, использует » l «, по умолчанию. Например, конструкция
будет перебирать все символы файла, начиная с текущей позиции. В отличие от io.lines , эта функция не закрывает файл после завершения цикла.
В случае ошибок эта функция генерирует ошибку, вместо возвращения кода ошибки.
file:read (···)
Читает файл file , в соответствии с переданными форматами, которые определяют, что читать. Для каждого формата, функция возвращает строку или число с прочитанными символами, или nil, если не может прочитать данные в этом формате. (В этом последнем случае, функция не читает последующие форматы.) Когда вызвана без форматов, использует по умолчанию формат, читающий следующую строку (см. ниже).
- » n «: читает число и возвращает его, как вещественное или целое, следуя лексическим соглашениям Lua. (Число может содержать начальные пробелы и знак.) Этот формат всегда читает самую длинную входную последовательность, которая является правильным префиксом для числа; если префикс не правильный (пустая строка, » 0x » или » 3.4e- «), он отбрасывается и функция возвращает nil.
- » a «: читает весь файл, начиная с текущей позиции. В конце файла возвращает пустую строку.
- » l «: читает следующую строку, пропуская символ конца строки, возвращает nil в конце файла. Это формат по умолчанию.
- » L «: читает следующую строку, сохраняя символ конца строки (если есть), возвращает nil в конце файла.
- число: читает строку этой длины в байтах, возвращает nil в конце файла. Если number = 0, ничего не читает и возвращает пустую строку, или nil в конце файла.
Форматы » l » и » L » должны использоваться только для текстовых файлов.
file:seek ([whence [, offset]])
- » set «: база на позиции 0 (начало файла);
- » cur «: база на текущей позиции;
- » end «: база в конце файла;
В случае успеха, seek возвращает окончательную позицию в файле, измеряемую в байтах от начала файла. При ошибке, возвращает nil и сообщение об ошибке.
По умолчанию whence = «cur» , offset = 0. Так вызов file:seek() возвращает текущую позицию, не изменяя её; вызов file:seek(«set») устанавливает позицию в начало файла (и возвращает 0); вызов file:seek(«end») устанавливает позицию в конец файла и возвращает размер файла.
file:setvbuf (mode [, size])
- » no «: без буферизации; результат любой операции вывода проявляется непосредственно.
- » full «: полная буферизация; операция вывода выполняется только, когда буфер полон или когда вы явно сбрасываете (flush) файл (см. io.flush ).
- » line «: строчная буферизация; выход буферизуется до новой строки в выводе или до любого ввода из специальных файлов (таких как терминал).
Для двух последних случаев size определяет размер буфера, в байтах. По умолчанию это подходящий размер.
file:write (···)
Записывает значение каждого аргумента в file . Аргументы должны быть строками или числами.
В случае успеха функция возвращает file . Иначе, возвращает nil и сообщение об ошибке.
6.9 – Средства операционной системы
Эта библиотека реализована через таблицу os .
os.clock ()
Возвращает апроксимацию количества секунд времени процессора, использованного программой.
os.date ([format [, time]])
Возвращает строку или таблицу, содержащую дату и время, отформатированную в соответствии с переданной строкой format .
Если аргумент time передан, то он является временем для форматирования (см. функцию os.time для описания этого значения). Иначе, date форматирует текущее время.
Если format начинается с символа ‘ ! ‘, то дата форматируется во всемирном координированном времени (UTC). После этого опционального символа, если format это строка » *t «, то date возвращает таблицу со следующими полями: year — год (четыре цифры), month — месяц (1–12), day — день (1–31), hour — час (0–23), min — минута (0–59), sec — секунда (0–61), wday — день недели (воскресенье = 1), yday — день в году и isdst — летнее время (boolean). Это последнее поле может отсутствовать, если информация недоступна.
Если format не » *t «, то date возвращает дату как строку, форматированную согласно правилам C функции strftime .
Когда вызвана без аргументов, date возвращает разумное представление даты и времени, зависящее от хостовой системы и текущей локали (т.е. os.date() эквивалентно os.date(«%c») ).
На не POSIX системах эта функция может не быть потокобезопасной, т.к. она использует C функции gmtime и localtime .
os.difftime (t2, t1)
Возвращает разницу, в секундах, от времени t1 до времени t2 (где значения времени возвращены os.time ). В POSIX, Windows и некоторых других системах это значение точно t2 — t1 .
os.execute ([command])
- » exit «: команда завершена нормально; следующее число это выходной статус команды.
- » signal «: команда была завершена сигналом; следующее число это сигнал, завершивший команду.
Когда вызвана без command , os.execute возвращет логическое значение, которое равно true, если оболочка (shell) доступна.
os.exit ([code [, close]])
Вызывает ISO C функцию exit для завершения хостовой программы. Если code = true, возвращается статус EXIT_SUCCESS ; если code = false, возвращается статус EXIT_FAILURE ; если code это число, возвращается статус равный этому числу. По умолчанию, code = true.
Если опциональный второй аргумент close = true, закрывает Lua состояние перед выходом.
os.getenv (varname)
Возвращает значение переменной окружения процесса varname , или nil, если переменная не определена.
os.remove (filename)
Удаляет файл (или пустую директорию, на POSIX системах) с переданным именем. Если функция терпит неудачу, она возвращает nil, сообщение об ошибке и код ошибки.
os.rename (oldname, newname)
Переименовывает файл или директорию oldname в newname . Если функция терпит неудачу, она возвращает nil, сообщение об ошибке и код ошибки.
os.setlocale (locale [, category])
Устанавливает текущую локаль для программы. locale — системозависимая строка, определяющая локаль; category — опциональная строка, описывающая какую категорию изменять: «all» , «collate» , «ctype» , «monetary» , «numeric» или «time» ; по умолчанию category = «all» . Функция возвращает имя новой локали, или nil, если запрос не может быть выполнен.
Если locale это пустая строка, текущая локаль устанавливается в засимую от реализации родную локаль. Если locale это строка » C «, текущая локаль устанавливается в стандартную C локаль.
Когда вызвана с nil в качестве первого аргумента, эта функция только возвращает имя текущей локали для данной категории.
Эта функция может не быть потокобезопасной, т.к. использует C функцию setlocale .
os.time ([table])
Возвращает текущее время, когда вызвана без аргуменов, или время, представляющее локальную дату и время определенные в переданной таблице. Эта таблица должна иметь поля year , month и day , и может иметь поля hour (по умолчанию, 12), min (по умолчанию, 0), sec (по умолчанию, 0) и isdst (по умолчанию, nil). Остальные поля игнорируются. Для описания этих полей, см. функцию os.date .
Значения этих полей могут не быть в своих правильных диапазонах. Например, если sec = -10, то это означает -10 секунд от времени, определенного другими полями; если hour = 1000, это означает +1000 часов от времени, определенного другими полями.
Возвращенное значение это число, значение которого зависит от вашей системы. В POSIX, Windows и некоторых других системах это количество секунд, прошедших с какого-то определенного времени («эпоха»). В других системах, значение не определено, и число, возвращенное функцией time , может использоваться только, как аргумент для os.date и os.difftime .
os.tmpname ()
Возвращает строку с именем файла, который может быть использован, как временный. Файл должен быть явно открыт перед использованием и явно удален, когда больше не нужен.
На POSIX системах эта функция также создает файл с этим именем, для избежания рисков беззопасности. (Кто-нибудь другой может создать файл с неправильными разрешениями в промежуток времени между получением имени файла и его созданием.) Вы по прежнему должны открыть файл для его использования и удалить его (даже если не использовали).
Когда возможно, предпочтительно использовать функцию io.tmpfile , которая автоматически удаляет файл при завершении программы.
6.10 – Библиотека отладки
Эта библиотека предоставляет Lua программам функциональность отладочного интерфейса (§4.9). Используя эту библиотеку, вы должны проявлять внимательность. Различные функции этой билиотеки нарушают базовые предположения о Lua коде (например, что локальные переменные функции не могут быть доступны снаружи; что метатаблицы пользовательских данных не могут изменяться Lua кодом; что Lua программы не падают) и следовательно могут скомпрометировать защищенный код. Кроме того, некоторые функции в этой библиотеке могут быть медленными.
Все функции в этой библиотеке предоставляются в таблице debug . Все функции, которые оперируют с потоком, имеют опциональный первый аргумент, определяющий поток. По умолчанию, это всегда текущий поток.
debug.debug ()
Входит в интерактивный режим с пользователем, запуская каждую строку, вводимую пользователем. Используя простые команды и другие отладочные возможности, пользователь может проверять глобальные и локальные переменные, изменять их значения, вычислять выражения и т.д. Строка, содержащая только слово cont , завершает эту функцию, так что вызывающий продожает своё исполнение.
Учтите, что команды для debug.debug не являются лексически вложенными ни в одну функцию и не имеют прямого доступа к локальным переменным.
debug.gethook ([thread])
Возвращает настройки текущего перехватчика потока, как три значения: текущая функция-перехватчик, текущая маска перехвата и текущий счетчик перехвата (как установлено функцией debug.sethook ).
debug.getinfo ([thread,] f [, what])
Возвращает таблицу с информацией о функции. Вы можете передать функцию напрямую или можете передать число, как значение f , которое означает функцию, выполняющуюся на уровне f стека вызовов данного потока thread: уровень 0 — текущая функция (непосредственно getinfo ); уровень 1 — функция, которая вызвала getinfo (за исключением хвостовых вызовов, которые не считаются на стеке); и так далее. Если число f больше количества активных функций, то getinfo возвращает nil.
Возвращенная таблица может содержать все поля возвращаемые lua_getinfo , со строкой what , описывающей какие поля заполнены. По умолчанию, what установлена для получения всей доступной информации, кроме таблицы значимых строк. Если передана, опция ‘ f ‘ добавляет поле func с функцией непосредственно. Если передана, опция ‘ L ‘ добавляет поле activelines с таблицей значимых строк.
Например, выражение debug.getinfo(1,»n»).name возвращает имя текущей функции, если разумное имя существует, и выражение debug.getinfo(print) возвращает таблицу со всей доступной информацией о функции print .
debug.getlocal ([thread,] f, local)
Эта функция возвращает имя и значение локальной переменной с индексом local функции на уровне f стека вызовов. Эта функция получает доступ не только к явным локальным переменным, но также к параметрам, временным переменныи и др.
Первый параметр или локальная переменная имеет индекс 1, и так далее, следуя порядку определения в коде, считаются только активные переменные в текущей области функции. Отрицательные индексы ссылаются на переменные (vararg) параметры; -1 первый переменный параметр. Функция возвращает nil, если нет переменной по данному индексу, и вызывает ошибку, когда вызвана с уровнем за пределами диапазона. (Вы можете вызвать debug.getinfo чтобы проверить, какой уровень допустим.)
Имена переменных, начинающиеся с ‘ ( ‘ (открывающая скобка) представляют переменные с неизвестными именами (внутренние переменные, такие как переменные управления циклом, и переменные из кусков, сохраненных без отладочной информации).
Параметр f также может быть функцией. В этом случае getlocal возвращает только имена параметров функции.
debug.getmetatable (value)
Возвращает метатаблицу переданного значения value или nil, если у значения нет метатаблицы.
debug.getregistry ()
Возвращает таблицу реестра (см. §4.5).
debug.getupvalue (f, up)
Эта функция возвращает имя и значение upvalue с индексом up функции f . Функция возвращает nil, если по данному индексу нет upvalue.
Имена переменных, начинающиеся с символа ‘ ( ‘ (открывающая скобка) , представляют переменные с неизвестными именами (переменные из кусков, сохраненных без отладочной информации).
debug.getuservalue (u)
Возвращает Lua значение, ассоциированное с u . Если u не пользовательские данные, возвращает nil.
debug.sethook ([thread,] hook, mask [, count])
- ‘ c ‘: перехватчик вызывается каждый раз, когда Lua вызывает функцию;
- ‘ r ‘: перехватчик вызывается каждый раз, когда Lua возвращается из функции;
- ‘ l ‘: перехватчик вызывается каждый раз, когда Lua входит на новую линию кода.
Кроме того, с count не равным нулю, перехватчик вызывается также через каждые count инструкций (count в значении «количество»).
Когда вызвана без аргументов, debug.sethook выключает перехват.
Когда вызван перехватчик, его первый параметр — это строка, описывающая событие, которое стало причиной вызова перехватчика: «call» (или «tail call» ), «return» , «line» и «count» . Для событий строк, перехватчик также получает номер строки во втором параметре. Внутри перехватчика вы можете вызвать getinfo с уровнем 2 для получения информации о запущенной функции (уровень 0 — это функция getinfo , уровень 1 — это функция-перехватчик).
debug.setlocal ([thread,] level, local, value)
Эта функция присваивает значение value локальной переменной по индексу local функции на уровне level в стеке вызовов. Функция возвращает nil, если локальная переменная с данным индексом не существует, и генерирует ошибку, когда вызвана с level вне диапазона. (Вы можете использовать getinfo чтобы проверить какой уровень допустим.) Иначе, возвращает имя локальной переменной.
См. debug.getlocal для дополнительной информации о именах и индексах переменных.
debug.setmetatable (value, table)
Устанавливает table метатаблицей для value ( table может быть равно nil). Возвращает value .
debug.setupvalue (f, up, value)
Эта функция присваивает значение value в upvalue с индексом up функции f . Функция возвращает nil, если по данному индексу нет upvalue. Иначе, возвращает имя upvalue.
debug.setuservalue (udata, value)
Устанавливает переданное значение value , как Lua значение, ассоциированное с udata . udata должно быть полными пользовательскими данными.
debug.traceback ([thread,] [message [, level]])
Если message передано, но не строка и не nil, эта функция возвращет message без дальнейшей обработки. Иначе, возвращает строку с трассировкой стека вызовов. Опциональная строка message добавляется в начале трассировки стека. Опциональное число level говорит, на каком уровне начинать трассировку (по умолчанию равен 1 — функция, вызвавшая traceback ).
debug.upvalueid (f, n)
Возвращает уникальный идентификатор (как лёгкие пользовательские данные) для upvalue под номером n из переданной функции.
Эти уникальные идентификаторы позволяют программе проверить, когда разные замыкания совместно используют одни upvalue. Lua замыкания, которые совместно используют upvalue (т.е. имеют доступ к одной внешней локальной переменной) вернут одинаковые идентификаторы для этих upvalue.
debug.upvaluejoin (f1, n1, f2, n2)
Заставляет n1 -е upvalue Lua замыкания f1 ссылаться на n2 -е upvalue Lua замыкания f2 .
7 – Интерпретатор Lua
Хотя Lua был разработан, как язык расширений, чтобы встраивать в хостовую C программу, он также часто используется, как автономный язык. Интерпретатор Lua, как автономного языка, называется просто lua и предоставляется в стандартном дистрибутиве. Автономный интерпретатор включает все стандартные библиотеки, в том числе отладочную библиотеку. Синтаксис командной строки:
- -e stat : запускает строку stat;
- -l mod : загружает (require) mod;
- -i : входит в интерактивный режим после запуска script;
- -v : печатает информацию о версии;
- -E : игнорирует переменные окружения;
- — : останавливает обработку опций;
- — : запускает stdin как файл и останавливает обработку опций.
После обработки опций, lua запускает переданный скрипт (script). Когда вызван без аргументов, lua ведет себя, как lua -v -i , когда стандартный ввод ( stdin ) это терминал; и как lua — иначе.
Когда вызван без опции -E , интерпретатор проверяет переменную окружения LUA_INIT_5_3 (или LUA_INIT , если предыдущая не определена) перед запуском аргументов. Если содержимое переменной имеет формат @filename , то lua запускает это файл. Иначе, lua запускает непосредственно эту строку.
Когда запущен с опцией -E , вместе с игнорированием LUA_INIT , Lua также игнорирует значения LUA_PATH и LUA_CPATH , устанавливая значения package.path и package.cpath путями по умолчанию, определенными в luaconf.h .
Все опции обрабатываются по порядку, кроме -i и -E . Например, вызов
сначала установит a = 1, затем напечатает значение a , и наконец запустит файл script.lua без аргументов. (Здесь $ — это приглашение командной строки. Ваше приглашение может отличаться.)
Перед запуском любого кода lua собирает все аргументы командной строки в глобальной таблице arg . Имя скрипта идет под индексом 0, первый аргумент после имени скрипта идет по индексу 1, и т.д. Все аргументы перед именем скрипта (т.е имя интерпретатора и его опции) находятся по отрицательным индексам. Например, вызов
Если в вызове нет скрипта, имя интерпретатора идет по индексу 0, далее идут другие аргументы. Например, вызов
напечатает » -e «. Если есть скрипт, то он вызывается с параметрами arg[1] , ···, arg[#arg] . (Как все куски в Lua, скрипт компилируется, как функция с переменным числом аргументов.)
В интерактивном режиме, Lua многократно выдает приглащение и ждет ввода строки. После ввода строки, Lua сначала пробует интерпретировать строку как выражение. В случае успеха, печатает её значение. Иначе, интерпретирует строку как оператор. Если вы напишете незавершенное выражение, интерпретатор будет ждать его завершения, выдывая приглашение.
В случае незащищенных ошибок в скрипте, интерпретатор пишет ошибку в стандартный поток ошибок. Если объект ошибки это не строка, но имеет метаметод __tostring , интерпретатор вызывает этот метаметод для выдачи финального сообщения. Иначе, интерпретатор конвертирует объект ошибки в строку и добавляет к нему трассировку стека.
При нормальном завершении интерпретатор закрывает своё главное Lua состояние (см. lua_close ). Скрипт может избежать этого шага, вызвав os.exit для завершения.
Чтобы использовать Lua, как интерпретатор скриптов в Unix системах, автономный интерпретатор пропускает первую линию куска, если он начинается с символа # . Следовательно, Lua скрипты могут быть сделаны исполняемыми программами, используя chmod +x и #! форму, например
(Конечно, расположение Lua интерпретатора может быть другим. Если lua в вашей переменной PATH , то
более портабельное решение.)
8 – Несовместимости с предыдущей версией
Здесь приведен список несовместимостей, которые вы можете встретить при портировании программы с Lua 5.2 в Lua 5.3. Вы можете избежать некоторые несовместимости, скомпилировав Lua с соответствующими опциями (см. файл luaconf.h ). Тем не менее, все эти опции совметимости будут убраны в будущем.
Версии Lua всегда могут изменить C API способами, которые не подразумевают изменение исходного кода программы, такие, как цифровые значения констант или реализация функций через макросы. Следовательно, вы не должны ожидать бинарной совметимости между разными версиями Lua. Всегда перекомпилируйте клиентов Lua API, когда используете новую версию.
Аналогично, версии Lua всегда могут изменить внутреннее представление скомпилированных кусков; скомпилированные куски не совместимы между разными версиями Lua.
Стандартные пути в официальном дистрибутиве могут меняться между версиями.
8.1 – Изменения в языке
- Главное различие между Lua 5.2 и Lua 5.3 это введение подтипа целых для чисел. Хотя это изменение не влияет на «нормальные» вычисления, некоторые вычисления (главным образом это некоторые типы переполнений) могут давать разные результаты.
8.2 – Изменения в библиотеках
- Библиотека bit32 стала нежелательной. Легко загрузить совместимую внешнюю библиотеку или лучше заменить её функции соответствующими битовыми операторами. (Помните, что bit32 оперирует с 32-битными целыми, а битовые операторы Lua 5.3 оперируют с целыми Lua, которые по умолчанию имеют 64 бита.)
- Табличная библиотека теперь уважает метаметоды для установки и получения элементов.
- Итератор ipairs теперь уважает метаметоды и его метаметод __ipairs стал нежелательным.
- Имена опций в io.read больше не имеют начального символа ‘ * ‘. Для совместимости Lua продолжит принимать (и игнорировать) этот символ.
- Следующие функции стали нежелательными в математической библиотеке: atan2 , cosh , sinh , tanh , pow , frexp и ldexp . Вы можете заменить math.pow(x,y) на x^y ; вы можете заменить math.atan2 на math.atan , который теперь принимает один или два параметра; вы можете заменить math.ldexp(x,exp) на x * 2.0^exp . Для других операций вы можете также использовать внешнюю библиотеку или реализовать их в Lua.
- Искатель для C загрузчиков, используемый require , изменил способ обработки имен с версиями. Сейчас версия должна идти после имени модуля (как обычно в большинстве других инструментов). Для совместимости, этот искатель все еще пытается использовать старый формат, если не может найти функцию открытия соответствующую новому стилю. (Lua 5.2 уже работает таким способом, но это не документировано.)
- Вызов collectgarbage(«count») сейчас возвращает только один результат. (Вы можете вычислить второй результат из дробной части первого результата.)
8.3 – Изменения в API
- Функции продолжения сейчас принимают как параметры то, что им нужно было получать через lua_getctx , так функция lua_getctx была удалена. Откорректируйте ваш код соответственно.
- Функция lua_dump имеет дополнительный параметр strip . Используйте 0 для этого параметра, чтобы получить старое поведение.
- Функции для вставки/получения беззнаковых целых ( lua_pushunsigned , lua_tounsigned , lua_tounsignedx , luaL_checkunsigned , luaL_optunsigned ) нежелательны. Используйте их знаковые эквиваленты с преобразованием типа.
- Макросы для получения нестандартных целых типов ( luaL_checkint , luaL_optint , luaL_checklong , luaL_optlong ) нежелательны. Используйте их эквиваленты с lua_Integer с преобразованием типов (или, когда возможно, используйте lua_Integer в вашем коде).
9 – Полный синтаксис Lua
Здесь приведен полный синтаксис Lua в БНФ. Как обычно в расширенной БНФ, означает 0 или более A, и [A] означает опциональное A. (Для приоритета операторов, см. §3.4.8; для описания терминалов Name, Numeral и LiteralString, см. §3.1.)
Last update: Wed Jun 10 18:31:15 BRT 2015 Last change: revised for Lua 5.3.1
Lua – Обзор
Lua – это расширяемый, легкий язык программирования, написанный на языке C. Он начался как собственный проект в 1993 году Роберто Иерусалимши, Луиса Энрике де Фигейредо и Вальдемара Селеса.
С самого начала оно было разработано как программное обеспечение, которое может быть интегрировано с кодом, написанным на C и других традиционных языках. Эта интеграция приносит много преимуществ. Он не пытается делать то, что C уже может сделать, но стремится предложить то, что C не очень хорошо: хорошее расстояние от аппаратного обеспечения, динамические структуры, отсутствие избыточности, простота тестирования и отладки. Для этого Lua имеет безопасную среду, автоматическое управление памятью и хорошие возможности для обработки строк и других видов данных с динамическим размером.
Характеристики
Lua предоставляет набор уникальных функций, которые отличают его от других языков. К ним относятся –
- растяжимый
- просто
- эффективное
- портативный
- Свободно и открыто
Пример кода
Как реализуется Lua?
Lua состоит из двух частей – части интерпретатора Lua и функционирующей системы программного обеспечения. Функциональная система программного обеспечения – это реальное компьютерное приложение, которое может интерпретировать программы, написанные на языке программирования Lua. Интерпретатор Lua написан на языке ANSI C, поэтому он очень переносим и может работать на широком спектре устройств – от высокопроизводительных сетевых серверов до небольших устройств.
И язык Луа, и его переводчик зрелые, маленькие и быстрые. Он произошел от других языков программирования и высочайших стандартов программного обеспечения. Небольшой размер позволяет запускать его на небольших устройствах с небольшим объемом памяти.
Учим Луа
Самый важный момент при изучении Lua – это сосредоточиться на концепциях, не теряясь в технических деталях.
Цель изучения языка программирования – стать лучшим программистом; то есть, чтобы стать более эффективным в разработке и внедрении новых систем и в поддержании старых.
Некоторые варианты использования Lua
Сценарии в автономных приложениях
Сценарии в Интернете
Расширения и дополнения для баз данных, таких как MySQL Proxy и MySQL WorkBench
Системы безопасности, такие как система обнаружения вторжений.
Сценарии в автономных приложениях
Сценарии в Интернете
Расширения и дополнения для баз данных, таких как MySQL Proxy и MySQL WorkBench
Системы безопасности, такие как система обнаружения вторжений.
Луа – Окружающая среда
Настройка локальной среды
Если вы все еще хотите настроить свою среду для языка программирования Lua, вам потребуются следующие программы, доступные на вашем компьютере: (а) текстовый редактор, (б) интерпретатор Lua и (в) компилятор Lua.
Текстовый редактор
Вам нужен текстовый редактор, чтобы напечатать вашу программу. Примеры нескольких редакторов: Блокнот Windows, команда «Редактирование ОС», Brief, Epsilon, EMACS и vim или vi.
Имя и версия текстового редактора могут различаться в разных операционных системах. Например, Блокнот будет использоваться в Windows, а vim или vi могут использоваться в Windows, а также в Linux или UNIX.
Файлы, которые вы создаете с помощью вашего редактора, называются исходными файлами, и эти файлы содержат исходный код программы. Исходные файлы для программ Lua обычно называются с расширением “.lua” .
Переводчик Lua
Это небольшая программа, которая позволяет вам набирать команды Lua и выполнять их немедленно. Он останавливает выполнение файла Lua в случае возникновения ошибки в отличие от компилятора, который выполняется полностью.
Компилятор Lua
Когда мы расширяем Lua на другие языки / приложения, нам нужен комплект разработки программного обеспечения с компилятором, совместимым с прикладным программным интерфейсом Lua.
Установка на Windows
Для среды Windows разработана отдельная среда разработки под названием «SciTE», которую можно скачать из https://code.google.com/p/luaforwindows/ раздела загрузки.
Запустите загруженный исполняемый файл, чтобы установить Lua IDE.
Поскольку это IDE, вы можете создавать и создавать код Lua, используя одно и то же.
В случае, если вы заинтересованы в установке Lua в режиме командной строки, вам необходимо установить MinGW или Cygwin, а затем скомпилировать и установить Lua в Windows.
Установка в Linux
Чтобы загрузить и собрать Lua, используйте следующую команду –
Чтобы установить на другие платформы, такие как aix, ansi, bsd, generic linux, mingw, posix, solaris, заменив Linux на make Linux, протестируйте его с соответствующим именем платформы.
У нас есть helloWorld.lua, в Lua следующим образом:
Теперь мы можем создать и запустить файл Lua, скажем helloWorld.lua, переключившись на папку, содержащую файл, с помощью cd, а затем с помощью следующей команды:
Мы можем увидеть следующий вывод.
Установка в Mac OS X
Чтобы собрать / протестировать Lua в Mac OS X, используйте следующую команду –
В некоторых случаях вы, возможно, не установили Xcode и инструменты командной строки. В таких случаях вы не сможете использовать команду make. Установите Xcode из магазина приложений Mac. Затем перейдите в «Настройки XCode», а затем переключитесь на «Загрузки» и установите компонент с именем «Инструменты командной строки». Как только процесс будет завершен, вам будет доступна команда make.
Вам не обязательно выполнять инструкцию «make macosx test». Даже без выполнения этой команды вы все равно можете использовать Lua в Mac OS X.
У нас есть helloWorld.lua, в Lua, следующим образом –
Теперь мы можем создать и запустить файл Lua, скажем helloWorld.lua, переключившись на папку, содержащую файл, с помощью cd, а затем с помощью следующей команды:
Мы можем увидеть следующий вывод –
Lua IDE
Как упоминалось ранее, для Windows SciTE, IDE Lua является IDE по умолчанию, предоставляемой командой создателей Lua. Доступна альтернативная IDE от ZeroBrane Studio, которая доступна на нескольких платформах, таких как Windows, Mac и Linux.
Есть также плагины для затмения, которые позволяют разработку Lua. Использование IDE облегчает разработку благодаря таким функциям, как завершение кода, и настоятельно рекомендуется. Среда IDE также обеспечивает программирование в интерактивном режиме, аналогичное версии Lua для командной строки.
Lua – основной синтаксис
Давайте начнем создавать нашу первую программу Lua!
Первая программа Lua
Программирование в интерактивном режиме
Lua предоставляет режим, называемый интерактивным режимом. В этом режиме вы можете вводить инструкции одну за другой и получать мгновенные результаты. Это может быть вызвано в оболочке с помощью lua -i или просто команды lua. Как только вы введете это, нажмите Enter, и интерактивный режим будет запущен, как показано ниже.
Вы можете напечатать что-нибудь, используя следующее утверждение –
Как только вы нажмете Enter, вы получите следующий вывод –
Программирование в режиме по умолчанию
Вызов интерпретатора с параметром имени файла Lua начинает выполнение файла и продолжается до завершения сценария. Когда сценарий завершен, интерпретатор больше не активен.
Давайте напишем простую программу Lua. Все файлы Lua будут иметь расширение .lua. Поэтому поместите следующий исходный код в файл test.lua.
Предполагая, что среда lua настроена правильно, давайте запустим программу, используя следующий код –
Мы получим следующий вывод –
Давайте попробуем другой способ выполнить программу Lua. Ниже приведен модифицированный файл test.lua –
Здесь мы предположили, что в вашем каталоге / usr / local / bin есть интерпретатор Lua. Первая строка игнорируется интерпретатором, если она начинается со знака #. Теперь попробуйте запустить эту программу следующим образом:
Мы получим следующий вывод.
Давайте теперь посмотрим на базовую структуру программы Lua, так что вам будет легко понять основные строительные блоки языка программирования Lua.
Жетоны в Луа
Программа Lua состоит из различных токенов, и токен является ключевым словом, идентификатором, константой, строковым литералом или символом. Например, следующий оператор Lua состоит из трех токенов:
Комментарии
Комментарии подобны тексту помощи в вашей программе Lua, и интерпретатор их игнорирует. Они начинаются с – [[и заканчиваются символами -]], как показано ниже –
Идентификаторы
Lua-идентификатор – это имя, используемое для идентификации переменной, функции или любого другого пользовательского элемента. Идентификатор начинается с буквы «от А до Я» или «от А до Я» или со знака подчеркивания «_», за которым следуют ноль или более букв, подчеркиваний и цифр (от 0 до 9).
Lua не допускает знаки препинания, такие как @, $ и% в идентификаторах. Lua – чувствительный к регистру язык программирования. Таким образом, рабочая сила и рабочая сила – два разных идентификатора в Lua. Вот несколько примеров допустимых идентификаторов:
Ключевые слова
Следующий список показывает несколько зарезервированных слов в Lua. Эти зарезервированные слова не могут использоваться в качестве констант или переменных или любых других имен идентификаторов.
а также | перерыв | делать | еще |
ElseIf | конец | ложный | за |
функция | если | в | местный |
ноль | не | или же | повторение |
вернуть | затем | правда | до тех пор |
в то время как |
Пробелы в Луа
Строка, содержащая только пробел, возможно, с комментарием, называется пустой строкой, и интерпретатор Lua полностью игнорирует ее.
Пробел – это термин, используемый в Lua для описания пробелов, вкладок, символов новой строки и комментариев. Пробелы отделяют одну часть оператора от другой и позволяют интерпретатору определить, где заканчивается один элемент в выражении, например, int, и начинается следующий элемент. Поэтому в следующем утверждении –
Должен быть хотя бы один пробельный символ (обычно пробел) между местным и возрастом, чтобы переводчик мог их различить. С другой стороны, в следующем утверждении –
Никаких пробельных символов не требуется между фруктами и = или между = и яблоками, хотя вы можете включить некоторые из них, если хотите, чтобы они были удобочитаемыми.
Lua – переменные
Переменная – это не что иное, как имя, данное области памяти, которой могут манипулировать наши программы. Он может содержать различные типы значений, включая функции и таблицы.
Имя переменной может состоять из букв, цифр и символа подчеркивания. Он должен начинаться либо с буквы, либо с подчеркивания. Прописные и строчные буквы различны, потому что Lua чувствителен к регистру. В Lua есть восемь основных типов ценностей:
В Lua, хотя у нас нет переменных типов данных, у нас есть три типа, основанные на области действия переменной.
Глобальные переменные – все переменные считаются глобальными, если они явно не объявлены как локальные.
Локальные переменные – когда тип указан как локальный для переменной, тогда его область действия ограничена функциями внутри их области.
Поля таблицы – это специальный тип переменной, который может содержать все, кроме nil, включая функции.
Глобальные переменные – все переменные считаются глобальными, если они явно не объявлены как локальные.
Локальные переменные – когда тип указан как локальный для переменной, тогда его область действия ограничена функциями внутри их области.
Поля таблицы – это специальный тип переменной, который может содержать все, кроме nil, включая функции.
Определение переменной в Lua
Определение переменной означает сообщить интерпретатору, где и сколько создать хранилище для переменной. Определение переменной имеет необязательный тип и содержит список из одной или нескольких переменных этого типа следующим образом:
Здесь тип необязательно является локальным, или тип определяется как глобальный, а переменная_лист может состоять из одного или нескольких имен идентификаторов, разделенных запятыми. Некоторые действительные объявления показаны здесь –
Строка local i, j объявляет и определяет переменные i и j; который указывает интерпретатору создавать переменные с именами i, j и ограничивает область видимости локальным.
Переменные могут быть инициализированы (им присвоено начальное значение) в их объявлении. Инициализатор состоит из знака равенства, за которым следует постоянное выражение:
Вот некоторые примеры:
Для определения без инициализатора: переменные со статической продолжительностью хранения неявно инициализируются значением nil.
Объявление переменных в Lua
Как вы можете видеть в приведенных выше примерах, присваивания для кратных переменных следуют формату variable_list и value_list. В приведенном выше примере локального d, f = 5,10 у нас есть d и f в variable_list и 5 и 10 в списке значений.
Присвоение значения в Lua происходит как первая переменная в variable_list с первым значением в value_list и так далее. Следовательно, значение d равно 5, а значение f равно 10.
пример
Попробуйте следующий пример, где переменные были объявлены сверху, но они были определены и инициализированы внутри основной функции –
Когда приведенный выше код создается и выполняется, он дает следующий результат –
Lvalues и Rvalues в Lua
В Lua есть два вида выражений:
lvalue – Выражения, которые ссылаются на ячейку памяти, называются выражением «lvalue». Lvalue может отображаться как левая или правая сторона задания.
rvalue – термин rvalue относится к значению данных, которое хранится по некоторому адресу в памяти. Значение r – это выражение, которому не может быть присвоено значение, что означает, что значение r может появляться в правой части, но не в левой части присваивания.
lvalue – Выражения, которые ссылаются на ячейку памяти, называются выражением «lvalue». Lvalue может отображаться как левая или правая сторона задания.
rvalue – термин rvalue относится к значению данных, которое хранится по некоторому адресу в памяти. Значение r – это выражение, которому не может быть присвоено значение, что означает, что значение r может появляться в правой части, но не в левой части присваивания.
Переменные являются lvalues и могут отображаться в левой части назначения. Числовые литералы являются r-значениями и поэтому не могут быть назначены и не могут отображаться слева. Следующее является действительным утверждением –
Но следующее не является действительным утверждением и может привести к ошибке времени сборки –
В языке программирования Lua, помимо вышеупомянутых типов присваивания, можно иметь несколько значений l и r в одном и том же операторе. Это показано ниже.
В приведенном выше утверждении 20 назначено для g и 30 назначено для l.
Lua – Типы данных
Lua – это язык с динамической типизацией, поэтому переменные не имеют типов, только значения имеют типы. Значения могут храниться в переменных, передаваться как параметры и возвращаться как результаты.
В Lua, хотя у нас нет переменных типов данных, но у нас есть типы для значений. Список типов данных для значений приведен ниже.
Используется для дифференциации значения от наличия данных или отсутствия (ноль) данных.
Включает в себя значения true и false как значения. Обычно используется для проверки состояния.
Представляет действительные числа (числа с плавающей запятой двойной точности).
Представляет массив символов.
Представляет метод, который написан на C или Lua.
данные пользователя
Представляет произвольные данные Си.
Представляет независимые потоки выполнения и используется для реализации сопрограмм.
Представляет обычные массивы, таблицы символов, наборы, записи, графики, деревья и т. Д. И реализует ассоциативные массивы. Может содержать любое значение (кроме нуля).
Используется для дифференциации значения от наличия данных или отсутствия (ноль) данных.
Включает в себя значения true и false как значения. Обычно используется для проверки состояния.
Представляет действительные числа (числа с плавающей запятой двойной точности).
Представляет массив символов.
Представляет метод, который написан на C или Lua.
данные пользователя
Представляет произвольные данные Си.
Представляет независимые потоки выполнения и используется для реализации сопрограмм.
Представляет обычные массивы, таблицы символов, наборы, записи, графики, деревья и т. Д. И реализует ассоциативные массивы. Может содержать любое значение (кроме нуля).
Тип Функция
В Lua есть функция type, которая позволяет нам узнать тип переменной. Некоторые примеры приведены в следующем коде.
Когда вы создаете и запускаете вышеупомянутую программу, она дает следующий результат в Linux:
По умолчанию все переменные будут указывать на ноль, пока им не будет присвоено значение или они не будут инициализированы. В Lua нулевые и пустые строки считаются истинными в случае проверки условий. Следовательно, вы должны быть осторожны при использовании логических операций. Мы узнаем больше об использовании этих типов в следующих главах.
Луа – Операторы
Оператор – это символ, который говорит переводчику выполнять определенные математические или логические манипуляции. Язык Lua богат встроенными операторами и предоставляет операторы следующего типа:
- Арифметические Операторы
- Операторы отношений
- Логические Операторы
- Разные Операторы
Этот урок объяснит один за другим арифметические, реляционные, логические и другие разные операторы.
Арифметические Операторы
Следующая таблица показывает все арифметические операторы, поддерживаемые языком Lua. Предположим, что переменная A содержит 10, а переменная B содержит 20, тогда –
оператор | Описание | пример |
---|---|---|
+ | Добавляет два операнда | А + Б даст 30 |
– | Вычитает второй операнд из первого | A – B даст -10 |
* | Умножьте оба операнда | А * Б даст 200 |
/ | Разделите числитель на числитель | Б / у даст 2 |
% | Оператор модуля и остаток от целочисленного деления | B% A даст 0 |
^ | Экспонент Оператор принимает экспоненты | А ^ 2 даст 100 |
– | Унарный – оператор действует как отрицание | -А даст -10 |
Операторы отношений
Следующая таблица показывает все реляционные операторы, поддерживаемые языком Lua. Предположим, что переменная A содержит 10, а переменная B содержит 20, тогда –
Логические Операторы
В следующей таблице приведены все логические операторы, поддерживаемые языком Lua. Предположим, что переменная A имеет значение true, а переменная B содержит значение false тогда –
оператор | Описание | пример |
---|---|---|
а также | Называется логический оператор И. Если оба операнда отличны от нуля, условие становится истинным. | (А и В) ложно. |
или же | Вызывается логическим оператором ИЛИ. Если любой из двух операндов отличен от нуля, условие становится истинным. | (А или В) это правда. |
не | Вызывается логическим оператором НЕ. Используйте для изменения логического состояния своего операнда. Если условие истинно, то оператор Логический НЕ будет делать ложь. | ! (А и Б) это правда. |
Разные Операторы
Различные операторы, поддерживаемые Lua Language, включают конкатенацию и длину .
оператор | Описание | пример |
---|---|---|
.. | Объединяет две строки. | a..b, где a – «Hello», а b – «World», вернет «Hello World». |
# | Унарный оператор, который возвращает длину строки или таблицы. | # “Привет” вернется 5 |
Приоритет операторов в Lua
Приоритет оператора определяет группировку терминов в выражении. Это влияет на то, как оценивается выражение. Некоторые операторы имеют более высокий приоритет, чем другие; например, оператор умножения имеет более высокий приоритет, чем оператор сложения –
Например, х = 7 + 3 * 2; Здесь x назначено 13, а не 20, потому что оператор * имеет более высокий приоритет, чем +, поэтому он сначала умножается на 3 * 2, а затем прибавляется к 7.
Здесь операторы с самым высоким приоритетом отображаются вверху таблицы, а операторы с самым низким – внизу. Внутри выражения операторы с более высоким приоритетом будут оцениваться первыми.
Луа – Петли
Может возникнуть ситуация, когда вам нужно выполнить блок кода несколько раз. В общем случае операторы выполняются последовательно: первый оператор в функции выполняется первым, затем второй и так далее.
Языки программирования предоставляют различные управляющие структуры, которые допускают более сложные пути выполнения.
Оператор цикла позволяет нам выполнять оператор или группу операторов несколько раз. Ниже приводится общая форма оператора цикла в большинстве языков программирования:
Lua предоставляет следующие типы циклов для обработки требований циклов.
Повторяет оператор или группу операторов, пока данное условие выполняется. Он проверяет условие перед выполнением тела цикла.
Выполняет последовательность операторов несколько раз и сокращает код, который управляет переменной цикла.
Повторяет операцию группы операторов до тех пор, пока не будет выполнено условие.
Вы можете использовать один или несколько циклов внутри любого другого цикла while, for или do.. while.
Повторяет оператор или группу операторов, пока данное условие выполняется. Он проверяет условие перед выполнением тела цикла.
Выполняет последовательность операторов несколько раз и сокращает код, который управляет переменной цикла.
Повторяет операцию группы операторов до тех пор, пока не будет выполнено условие.
Вы можете использовать один или несколько циклов внутри любого другого цикла while, for или do.. while.
Loop Control Statement
Оператор управления циклом изменяет выполнение от своей обычной последовательности. Когда выполнение покидает область действия, все автоматические объекты, созданные в этой области, уничтожаются.
Lua поддерживает следующие контрольные операторы.
Завершает цикл и передает выполнение оператору сразу после цикла или переключателя.
Завершает цикл и передает выполнение оператору сразу после цикла или переключателя.
Бесконечный цикл
Цикл становится бесконечным, если условие никогда не становится ложным. Цикл while часто используется для этой цели. Поскольку мы прямо выражаем истинность условия, оно выполняется вечно. Мы можем использовать оператор break, чтобы разорвать этот цикл.
Луа – Принятие решений
Структуры принятия решений требуют, чтобы программист определял одно или несколько условий, которые должны быть оценены или протестированы программой, вместе с оператором или инструкциями, которые должны быть выполнены, если условие определено как истинное, и, необязательно, другие операторы, которые должны быть выполнены, если условие определяется как ложное.
Ниже приводится общая форма типичной структуры принятия решений, встречающейся в большинстве языков программирования.
Язык программирования Lua предполагает любую комбинацию логических значений true и не-nil как true , и если это либо логическое значение false, либо nil , то оно принимается за значение false . Следует отметить, что в Lua ноль будет считаться истинным.
Язык программирования Lua предоставляет следующие типы операторов принятия решений.
Оператор if состоит из логического выражения, за которым следует одно или несколько операторов.
За оператором if может следовать необязательный оператор else , который выполняется, когда логическое выражение имеет значение false.
Вы можете использовать один оператор if или else if внутри другого оператора if или else if .
Оператор if состоит из логического выражения, за которым следует одно или несколько операторов.
За оператором if может следовать необязательный оператор else , который выполняется, когда логическое выражение имеет значение false.
Вы можете использовать один оператор if или else if внутри другого оператора if или else if .
Lua – Функции
Функция – это группа операторов, которые вместе выполняют задачу. Вы можете разделить ваш код на отдельные функции. Как вы делите свой код между различными функциями, зависит от вас, но логически разделение обычно уникально, поэтому каждая функция выполняет определенную задачу.
Язык Lua предоставляет множество встроенных методов, которые может вызывать ваша программа. Например, метод print () для печати аргумента, переданного в качестве ввода в консоли.
Функция известна под разными именами, например, метод, подпрограмма, процедура и т. Д.
Определение функции
Общая форма определения метода в языке программирования Lua выглядит следующим образом:
Определение метода в языке программирования Lua состоит из заголовка метода и тела метода . Вот все части метода –
Необязательная область действия функции. Вы можете использовать ключевое слово local, чтобы ограничить область действия функции или игнорировать раздел области действия, что сделает ее глобальной функцией.
Имя функции – это фактическое имя функции. Имя функции и список параметров вместе составляют сигнатуру функции.
Аргументы – Аргумент похож на заполнитель. Когда вызывается функция, вы передаете значение аргументу. Это значение называется фактическим параметром или аргументом. Список параметров относится к типу, порядку и количеству аргументов метода. Аргументы необязательны; то есть метод может не содержать аргументов.
Тело функции – Тело метода содержит коллекцию операторов, которые определяют, что делает метод.
Return – в Lua можно вернуть несколько значений, следуя ключевому слову return с возвращаемыми значениями через запятую.
Необязательная область действия функции. Вы можете использовать ключевое слово local, чтобы ограничить область действия функции или игнорировать раздел области действия, что сделает ее глобальной функцией.
Имя функции – это фактическое имя функции. Имя функции и список параметров вместе составляют сигнатуру функции.
Аргументы – Аргумент похож на заполнитель. Когда вызывается функция, вы передаете значение аргументу. Это значение называется фактическим параметром или аргументом. Список параметров относится к типу, порядку и количеству аргументов метода. Аргументы необязательны; то есть метод может не содержать аргументов.
Тело функции – Тело метода содержит коллекцию операторов, которые определяют, что делает метод.
Return – в Lua можно вернуть несколько значений, следуя ключевому слову return с возвращаемыми значениями через запятую.
пример
Ниже приведен исходный код функции с именем max () . Эта функция принимает два параметра num1 и num2 и возвращает максимум между двумя –
Аргументы функции
Если функция должна использовать аргументы, она должна объявлять переменные, которые принимают значения аргументов. Эти переменные называются формальными параметрами функции.
Формальные параметры ведут себя как другие локальные переменные внутри функции и создаются при входе в функцию и уничтожаются при выходе.
Вызов функции
При создании функции Lua вы даете определение того, что должна делать функция. Чтобы использовать метод, вам нужно вызвать эту функцию для выполнения определенной задачи.
Когда программа вызывает функцию, управление программой передается вызываемой функции. Вызываемая функция выполняет определенную задачу, и когда выполняется оператор return или когда достигается конец ее функции, она возвращает управление программой обратно в основную программу.
Чтобы вызвать метод, вам просто нужно передать необходимые параметры вместе с именем метода, и если метод возвращает значение, вы можете сохранить возвращенное значение. Например –
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Назначение и передача функций
В Lua мы можем назначить функцию переменным, а также передать их в качестве параметров другой функции. Вот простой пример назначения и передачи функции в качестве параметра в Lua.
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Функция с переменным аргументом
В Lua можно создавать функции с переменными аргументами, используя «…» в качестве параметра. Мы можем понять это, увидев пример, в котором функция возвращает среднее значение и может принимать переменные аргументы.
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Луа – Струны
Строка – это последовательность символов, а также управляющие символы, такие как подача формы. Строка может быть инициализирована с тремя формами, которая включает в себя –
- Символы между одинарными кавычками
- Символы между двойными кавычками
- Символы между [[и]]
Пример вышеупомянутых трех форм показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Символы Escape-последовательности используются в строке для изменения обычной интерпретации символов. Например, чтобы напечатать двойные кавычки (“”), мы использовали \ “в приведенном выше примере. Экранирующая последовательность и ее использование перечислены ниже в таблице.
Последовательность побега | использование |
---|---|
\ а | колокол |
\ б | возврат на одну позицию |
\ е | Под.стр |
\ п | Новая линия |
\р | Возврат каретки |
\ т | табуляция |
\ v | Вертикальная вкладка |
\\ | бэкслэш |
\» | Двойные кавычки |
\» | Одинарные кавычки |
\ [ | Левая квадратная скобка |
\] | Правая квадратная скобка |
Манипуляция строк
Lua поддерживает строку для работы со строками –
string.upper (аргумент)
Возвращает заглавное представление аргумента.
string.lower (аргумент)
Возвращает строчное представление аргумента.
string.gsub (mainString, FindString, replaceString)
Возвращает строку путем замены вхождений findString на replaceString.
string.find (mainString, FindString,
optionalStartIndex, optionalEndIndex)
Возвращает начальный индекс и конечный индекс findString в основной строке и nil, если не найден.
string.reverse (Arg)
Возвращает строку путем обращения символов переданной строки.
Возвращает отформатированную строку.
string.char (arg) и string.byte (arg)
Возвращает внутренние числовые и символьные представления входного аргумента.
string.len (Arg)
Возвращает длину переданной строки.
string.rep (string, n))
Возвращает строку, повторяя одну и ту же строку n раз.
Таким образом, оператор объединяет две строки.
string.upper (аргумент)
Возвращает заглавное представление аргумента.
string.lower (аргумент)
Возвращает строчное представление аргумента.
string.gsub (mainString, FindString, replaceString)
Возвращает строку путем замены вхождений findString на replaceString.
string.find (mainString, FindString,
optionalStartIndex, optionalEndIndex)
Возвращает начальный индекс и конечный индекс findString в основной строке и nil, если не найден.
string.reverse (Arg)
Возвращает строку путем обращения символов переданной строки.
Возвращает отформатированную строку.
string.char (arg) и string.byte (arg)
Возвращает внутренние числовые и символьные представления входного аргумента.
string.len (Arg)
Возвращает длину переданной строки.
string.rep (string, n))
Возвращает строку, повторяя одну и ту же строку n раз.
Таким образом, оператор объединяет две строки.
Теперь давайте рассмотрим несколько примеров, чтобы точно увидеть, как ведут себя эти функции манипуляции со строками.
Манипуляция делами
Пример кода для управления строками в верхнем и нижнем регистре приведен ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Замена подстроки
Пример кода для замены вхождений одной строки другой приведен ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Нахождение и Реверс
Пример кода для поиска индекса подстроки и обратной строки приведен ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Форматирование строк
Много раз в нашем программировании нам может потребоваться печатать строки в отформатированном виде. Вы можете использовать функцию string.format для форматирования вывода, как показано ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Символьные и байтовые представления
Пример кода для символьного и байтового представления, который используется для преобразования строки из строки во внутреннее представление и наоборот.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Другие общие функции
Обычные манипуляции со строками включают в себя конкатенацию строк, определение длины строки и время от времени повторение одной и той же строки несколько раз. Пример для этих операций приведен ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Луа – Массивы
Массивы – это упорядоченное расположение объектов, которое может быть одномерным массивом, содержащим набор строк, или многомерным массивом, содержащим несколько строк и столбцов.
В Lua массивы реализованы с использованием таблиц индексации с целыми числами. Размер массива не фиксирован, и он может увеличиваться в зависимости от наших требований с учетом ограничений памяти.
Одномерный массив
Одномерный массив может быть представлен с использованием простой структуры таблицы и может быть инициализирован и считан с использованием простого цикла for . Пример показан ниже.
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Как видно из приведенного выше кода, когда мы пытаемся получить доступ к элементу в индексе, которого нет в массиве, он возвращает nil. В Lua индексация обычно начинается с индекса 1. Но возможно также создавать объекты с индексом 0 и ниже 0. Массив с использованием отрицательных индексов показан ниже, где мы инициализируем массив с помощью цикла for .
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Многомерный массив
Многомерные массивы могут быть реализованы двумя способами.
- Массив массивов
- Одномерный массив путем манипулирования индексами
Пример для многомерного массива 3. 3 показан ниже с использованием массива массивов.
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Пример многомерного массива показан ниже с использованием манипулирования индексами.
Когда мы запустим приведенный выше код, мы получим следующий вывод.
Как видно из приведенного выше примера, данные хранятся на основе индексов. Можно размещать элементы разреженным образом, и именно так работает реализация матрицы в Lua. Поскольку он не хранит нулевые значения в Lua, можно сэкономить много памяти без каких-либо специальных приемов в Lua по сравнению со специальными приемами, используемыми в других языках программирования.
Lua – Итераторы
Итератор – это конструкция, позволяющая перемещаться по элементам так называемой коллекции или контейнера. В Lua эти коллекции часто ссылаются на таблицы, которые используются для создания различных структур данных, таких как массив.
Универсальный для Итератора
Универсальный для итератора предоставляет пары ключ-значение каждого элемента в коллекции. Простой пример приведен ниже.
Когда мы запустим приведенный выше код, мы получим следующий вывод:
В приведенном выше примере используется итератор ipairs по умолчанию, предоставленный Lua.
В Lua мы используем функции для представления итераторов. Основываясь на поддержании состояния в этих функциях итератора, мы имеем два основных типа:
- Итераторы без состояния
- Stateful Iterators
Итераторы без состояния
По самому имени мы можем понять, что этот тип функции итератора не сохраняет никакого состояния.
Давайте теперь посмотрим на пример создания нашего собственного итератора, используя простую функцию, которая печатает квадраты n чисел.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Приведенный выше код может быть слегка изменен, чтобы имитировать работу ipairs функции итераторов. Это показано ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Stateful Iterators
Предыдущий пример итерации с использованием функции не сохраняет состояние. Каждый раз, когда вызывается функция, она возвращает следующий элемент коллекции на основе второй переменной, отправленной в функцию. Для хранения состояния текущего элемента используются замыкания. Закрытие сохраняет значения переменных через вызовы функций. Чтобы создать новое замыкание, мы создаем две функции, включая само замыкание и фабрику, функцию, которая создает замыкание.
Давайте теперь посмотрим на пример создания нашего собственного итератора, в котором мы будем использовать замыкания.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
В приведенном выше примере мы видим, что внутри elementIterator есть еще один метод, который использует индекс локальных внешних переменных и count для возврата каждого элемента в коллекции путем увеличения индекса каждый раз, когда вызывается функция.
Мы можем создавать свои собственные итераторы функций, используя замыкание, как показано выше, и оно может возвращать несколько элементов для каждого итерации цикла.
Луа – Столы
Вступление
Таблицы – единственная структура данных, доступная в Lua, которая помогает нам создавать различные типы, такие как массивы и словари. Lua использует ассоциативные массивы, которые можно индексировать не только числами, но и строками, кроме nil. Таблицы не имеют фиксированного размера и могут расти в зависимости от наших потребностей.
Lua использует таблицы во всех представлениях, включая представление пакетов. Когда мы обращаемся к методу string.format, это означает, что мы обращаемся к функции форматирования, доступной в пакете string.
Представление и использование
Таблицы называются объектами и не являются ни значениями, ни переменными. Lua использует выражение конструктора <> для создания пустой таблицы. Должно быть известно, что не существует фиксированной связи между переменной, которая содержит ссылку на таблицу, и самой таблицей.
Когда у нас есть таблица a с набором элементов и если мы присваиваем ее b , и a, и b ссылаются на одну и ту же память. Отдельная память не выделяется отдельно для b. Когда для a установлено значение nil, таблица все еще будет доступна для b. Когда нет ссылки на таблицу, сборщик мусора в Lua позаботится о том, чтобы очистить процесс, чтобы снова использовать эту нереференсную память.
Пример показан ниже для объяснения вышеупомянутых особенностей таблиц.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод:
Таблица Манипуляция
Есть встроенные функции для работы с таблицами, и они перечислены в следующей таблице.
table.concat (table [, sep [, i [, j]]])
Объединяет строки в таблицах на основе заданных параметров. Смотрите пример для деталей.
table.insert (таблица, [pos,] значение)
Вставляет значение в таблицу в указанной позиции.
table.maxn (таблица)
Возвращает самый большой числовой индекс.
table.remove (таблица [, pos])
Удаляет значение из таблицы.
table.sort (table [, comp])
Сортирует таблицу на основе необязательного аргумента компаратора.
table.concat (table [, sep [, i [, j]]])
Объединяет строки в таблицах на основе заданных параметров. Смотрите пример для деталей.
table.insert (таблица, [pos,] значение)
Вставляет значение в таблицу в указанной позиции.
table.maxn (таблица)
Возвращает самый большой числовой индекс.
table.remove (таблица [, pos])
Удаляет значение из таблицы.
table.sort (table [, comp])
Сортирует таблицу на основе необязательного аргумента компаратора.
Давайте посмотрим на некоторые примеры вышеуказанных функций.
Конкатенация таблиц
Мы можем использовать функцию concat для объединения двух таблиц, как показано ниже:
Когда мы запустим вышеуказанную программу, мы получим следующий вывод:
Вставить и удалить
Вставка и удаление элементов в таблицах наиболее распространена при манипулировании таблицами. Это объясняется ниже.
Когда мы запустим вышеупомянутую программу, мы получим следующий вывод –
Таблицы сортировки
Нам часто требуется сортировать таблицу в определенном порядке. Функции сортировки сортируют элементы в таблице по алфавиту. Пример для этого показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод:
Lua – модули
Что такое модуль?
Модуль похож на библиотеку, которая может быть загружена с помощью require и имеет одно глобальное имя, содержащее таблицу. Этот модуль может состоять из ряда функций и переменных. Все эти функции и переменные помещаются в таблицу, которая действует как пространство имен. Кроме того, модуль с хорошим поведением имеет необходимые условия для возврата этой таблицы по требованию.
Специальность модулей Lua
Использование таблиц в модулях помогает нам различными способами и позволяет нам манипулировать модулями так же, как мы манипулируем любой другой таблицей Lua. Благодаря возможности манипулировать модулями, он предоставляет дополнительные функции, для которых другим языкам нужны специальные механизмы. Благодаря этому бесплатному механизму модулей в Lua, пользователь может вызывать функции в Lua несколькими способами. Некоторые из них показаны ниже.
В приведенном выше примере кода вы можете увидеть, насколько гибким является программирование на Lua без какого-либо специального дополнительного кода.
Требуемая функция
Lua предоставила высокоуровневую функцию под названием require для загрузки всех необходимых модулей. Он поддерживается настолько простым, насколько это возможно, чтобы избежать слишком большой информации о модуле для его загрузки. Функция require принимает модули как кусок кода, который определяет некоторые значения, которые на самом деле являются функциями или таблицами, содержащими функции.
пример
Рассмотрим простой пример, где одна функция имеет математические функции. Давайте назовем этот модуль mymath.lua, а имя файла – mymath.lua. Содержание файла выглядит следующим образом –
Теперь, чтобы получить доступ к этому модулю Lua в другом файле, скажем, moduletutorial.lua, вам нужно использовать следующий сегмент кода.
Чтобы запустить этот код, нам нужно поместить два файла Lua в один и тот же каталог или, в качестве альтернативы, вы можете поместить файл модуля в путь к пакету, и он требует дополнительной настройки. Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
То, что нужно запомнить
Поместите оба модуля и файл, который вы запускаете, в один каталог.
Имя модуля и его имя файла должны совпадать.
Рекомендуется возвращать модули для функции require, и, следовательно, модуль должен быть предпочтительно реализован, как показано выше, даже если вы можете найти другие типы реализаций в другом месте.
Поместите оба модуля и файл, который вы запускаете, в один каталог.
Имя модуля и его имя файла должны совпадать.
Рекомендуется возвращать модули для функции require, и, следовательно, модуль должен быть предпочтительно реализован, как показано выше, даже если вы можете найти другие типы реализаций в другом месте.
Старый способ реализации модулей
Позвольте мне теперь переписать тот же пример более старым способом, который использует реализацию типа package.seeall. Это использовалось в Lua версий 5.1 и 5.0. Модуль mymath показан ниже.
Использование модулей в moduletutorial.lua показано ниже.
Когда мы запустим вышеупомянутое, мы получим тот же результат. Но рекомендуется использовать более старую версию кода, и предполагается, что она менее безопасна. Многие SDK, которые используют Lua для программирования, такие как Corona SDK, не рекомендовали использовать это.
Lua – Metatables
Метатабельная таблица – это таблица, которая помогает изменить поведение таблицы, к которой она присоединена, с помощью набора ключей и связанных мета-методов. Эти мета-методы являются мощной функциональностью Lua, которая включает такие функции, как –
Изменение / добавление функций к операторам на таблицах.
Поиск метатаблиц, когда ключ недоступен в таблице, с помощью __index в метатаблице.
Изменение / добавление функций к операторам на таблицах.
Поиск метатаблиц, когда ключ недоступен в таблице, с помощью __index в метатаблице.
Есть два важных метода, которые используются в обработке метатаблиц, которые включают в себя:
setmetatable (table, metatable) – этот метод используется для установки метатаблицы для таблицы.
getmetatable (table) – этот метод используется для получения метатаблицы таблицы.
setmetatable (table, metatable) – этот метод используется для установки метатаблицы для таблицы.
getmetatable (table) – этот метод используется для получения метатаблицы таблицы.
Давайте сначала посмотрим, как установить одну таблицу как метатабельную к другой. Это показано ниже.
Приведенный выше код может быть представлен в одной строке, как показано ниже.
_индекс
Простой пример метатаблицы для поиска мета-таблицы, когда она недоступна в таблице, показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Давайте объясним, что произошло в приведенном выше примере, по шагам.
Таблица mytable здесь .
Metatable устанавливается для mytable, который содержит функцию для __index, которую мы называем метаметодом.
Метаметод выполняет простую работу по поиску индекса «key2», если он найден, он возвращает «metatablevalue», в противном случае возвращает значение mytable для соответствующего индекса.
Таблица mytable здесь .
Metatable устанавливается для mytable, который содержит функцию для __index, которую мы называем метаметодом.
Метаметод выполняет простую работу по поиску индекса «key2», если он найден, он возвращает «metatablevalue», в противном случае возвращает значение mytable для соответствующего индекса.
У нас может быть упрощенная версия вышеуказанной программы, как показано ниже.
__newindex
Когда мы добавляем __newindex в metatable, если ключи не доступны в таблице, поведение новых ключей будет определяться мета-методами. Простой пример, когда индекс метатаблицы устанавливается, когда индекс не доступен в основной таблице, приведен ниже.
Когда вы запускаете вышеуказанную программу, вы получаете следующий вывод.
Вы можете видеть в приведенной выше программе, если ключ существует в основной таблице, он просто обновляет его. Когда ключ недоступен в maintable, он добавляет этот ключ в метатаблицу.
Другой пример, который обновляет ту же таблицу с помощью функции rawset, показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
rawset устанавливает значение без использования __newindex для metatable. Точно так же есть rawget, который получает значение без использования __index.
Добавление поведения оператора в таблицы
Простой пример объединения двух таблиц с помощью оператора + показан ниже –
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Ключ __add включен в metatable для добавления поведения оператора +. Таблица ключей и соответствующего оператора показана ниже.
__добавлять
Изменяет поведение оператора ‘+’.
Изменяет поведение оператора ‘-‘.
Изменяет поведение оператора ‘*’.
Изменяет поведение оператора ‘/’.
Изменяет поведение оператора “%”.
Изменяет поведение оператора ‘-‘.
Изменяет поведение оператора ‘..’.
Изменяет поведение оператора ‘==’.
Изменяет поведение оператора ‘<‘.
Изменяет поведение оператора ‘<=’.
__добавлять
Изменяет поведение оператора ‘+’.
Изменяет поведение оператора ‘-‘.
Изменяет поведение оператора ‘*’.
Изменяет поведение оператора ‘/’.
Изменяет поведение оператора “%”.
Изменяет поведение оператора ‘-‘.
Изменяет поведение оператора ‘..’.
Изменяет поведение оператора ‘==’.
Изменяет поведение оператора ‘<‘.
Изменяет поведение оператора ‘<=’.
__вызов
Добавление поведения вызова метода выполняется с помощью оператора __call. Простой пример, который возвращает сумму значений в основной таблице с переданной таблицей.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
__нанизывать
Чтобы изменить поведение оператора print, мы можем использовать метаметод __tostring. Простой пример показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Если вы полностью знакомы с возможностями мета-таблицы, вы действительно можете выполнить множество операций, которые были бы очень сложными без ее использования. Поэтому постарайтесь больше работать над использованием метатаблиц с различными опциями, доступными в мета таблицах, как описано в примерах, а также создавайте свои собственные образцы.
Луа – сопрограммы
Вступление
Сопрограммы по своей природе являются совместными, что позволяет двум или более методам выполняться контролируемым образом. С сопрограммами в любой момент времени выполняется только одна сопрограмма, и эта запущенная сопрограмма только приостанавливает свое выполнение, когда она явно запрашивает приостановку.
Приведенное выше определение может выглядеть расплывчато. Предположим, у нас есть два метода, один из которых является основным методом программы и сопрограммой. Когда мы вызываем сопрограмму с помощью функции resume, она начинает выполняться, а когда мы вызываем функцию yield, она приостанавливает выполнение. Снова та же самая сопрограмма может продолжить выполнение с другим вызовом функции возобновления, с которого это было приостановлено. Этот процесс может продолжаться до конца выполнения сопрограммы.
Функции, доступные в сопрограммах
В следующей таблице перечислены все доступные функции для сопрограмм в Lua и их соответствующее использование.
coroutine.create (f)
Создает новую сопрограмму с функцией f и возвращает объект типа «поток».
coroutine.resume (co [, val1, …])
Возобновляет сопрограмму co и передает параметры, если таковые имеются. Возвращает статус операции и необязательные другие возвращаемые значения.
coroutine.running ()
Возвращает запущенную сопрограмму или ноль, если вызывается в основном потоке.
coroutine.status (со)
Возвращает одно из значений: запущено, нормально, приостановлено или не работает в зависимости от состояния сопрограммы.
coroutine.wrap (f)
Как и coroutine.create, функция coroutine.wrap также создает сопрограмму, но вместо возврата самой сопрограммы она возвращает функцию, которая при вызове возобновляет сопрограмму.
coroutine.yield (…)
Приостанавливает запущенную сопрограмму. Параметр, передаваемый этому методу, действует как дополнительные возвращаемые значения функции возобновления.
coroutine.create (f)
Создает новую сопрограмму с функцией f и возвращает объект типа «поток».
coroutine.resume (co [, val1, …])
Возобновляет сопрограмму co и передает параметры, если таковые имеются. Возвращает статус операции и необязательные другие возвращаемые значения.
coroutine.running ()
Возвращает запущенную сопрограмму или ноль, если вызывается в основном потоке.
coroutine.status (со)
Возвращает одно из значений: запущено, нормально, приостановлено или не работает в зависимости от состояния сопрограммы.
coroutine.wrap (f)
Как и coroutine.create, функция coroutine.wrap также создает сопрограмму, но вместо возврата самой сопрограммы она возвращает функцию, которая при вызове возобновляет сопрограмму.
coroutine.yield (…)
Приостанавливает запущенную сопрограмму. Параметр, передаваемый этому методу, действует как дополнительные возвращаемые значения функции возобновления.
пример
Давайте посмотрим на пример, чтобы понять концепцию сопрограмм.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Что делает приведенный выше пример?
Как упоминалось ранее, мы используем функцию возобновления, чтобы запустить операцию, и функцию yield, чтобы остановить операцию. Кроме того, вы можете видеть, что есть несколько возвращаемых значений, полученных функцией возобновления сопрограммы.
Сначала мы создаем сопрограмму и присваиваем ей имя переменной co, и сопрограмма принимает в качестве параметров две переменные.
Когда мы вызываем первую функцию возобновления, значения 3 и 2 сохраняются во временных переменных value1 и value2 до конца сопрограммы.
Чтобы вы поняли это, мы использовали tempvar3, который изначально равен 10, и он обновляется до 13 и 16 последующими вызовами сопрограмм, поскольку значение1 сохраняется как 3 на протяжении всего выполнения сопрограммы.
Первый файл coroutine.yield возвращает два значения 4 и 3 в функцию возобновления, которую мы получаем, обновляя входные параметры 3 и 2 в операторе yield. Он также получает истинный / ложный статус выполнения сопрограммы.
Еще одна вещь, связанная с сопрограммами, заключается в том, как обрабатываются следующие параметры вызова возобновления в приведенном выше примере; Вы можете видеть, что переменная coroutine.yield получает параметры следующего вызова, что обеспечивает мощный способ выполнения новой операции с сохранением существующих значений параметров.
Наконец, как только все операторы в сопрограммах будут выполнены, последующие вызовы вернутся в false и оператор «не может возобновить мертвую сопрограмму» в качестве ответа.
Сначала мы создаем сопрограмму и присваиваем ей имя переменной co, и сопрограмма принимает в качестве параметров две переменные.
Когда мы вызываем первую функцию возобновления, значения 3 и 2 сохраняются во временных переменных value1 и value2 до конца сопрограммы.
Чтобы вы поняли это, мы использовали tempvar3, который изначально равен 10, и он обновляется до 13 и 16 последующими вызовами сопрограмм, поскольку значение1 сохраняется как 3 на протяжении всего выполнения сопрограммы.
Первый файл coroutine.yield возвращает два значения 4 и 3 в функцию возобновления, которую мы получаем, обновляя входные параметры 3 и 2 в операторе yield. Он также получает истинный / ложный статус выполнения сопрограммы.
Еще одна вещь, связанная с сопрограммами, заключается в том, как обрабатываются следующие параметры вызова возобновления в приведенном выше примере; Вы можете видеть, что переменная coroutine.yield получает параметры следующего вызова, что обеспечивает мощный способ выполнения новой операции с сохранением существующих значений параметров.
Наконец, как только все операторы в сопрограммах будут выполнены, последующие вызовы вернутся в false и оператор «не может возобновить мертвую сопрограмму» в качестве ответа.
Другой пример сопрограммы
Давайте посмотрим на простую сопрограмму, которая возвращает число от 1 до 5 с помощью функции yield и функции resume. Он создает сопрограмму, если она недоступна, или возобновляет существующую сопрограмму.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Часто происходит сравнение сопрограмм с потоками языков мультипрограммирования, но мы должны понимать, что сопрограммы имеют схожие свойства потоков, но они выполняются только по одному за раз и никогда не выполняются одновременно.
Мы контролируем последовательность выполнения программы для удовлетворения потребностей, обеспечивая временное хранение определенной информации. Использование глобальных переменных с сопрограммами обеспечивает еще большую гибкость сопрограмм.
Lua – File I / O
Библиотека ввода / вывода используется для чтения и управления файлами в Lua. В Lua существует два вида файловых операций, а именно неявные файловые дескрипторы и явные файловые дескрипторы.
Для следующих примеров мы будем использовать пример файла test.lua, как показано ниже.
Простая операция открытия файла использует следующее утверждение.
Различные режимы файлов перечислены в следующей таблице.
Режим только для чтения. Это режим по умолчанию, в котором открывается существующий файл.
Режим записи включен, который перезаписывает существующий файл или создает новый файл.
Режим добавления, который открывает существующий файл или создает новый файл для добавления.
Режим чтения и записи для существующего файла.
Все существующие данные удаляются, если файл существует или создается новый файл с разрешениями на чтение и запись.
Режим добавления с включенным режимом чтения, который открывает существующий файл или создает новый файл.
Режим только для чтения. Это режим по умолчанию, в котором открывается существующий файл.
Режим записи включен, который перезаписывает существующий файл или создает новый файл.
Режим добавления, который открывает существующий файл или создает новый файл для добавления.
Режим чтения и записи для существующего файла.
Все существующие данные удаляются, если файл существует или создается новый файл с разрешениями на чтение и запись.
Режим добавления с включенным режимом чтения, который открывает существующий файл или создает новый файл.
Неявные файловые дескрипторы
Неявные файловые дескрипторы используют стандартные режимы ввода / вывода или используют один входной и один выходной файл. Пример использования неявных файловых дескрипторов показан ниже.
Когда вы запустите программу, вы получите вывод первой строки файла test.lua. Для нашей программы мы получили следующий вывод.
Это была первая строка утверждения в файле test.lua для нас. Также строка “- Конец файла test.lua” будет добавлена к последней строке кода test.lua.
В приведенном выше примере вы можете увидеть, как неявные дескрипторы работают с файловой системой, используя методы io. “X”. В приведенном выше примере используется io.read () без необязательного параметра. Необязательный параметр может быть любым из следующих.
Читает из текущей позиции файла и возвращает число, если существует в позиции файла или возвращает ноль.
Возвращает все содержимое файла из текущей позиции файла.
Читает строку из текущей позиции файла и перемещает позицию файла на следующую строку.
Читает количество байтов, указанных в функции.
Читает из текущей позиции файла и возвращает число, если существует в позиции файла или возвращает ноль.
Возвращает все содержимое файла из текущей позиции файла.
Читает строку из текущей позиции файла и перемещает позицию файла на следующую строку.
Читает количество байтов, указанных в функции.
Другие распространенные методы ввода / вывода включают в себя:
io.tmpfile () – возвращает временный файл для чтения и записи, который будет удален после завершения работы программы.
io.type (file) – возвращает ли файл, закрытый файл или ноль на основе входного файла.
io.flush () – очищает выходной буфер по умолчанию.
io.lines (необязательное имя файла) – предоставляет универсальный итератор цикла, который циклически просматривает файл и закрывает файл в конце, если указано имя файла или файл по умолчанию используется и не закрывается в конце цикла ,
io.tmpfile () – возвращает временный файл для чтения и записи, который будет удален после завершения работы программы.
io.type (file) – возвращает ли файл, закрытый файл или ноль на основе входного файла.
io.flush () – очищает выходной буфер по умолчанию.
io.lines (необязательное имя файла) – предоставляет универсальный итератор цикла, который циклически просматривает файл и закрывает файл в конце, если указано имя файла или файл по умолчанию используется и не закрывается в конце цикла ,
Явные файловые дескрипторы
Мы часто используем явный файловый дескриптор, который позволяет нам манипулировать несколькими файлами одновременно. Эти функции очень похожи на неявные файловые дескрипторы. Здесь мы используем file: function_name вместо io.function_name. Следующий пример версии файла того же самого примера неявных файловых дескрипторов показан ниже.
Когда вы запустите программу, вы получите вывод, аналогичный примеру неявных дескрипторов.
Все режимы открытия файлов и параметров для чтения для внешних дескрипторов такие же, как и для неявных файловых дескрипторов.
Другие распространенные файловые методы включают в себя:
file: seek (необязательный fromce, необязательное смещение) – параметр Fromce имеет значение «set», «cur» или «end». Устанавливает новый указатель файла с обновленной позицией файла от начала файла. Смещения в этой функции начинаются с нуля. Смещение измеряется от начала файла, если первый аргумент «установлен»; из текущей позиции в файле, если это “cur”; или из конца файла, если это «конец». Значения аргумента по умолчанию – «cur» и 0, поэтому текущую позицию файла можно получить, вызвав эту функцию без аргументов.
file: flush () – очищает выходной буфер по умолчанию.
io.lines (необязательное имя файла) – предоставляет универсальный итератор цикла, который циклически просматривает файл и закрывает файл в конце, если указано имя файла или файл по умолчанию используется и не закрывается в конце цикла ,
file: seek (необязательный fromce, необязательное смещение) – параметр Fromce имеет значение «set», «cur» или «end». Устанавливает новый указатель файла с обновленной позицией файла от начала файла. Смещения в этой функции начинаются с нуля. Смещение измеряется от начала файла, если первый аргумент «установлен»; из текущей позиции в файле, если это “cur”; или из конца файла, если это «конец». Значения аргумента по умолчанию – «cur» и 0, поэтому текущую позицию файла можно получить, вызвав эту функцию без аргументов.
file: flush () – очищает выходной буфер по умолчанию.
io.lines (необязательное имя файла) – предоставляет универсальный итератор цикла, который циклически просматривает файл и закрывает файл в конце, если указано имя файла или файл по умолчанию используется и не закрывается в конце цикла ,
Пример использования метода поиска показан ниже. Он смещает курсор от 25 позиций до конца файла. Функция чтения печатает остаток файла с позиции поиска.
Вы получите вывод, похожий на следующий.
Вы можете поэкспериментировать со всеми различными режимами и параметрами, чтобы узнать все возможности операций с файлами Lua.
Lua – Обработка ошибок
Необходимость обработки ошибок
Обработка ошибок очень важна, поскольку реальные операции часто требуют использования сложных операций, которые включают файловые операции, транзакции базы данных и вызовы веб-служб.
В любом программировании всегда есть требование для обработки ошибок. Ошибки могут быть двух типов, которые включают в себя,
- Синтаксические ошибки
- Ошибки во время выполнения
Синтаксические ошибки
Синтаксические ошибки возникают из-за неправильного использования различных компонентов программы, таких как операторы и выражения. Простой пример синтаксической ошибки показан ниже.
Как вы знаете, существует разница между использованием одного «равно» и двойного «равно». Использование одного вместо другого может привести к ошибке. Одно «равно» относится к присвоению, а двойное «равно» относится к сравнению. Точно так же у нас есть выражения и функции, имеющие предопределенные способы реализации.
Другой пример синтаксической ошибки показан ниже –
Когда мы запустим вышеупомянутую программу, мы получим следующий вывод –
Синтаксические ошибки гораздо легче обрабатывать, чем ошибки времени выполнения, поскольку интерпретатор Lua обнаруживает ошибку более четко, чем в случае ошибки времени выполнения. Из вышеприведенной ошибки мы можем легко узнать, что добавление оператора do перед оператором print требуется согласно структуре Lua.
Ошибки времени выполнения
В случае ошибок во время выполнения, программа выполняется успешно, но это может привести к ошибкам во время выполнения из-за ошибок во входных или неправильно обработанных функциях. Простой пример отображения ошибки времени выполнения показан ниже.
Когда мы соберем программу, она будет успешно собрана и запущена. Как только он запускается, показывает ошибку времени выполнения.
Это ошибка времени выполнения, которая произошла из-за отсутствия передачи двух переменных. Ожидается параметр b, и здесь он равен нулю и выдает ошибку.
Функции подтверждения и ошибки
Для обработки ошибок мы часто используем две функции – assert и error . Простой пример показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод об ошибке.
Ошибка (сообщение [, уровень]) завершает последнюю вызванную защищенную функцию и возвращает сообщение как сообщение об ошибке. Эта ошибка функции никогда не возвращается. Обычно ошибка добавляет некоторую информацию о позиции ошибки в начале сообщения. Аргумент уровня указывает, как получить позицию ошибки. На уровне 1 (по умолчанию) позиция ошибки – это то место, где была вызвана функция ошибки. Уровень 2 указывает на ошибку, где была вызвана функция, которая вызвала ошибку; и так далее. Пропуск уровня 0 позволяет избежать добавления информации о позиции ошибки в сообщение.
pcall и xpcall
В программировании на Lua, чтобы избежать появления этих ошибок и обработки ошибок, нам нужно использовать функции pcall или xpcall.
Функция pcall (f, arg1, …) вызывает запрошенную функцию в защищенном режиме. Если какая-то ошибка возникает в функции f, она не выдает ошибку. Он просто возвращает статус ошибки. Простой пример использования pcall показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Функция xpcall (f, err) вызывает запрошенную функцию, а также устанавливает обработчик ошибок. Любая ошибка внутри f не распространяется; вместо этого xpcall перехватывает ошибку, вызывает функцию err с исходным объектом ошибки и возвращает код состояния.
Простой пример для xpcall показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Как программист, очень важно, чтобы вы позаботились о правильной обработке ошибок в программах, которые вы пишете. Использование обработки ошибок может гарантировать, что неожиданные условия за пределами граничных условий будут обрабатываться без вмешательства пользователя программы.
Lua – отладка
Lua предоставляет библиотеку отладки, которая предоставляет нам все примитивные функции для создания нашего собственного отладчика. Хотя встроенного отладчика Lua нет, у нас есть много отладчиков для Lua, созданных различными разработчиками, многие из которых являются открытыми.
Функции, доступные в библиотеке отладки Lua, перечислены в следующей таблице вместе с их использованием.
Переходит в интерактивный режим отладки, который остается активным до тех пор, пока мы не введем только строку в строке и не нажмем клавишу ввода Пользователь может проверять переменные в этом режиме, используя другие функции.
getfenv (объект)
Возвращает среду объекта.
gethook (необязательная тема)
Возвращает текущие настройки ловушек потока в виде трех значений – текущей функции ловушек, текущей маски ловушек и текущего счетчика ловушек.
getinfo (необязательный поток, функция или уровень стека, необязательный флаг)
Возвращает таблицу с информацией о функции. Вы можете передать функцию напрямую или указать число в качестве значения функции, что означает, что функция выполняется на уровне функции стека вызовов данного потока – уровень 0 является текущей функцией (сама getinfo); уровень 1 – это функция, которая вызвала getinfo; и так далее. Если функция на число больше, чем количество активных функций, getinfo возвращает nil.
getlocal (необязательный поток, уровень стека, локальный индекс)
Возвращает имя и значение локальной переменной с индексом local функции на уровне стека. Возвращает nil, если локальная переменная с указанным индексом отсутствует, и выдает ошибку при вызове с уровнем вне диапазона.
GetMetaTable (значение)
Возвращает метатабельность данного объекта или ноль, если у него нет метатаблицы.
getregistry ()
Возвращает таблицу реестра, предопределенную таблицу, которая может использоваться любым кодом C для хранения любого значения Lua, которое необходимо сохранить.
getupvalue (функция, индекс upvalue)
Эта функция возвращает имя и значение upvalue с индексом вверх функции func. Функция возвращает nil, если нет никакого значения с данным индексом.
setfenv (функция или поток или пользовательские данные, таблица окружения)
Устанавливает среду данного объекта в данную таблицу. Возвращает объект.
sethook (необязательный поток, функция ловушки, строка маски крюка с “c” и / или “r” и / или “l”, необязательный счетчик команд)
Устанавливает данную функцию как хук. Строковая маска и счетчик чисел описывают, когда будет вызываться ловушка. Здесь c, r и l вызываются каждый раз, когда Lua вызывает, возвращает и вводит каждую строку кода в функцию соответственно.
setlocal (необязательный поток, уровень стека, локальный индекс, значение)
Назначает значение локальной переменной с индексом local функции на уровне стека. Функция возвращает nil, если нет локальной переменной с данным индексом, и выдает ошибку при вызове с уровнем вне диапазона. В противном случае он возвращает имя локальной переменной.
setmetatable (значение, метатабельный)
Устанавливает метатабельность для данного объекта в данной таблице (которая может быть ноль).
setupvalue (функция, индекс upvalue, значение)
Эта функция присваивает значение повышающему значению с индексом вверх функции func. Функция возвращает nil, если нет никакого значения с данным индексом. В противном случае он возвращает имя upvalue.
traceback (необязательный поток, необязательная строка сообщения, необязательный аргумент уровня)
Создает расширенное сообщение об ошибке с трассировкой.
Переходит в интерактивный режим отладки, который остается активным до тех пор, пока мы не введем только строку в строке и не нажмем клавишу ввода Пользователь может проверять переменные в этом режиме, используя другие функции.
getfenv (объект)
Возвращает среду объекта.
gethook (необязательная тема)
Возвращает текущие настройки ловушек потока в виде трех значений – текущей функции ловушек, текущей маски ловушек и текущего счетчика ловушек.
getinfo (необязательный поток, функция или уровень стека, необязательный флаг)
Возвращает таблицу с информацией о функции. Вы можете передать функцию напрямую или указать число в качестве значения функции, что означает, что функция выполняется на уровне функции стека вызовов данного потока – уровень 0 является текущей функцией (сама getinfo); уровень 1 – это функция, которая вызвала getinfo; и так далее. Если функция на число больше, чем количество активных функций, getinfo возвращает nil.
getlocal (необязательный поток, уровень стека, локальный индекс)
Возвращает имя и значение локальной переменной с индексом local функции на уровне стека. Возвращает nil, если локальная переменная с указанным индексом отсутствует, и выдает ошибку при вызове с уровнем вне диапазона.
GetMetaTable (значение)
Возвращает метатабельность данного объекта или ноль, если у него нет метатаблицы.
getregistry ()
Возвращает таблицу реестра, предопределенную таблицу, которая может использоваться любым кодом C для хранения любого значения Lua, которое необходимо сохранить.
getupvalue (функция, индекс upvalue)
Эта функция возвращает имя и значение upvalue с индексом вверх функции func. Функция возвращает nil, если нет никакого значения с данным индексом.
setfenv (функция или поток или пользовательские данные, таблица окружения)
Устанавливает среду данного объекта в данную таблицу. Возвращает объект.
sethook (необязательный поток, функция ловушки, строка маски крюка с “c” и / или “r” и / или “l”, необязательный счетчик команд)
Устанавливает данную функцию как хук. Строковая маска и счетчик чисел описывают, когда будет вызываться ловушка. Здесь c, r и l вызываются каждый раз, когда Lua вызывает, возвращает и вводит каждую строку кода в функцию соответственно.
setlocal (необязательный поток, уровень стека, локальный индекс, значение)
Назначает значение локальной переменной с индексом local функции на уровне стека. Функция возвращает nil, если нет локальной переменной с данным индексом, и выдает ошибку при вызове с уровнем вне диапазона. В противном случае он возвращает имя локальной переменной.
setmetatable (значение, метатабельный)
Устанавливает метатабельность для данного объекта в данной таблице (которая может быть ноль).
setupvalue (функция, индекс upvalue, значение)
Эта функция присваивает значение повышающему значению с индексом вверх функции func. Функция возвращает nil, если нет никакого значения с данным индексом. В противном случае он возвращает имя upvalue.
traceback (необязательный поток, необязательная строка сообщения, необязательный аргумент уровня)
Создает расширенное сообщение об ошибке с трассировкой.
Приведенный выше список является полным списком функций отладки в Lua, и мы часто используем библиотеку, которая использует вышеуказанные функции и обеспечивает более простую отладку. Использование этих функций и создание нашего собственного отладчика довольно сложно и не является предпочтительным. В любом случае, мы увидим пример простого использования функций отладки.
Когда мы запустим вышеуказанную программу, мы получим трассировку стека, как показано ниже.
В приведенном выше примере программы трассировка стека печатается с использованием функции debug.trace, доступной в библиотеке отладки. Debug.getinfo получает текущую таблицу функции.
Отладка – Пример
Нам часто нужно знать локальные переменные функции для отладки. Для этой цели мы можем использовать getupvalue, а для установки этих локальных переменных мы используем setupvalue. Простой пример для этого показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
В этом примере счетчик обновляется по одному при каждом вызове. Мы можем видеть текущее состояние локальной переменной, используя функцию getupvalue. Затем мы устанавливаем локальную переменную в новое значение. Здесь n равно 2 до вызова операции set. Используя функцию setupvalue, она обновляется до 10. Теперь, когда мы вызываем функцию счетчика, она возвращает 11 вместо 3.
Типы отладки
- Отладка командной строки
- Графическая отладка
Отладка командной строки
Отладка командной строки – это тип отладки, который использует командную строку для отладки с помощью команд и операторов печати. Для Lua доступно множество отладчиков командной строки, некоторые из которых перечислены ниже.
RemDebug – RemDebug является удаленным отладчиком для Lua 5.0 и 5.1. Это позволяет удаленно контролировать выполнение другой программы Lua, устанавливать точки останова и проверять текущее состояние программы. RemDebug также может отлаживать сценарии CGILua.
clidebugger – простой отладчик интерфейса командной строки для Lua 5.1, написанный на чистом Lua. Он не зависит ни от чего, кроме стандартных библиотек Lua 5.1. Он был вдохновлен RemDebug, но не имеет своих удаленных средств.
ctrace – инструмент для отслеживания вызовов Lua API.
xdbLua – простой отладчик командной строки Lua для платформы Windows.
LuaInterface – Debugger – Этот проект является расширением отладчика для LuaInterface. Это поднимает встроенный интерфейс отладки Lua на более высокий уровень. Взаимодействие с отладчиком осуществляется посредством событий и вызовов методов.
Rldb – это удаленный отладчик Lua через сокет, доступный как в Windows, так и в Linux. Это может дать вам гораздо больше возможностей, чем любой существующий.
ModDebug – позволяет удаленно контролировать выполнение другой программы Lua, устанавливать точки останова и проверять текущее состояние программы.
RemDebug – RemDebug является удаленным отладчиком для Lua 5.0 и 5.1. Это позволяет удаленно контролировать выполнение другой программы Lua, устанавливать точки останова и проверять текущее состояние программы. RemDebug также может отлаживать сценарии CGILua.
clidebugger – простой отладчик интерфейса командной строки для Lua 5.1, написанный на чистом Lua. Он не зависит ни от чего, кроме стандартных библиотек Lua 5.1. Он был вдохновлен RemDebug, но не имеет своих удаленных средств.
ctrace – инструмент для отслеживания вызовов Lua API.
xdbLua – простой отладчик командной строки Lua для платформы Windows.
LuaInterface – Debugger – Этот проект является расширением отладчика для LuaInterface. Это поднимает встроенный интерфейс отладки Lua на более высокий уровень. Взаимодействие с отладчиком осуществляется посредством событий и вызовов методов.
Rldb – это удаленный отладчик Lua через сокет, доступный как в Windows, так и в Linux. Это может дать вам гораздо больше возможностей, чем любой существующий.
ModDebug – позволяет удаленно контролировать выполнение другой программы Lua, устанавливать точки останова и проверять текущее состояние программы.
Графическая отладка
Графическая отладка доступна с помощью IDE, где вам предоставляется визуальная отладка различных состояний, таких как значения переменных, трассировка стека и другая связанная информация. Существует визуальное представление и пошаговое управление выполнением с помощью точек останова, перехода, перехода и других кнопок в IDE.
Существует несколько графических отладчиков для Lua, и это включает следующее.
SciTE – стандартная Windows IDE для Lua предоставляет несколько средств отладки, таких как точки останова, шаг, шаг, шаг, просмотр переменных и так далее.
Decoda – это графический отладчик с поддержкой удаленной отладки.
ZeroBrane Studio – Lua IDE со встроенным удаленным отладчиком, просмотром стека, просмотром часов, удаленной консолью, статическим анализатором и многим другим. Работает с LuaJIT, Love2d, Moai и другими двигателями Lua; Windows, OSX и Linux. Открытый исходный код.
akdebugger – Отладчик и редактор Lua для Eclipse.
luaedit – Это включает в себя удаленную отладку, локальную отладку, подсветку синтаксиса, список предложений завершения, механизм предложения параметров, предварительное управление точками останова (включая систему условий на точках останова и числе обращений), список функций, список глобальных и локальных переменных, наблюдения, управление, ориентированное на решение.
SciTE – стандартная Windows IDE для Lua предоставляет несколько средств отладки, таких как точки останова, шаг, шаг, шаг, просмотр переменных и так далее.
Decoda – это графический отладчик с поддержкой удаленной отладки.
ZeroBrane Studio – Lua IDE со встроенным удаленным отладчиком, просмотром стека, просмотром часов, удаленной консолью, статическим анализатором и многим другим. Работает с LuaJIT, Love2d, Moai и другими двигателями Lua; Windows, OSX и Linux. Открытый исходный код.
akdebugger – Отладчик и редактор Lua для Eclipse.
luaedit – Это включает в себя удаленную отладку, локальную отладку, подсветку синтаксиса, список предложений завершения, механизм предложения параметров, предварительное управление точками останова (включая систему условий на точках останова и числе обращений), список функций, список глобальных и локальных переменных, наблюдения, управление, ориентированное на решение.
Луа – Сборка мусора
Lua использует автоматическое управление памятью, которое использует сборку мусора на основе определенных алгоритмов, встроенных в Lua. В результате автоматического управления памятью, как разработчик –
- Не нужно беспокоиться о выделении памяти для объектов.
- Нет необходимости освобождать их, когда они больше не нужны, за исключением установки на ноль.
Lua использует сборщик мусора, который запускается время от времени для сбора мертвых объектов, когда они больше не доступны из программы Lua.
Все объекты, включая таблицы, пользовательские данные, функции, потоки, строки и т. Д., Подлежат автоматическому управлению памятью. Lua использует инкрементный сборщик меток и очистки, который использует два числа для управления циклами сборки мусора, а именно паузу сборщика мусора и множитель шага сборщика мусора . Эти значения в процентах, а значение 100 часто равно 1 внутри.
Сборщик мусора Пауза
Пауза сборщика мусора используется для контроля того, как долго должен ждать сборщик мусора; он снова вызывается автоматическим управлением памятью Lua. Значения меньше 100 означают, что Lua не будет ждать следующего цикла. Аналогично, более высокие значения этого значения приведут к тому, что сборщик мусора будет медленным и менее агрессивным по своей природе. Значение 200 означает, что сборщик ожидает удвоения общего объема используемой памяти, прежде чем начинать новый цикл. Следовательно, в зависимости от характера и скорости приложения может потребоваться изменить это значение, чтобы получить лучшую производительность в приложениях Lua.
Множитель шага сборщика мусора
Этот множитель шага управляет относительной скоростью сборщика мусора и скоростью выделения памяти в программе Lua. Большие значения шага приведут к тому, что сборщик мусора станет более агрессивным, а также увеличит размер шага каждого добавочного шага сборки мусора. Значения меньше 100 часто могут привести к тому, что сборщик мусора не завершит свой цикл, и это обычно не является предпочтительным. Значение по умолчанию равно 200, что означает, что сборщик мусора работает в два раза быстрее, чем скорость выделения памяти.
Функции сборщика мусора
Как разработчики, у нас есть некоторый контроль над автоматическим управлением памятью в Lua. Для этого у нас есть следующие методы.
collectgarbage («собирать») – запускает один полный цикл сборки мусора.
collectgarbage (“count”) – Возвращает объем памяти, используемой в настоящее время программой в килобайтах.
collectgarbage («restart») – Если сборщик мусора был остановлен, он перезапускает его.
collectgarbage (“setpause”) – Устанавливает значение, заданное в качестве второго параметра, деленное на 100 для переменной паузы сборщика мусора. Его использование – как обсуждено немного выше.
collectgarbage (“setstepmul”) – Устанавливает значение, заданное в качестве второго параметра, деленное на 100 для переменной множителя шага мусора. Его использование – как обсуждено немного выше.
collectgarbage («шаг») – Запускает один шаг сборки мусора. Чем больше второй аргумент, тем больше будет этот шаг. Параметр collectgarbage будет возвращать значение true, если запущенный шаг был последним этапом цикла сбора мусора.
collectgarbage («стоп») – останавливает сборщик мусора, если он работает.
collectgarbage («собирать») – запускает один полный цикл сборки мусора.
collectgarbage (“count”) – Возвращает объем памяти, используемой в настоящее время программой в килобайтах.
collectgarbage («restart») – Если сборщик мусора был остановлен, он перезапускает его.
collectgarbage (“setpause”) – Устанавливает значение, заданное в качестве второго параметра, деленное на 100 для переменной паузы сборщика мусора. Его использование – как обсуждено немного выше.
collectgarbage (“setstepmul”) – Устанавливает значение, заданное в качестве второго параметра, деленное на 100 для переменной множителя шага мусора. Его использование – как обсуждено немного выше.
collectgarbage («шаг») – Запускает один шаг сборки мусора. Чем больше второй аргумент, тем больше будет этот шаг. Параметр collectgarbage будет возвращать значение true, если запущенный шаг был последним этапом цикла сбора мусора.
collectgarbage («стоп») – останавливает сборщик мусора, если он работает.
Простой пример с использованием примера сборщика мусора показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод. Обратите внимание, что этот результат зависит от типа операционной системы, а также от функции автоматического управления памятью в Lua.
Вы можете видеть в приведенной выше программе, когда сборка мусора завершена, она уменьшает используемую память. Но это не обязательно называть это. Даже если мы не вызовем их, он будет выполнен автоматически на более позднем этапе интерпретатором Lua после предварительно определенного периода.
Очевидно, что мы можем изменить поведение сборщика мусора, используя эти функции, если это необходимо. Эти функции предоставляют разработчику немного дополнительных возможностей для решения сложных ситуаций. В зависимости от типа памяти, необходимого для программы, вы можете или не можете использовать эту функцию. Но очень полезно знать использование памяти в приложениях и проверять ее во время самого программирования, чтобы избежать нежелательных результатов после развертывания.
Lua – объектно-ориентированный
Введение в ООП
Объектно-ориентированное программирование (ООП) – это один из наиболее часто используемых методов программирования, который используется в современную эпоху программирования. Существует ряд языков программирования, которые поддерживают ООП, включая:
- C ++
- Джава
- Objective-C
- Болтовня
- C #
- Рубин
Особенности ООП
Класс – класс – это расширяемый шаблон для создания объектов, предоставляющий начальные значения для состояния (переменные-члены) и реализации поведения.
Объекты – это экземпляр класса, для которого выделена отдельная память.
Наследование – это понятие, посредством которого переменные и функции одного класса наследуются другим классом.
Инкапсуляция – это процесс объединения данных и функций внутри класса. Данные могут быть доступны вне класса с помощью функций. Это также известно как абстракция данных.
Класс – класс – это расширяемый шаблон для создания объектов, предоставляющий начальные значения для состояния (переменные-члены) и реализации поведения.
Объекты – это экземпляр класса, для которого выделена отдельная память.
Наследование – это понятие, посредством которого переменные и функции одного класса наследуются другим классом.
Инкапсуляция – это процесс объединения данных и функций внутри класса. Данные могут быть доступны вне класса с помощью функций. Это также известно как абстракция данных.
ООП в Луа
Вы можете реализовать ориентацию объекта в Lua с помощью таблиц и первоклассных функций Lua. Помещая функции и связанные данные в таблицу, формируется объект. Наследование может быть реализовано с помощью метатаблиц, обеспечивающих механизм поиска несуществующих функций (методов) и полей в родительском объекте (ах).
Таблицы в Lua имеют свойства объекта, такие как состояние и идентичность, которые не зависят от его значений. Два объекта (таблицы) с одинаковым значением являются разными объектами, тогда как объект может иметь разные значения в разное время, но это всегда один и тот же объект. Как и у объектов, таблицы имеют жизненный цикл, который не зависит от того, кто их создал или где они были созданы.
Пример из реального мира
Концепция объектной ориентации широко используется, но вам необходимо четко понимать ее для правильной и максимальной выгоды.
Давайте рассмотрим простой математический пример. Мы часто сталкиваемся с ситуациями, когда работаем с разными формами, такими как круг, прямоугольник и квадрат.
Формы могут иметь общее свойство Area. Таким образом, мы можем расширить другие фигуры из формы базового объекта с помощью общей области свойств. Каждая из фигур может иметь свои собственные свойства и функции, например, прямоугольник может иметь свойства length, width, area в качестве своих свойств, а printArea и defineArea в качестве своих функций.
Создание простого класса
Простая реализация класса для прямоугольника с тремя свойствами: площадь, длина и ширина показаны ниже. Он также имеет функцию printArea для печати рассчитанной площади.
Создание объекта
Создание объекта – это процесс выделения памяти для экземпляра класса. Каждый из объектов имеет свою собственную память и разделяет данные общего класса.
Доступ к свойствам
Мы можем получить доступ к свойствам в классе, используя оператор точки, как показано ниже –
Доступ к функции-члену
Вы можете получить доступ к функции-члену, используя оператор двоеточия с объектом, как показано ниже –
Память распределяется и устанавливаются начальные значения. Процесс инициализации можно сравнить с конструкторами в других объектно-ориентированных языках. Это не что иное, как функция, которая позволяет устанавливать значения, как показано выше.
Полный пример
Давайте посмотрим на полный пример, используя объектную ориентацию в Lua.
Когда вы запустите вышеуказанную программу, вы получите следующий вывод.
Наследование в Lua
Наследование – это процесс расширения простых базовых объектов, таких как фигура, на прямоугольники, квадраты и так далее. Он часто используется в реальном мире для обмена и расширения основных свойств и функций.
Давайте посмотрим на простое расширение класса. У нас есть класс, как показано ниже.
Мы можем расширить форму до квадратного класса, как показано ниже.
Базовые функции
Мы можем переопределить функции базового класса, то есть вместо того, чтобы использовать функцию в базовом классе, производный класс может иметь собственную реализацию, как показано ниже –
Пример завершения наследования
Мы можем расширить реализацию простого класса в Lua, как показано выше, с помощью другого нового метода с помощью метатаблиц. Все переменные-члены и функции базового класса сохраняются в производном классе.
Когда мы запустим вышеупомянутую программу, мы получим следующий вывод –
В приведенном выше примере мы создали два производных класса – Rectangle и Square из базового класса Square. Можно переопределить функции базового класса в производном классе. В этом примере производный класс переопределяет функцию printArea.
Lua – веб-программирование
Lua – очень гибкий язык, и он часто используется на разных платформах, включая веб-приложения. Сообщество Kepler, которое было сформировано в 2004 году для предоставления веб-компонентов с открытым исходным кодом в Lua.
Несмотря на то, что существуют другие веб-фреймворки, использующие Lua, мы в первую очередь сосредоточимся на компонентах, предоставляемых сообществом Kepler.
Приложения и рамки
Orbit – это веб-фреймворк MVC для Lua, основанный на WSAPI.
WSAPI – это API, который абстрагирует сервер веб-хоста от веб-приложений Lua и является основой для многих проектов.
Xavante – это веб-сервер Lua, который предлагает интерфейс WSAPI.
Sputnik – это вики / CMS, разработанная на основе WSAPI для проекта Kepler, используемая для юмора и развлечений.
CGILua предлагает создание веб-страниц LuaPages и LuaScripts на основе WSAPI, но больше не поддерживается. Вместо этого используйте Orbit, Sputnik или WSAPI.
Orbit – это веб-фреймворк MVC для Lua, основанный на WSAPI.
WSAPI – это API, который абстрагирует сервер веб-хоста от веб-приложений Lua и является основой для многих проектов.
Xavante – это веб-сервер Lua, который предлагает интерфейс WSAPI.
Sputnik – это вики / CMS, разработанная на основе WSAPI для проекта Kepler, используемая для юмора и развлечений.
CGILua предлагает создание веб-страниц LuaPages и LuaScripts на основе WSAPI, но больше не поддерживается. Вместо этого используйте Orbit, Sputnik или WSAPI.
В этом руководстве мы постараемся помочь вам понять, что может делать Lua, и узнать больше о его установке и использовании, см. Веб-сайт kepler.
орбита
Orbit – это веб-фреймворк MVC для Lua. Он полностью отказывается от модели «сценариев» CGILua в пользу приложений, где каждое приложение Orbit может помещаться в один файл, но вы можете разбить его на несколько файлов, если хотите.
Все приложения Orbit следуют протоколу WSAPI, поэтому в настоящее время они работают с Xavante, CGI и Fastcgi. Он включает в себя панель запуска, которая позволяет легко запускать экземпляр Xavante для разработки.
Самый простой способ установить Orbit – это использовать LuaRocks. Luarocks install orbit – это команда для установки. Для этого вам нужно сначала установить LuaRocks .
Если вы не установили все зависимости, вот шаги, которые необходимо выполнить для настройки Orbit в среде Unix / Linux.
Установка Apache
Подключитесь к вашему серверу. Установите Apache2, его модули поддержки и включите необходимые модули Apache2, используя –
Установить LuaRocks
Установите WSAPI, FCGI, Orbit и Xavante
Настройка Apache2
Добавьте этот следующий раздел ниже раздела <Directory / var / www /> файла конфигурации. Если в этом разделе указано «AllowOverride None», вам нужно изменить «None» на «All», чтобы файл .htaccess мог переопределить конфигурацию локально.
Перезагрузите сервер, чтобы изменения вступили в силу.
Чтобы включить ваше приложение, вам нужно добавить + ExecCGI в файл .htaccess в корне вашего приложения Orbit – в данном случае, / var / www.
Простой пример – Орбита
Теперь вы сможете запустить свой веб-браузер. Перейдите на http: // localhost: 8080 /, и вы должны увидеть следующий вывод –
Orbit предоставляет другой вариант, т. Е. Код Lua может генерировать html.
Создание форм
Простой пример формы показан ниже –
WSAPI
Как упоминалось ранее, WSAPI выступает в качестве основы для многих проектов и имеет несколько встроенных функций. Вы можете использовать WSAPI и поддерживать следующие платформы,
- Windows
- UNIX-системы
Поддерживаемые серверы и интерфейсы WSAPI включают в себя:
- CGI
- FastCGI
- Xavante
WSAPI предоставляет ряд библиотек, что облегчает нам веб-программирование с использованием Lua. Некоторые из поддерживаемых функций в Lua включают в себя:
- Обработка запросов
- Буферизация вывода
- Аутентификация
- Загрузка файлов
- Запросить изоляцию
- мультиплексирование
Простой пример WSAPI показан ниже –
В приведенном выше коде вы видите простую HTML-страницу, которая создается и возвращается. Вы можете увидеть использование сопрограмм, которые позволяют возвращать оператор за оператором вызывающей функции. Наконец, возвращается HTML-код состояния (200), заголовки и HTML-страница.
Xavante
Xavante – это веб-сервер Lua HTTP 1.1, использующий модульную архитектуру на основе обработчиков сопоставленных URI. Ксаванте в настоящее время предлагает,
- Обработчик файлов
- Обработчик перенаправления
- Обработчик WSAPI
Обработчик файлов используется для общих файлов. Обработчик перенаправления включает переопределение URI и обработчик WSAPI для обработки с приложениями WSAPI.
Простой пример показан ниже.
Чтобы использовать виртуальные хосты с Xavante, вызов xavante.HTTP будет изменен на что-то вроде следующего:
Lua Web Components
Copas , диспетчер, основанный на сопрограммах, которые могут использоваться серверами TCP / IP.
Cosmo , движок «безопасных шаблонов», защищающий ваше приложение от произвольного кода в шаблонах.
Coxpcall инкапсулирует Lua нативный pcall и xpcall с сопрограмм-совместимыми.
LuaFileSystem , переносимый способ доступа к базовой структуре каталогов и атрибутам файлов.
Rings , библиотека, которая обеспечивает способ создания новых состояний Lua из Lua.
Copas , диспетчер, основанный на сопрограммах, которые могут использоваться серверами TCP / IP.
Cosmo , движок «безопасных шаблонов», защищающий ваше приложение от произвольного кода в шаблонах.
Coxpcall инкапсулирует Lua нативный pcall и xpcall с сопрограмм-совместимыми.
LuaFileSystem , переносимый способ доступа к базовой структуре каталогов и атрибутам файлов.
Rings , библиотека, которая обеспечивает способ создания новых состояний Lua из Lua.
Конечная заметка
Для нас доступно так много веб-фреймворков и компонентов, основанных на Lua, и, исходя из потребностей, их можно выбрать. Существуют и другие доступные веб-фреймворки, которые включают следующее:
Moonstalk позволяет эффективно разрабатывать и размещать динамически генерируемые веб-проекты, построенные на языке Lua; от базовых страниц до сложных приложений.
Lapis , фреймворк для создания веб-приложений с использованием MoonScript (или Lua), который работает внутри настроенной версии Nginx под названием OpenResty.
Lua Server Pages , плагин скриптового движка Lua, который отбрасывает любой другой подход к встроенной веб-разработке, предлагает впечатляющий краткий путь к традиционным страницам C-сервера.
Moonstalk позволяет эффективно разрабатывать и размещать динамически генерируемые веб-проекты, построенные на языке Lua; от базовых страниц до сложных приложений.
Lapis , фреймворк для создания веб-приложений с использованием MoonScript (или Lua), который работает внутри настроенной версии Nginx под названием OpenResty.
Lua Server Pages , плагин скриптового движка Lua, который отбрасывает любой другой подход к встроенной веб-разработке, предлагает впечатляющий краткий путь к традиционным страницам C-сервера.
Эти веб-фреймворки могут использовать ваши веб-приложения и помочь вам в выполнении мощных операций.
Lua – доступ к базе данных
Для простых операций с данными мы можем использовать файлы, но иногда эти файловые операции могут быть неэффективными, масштабируемыми и мощными. Для этого мы можем часто переходить на использование баз данных. LuaSQL – это простой интерфейс от Lua к ряду систем управления базами данных. LuaSQL – это библиотека, которая обеспечивает поддержку различных типов SQL. Это включает в себя,
- SQLite
- Mysql
- ODBC
В этом уроке мы рассмотрим обработку базы данных MySQL и SQLite на Lua. Он использует общий интерфейс для обоих и должен иметь возможность портировать эту реализацию на другие типы баз данных. Сначала давайте посмотрим, как вы можете делать операции в MySQL.
Настройка базы данных MySQL
Чтобы использовать следующие примеры для правильной работы, нам нужна начальная настройка БД. Допущения перечислены ниже.
Вы установили и настроили MySQL с пользователем по умолчанию в качестве пользователя root и паролем «123456».
Вы создали тест базы данных.
Вы прошли учебник по MySQL, чтобы понять основы MySQL.
Вы установили и настроили MySQL с пользователем по умолчанию в качестве пользователя root и паролем «123456».
Вы создали тест базы данных.
Вы прошли учебник по MySQL, чтобы понять основы MySQL.
Импорт MySQL
Мы можем использовать простой оператор require для импорта библиотеки sqlite, предполагая, что ваша реализация Lua была выполнена правильно.
Переменная mysql предоставит доступ к функциям, ссылаясь на основную таблицу mysql.
Настройка подключения
Мы можем установить соединение, инициируя среду MySQL, а затем создавая соединение для среды. Это показано ниже.
Вышеуказанное соединение подключится к существующему файлу MySQL и установит соединение с вновь созданным файлом.
Выполнить функцию
В соединении есть простая функция execute, которая поможет нам выполнить все операции с базами данных: создание, вставка, удаление, обновление и так далее. Синтаксис показан ниже –
В приведенном выше синтаксисе мы должны убедиться, что conn открыта и существует соединение MySQL, и заменить MySQLSTATEMENT на правильное выражение.
Пример создания таблицы
Простой пример создания таблицы показан ниже. Создает таблицу с двумя параметрами id типа integer и именем типа varchar.
Когда вы запустите вышеупомянутую программу, будет создана таблица с именем sample с двумя столбцами, а именно id и name.
В случае какой-либо ошибки вам будет возвращено сообщение об ошибке вместо nil. Простое сообщение об ошибке показано ниже.
Пример вставки выписки
Оператор вставки для MySQL показан ниже.
Пример обновления оператора
Заявление об обновлении для MySQL показано ниже.
Пример удаления выписки
Оператор удаления для MySQL показан ниже.
Выберите пример выписки
Что касается оператора select, нам нужно пройтись по каждой строке и извлечь необходимые данные. Простой оператор выбора показан ниже.
В приведенном выше коде conn является открытым MySQL-соединением. С помощью курсора, возвращаемого оператором execute, вы можете перебрать ответ таблицы и получить необходимые данные выбора.
Полный пример
Полный пример, включающий все приведенные выше утверждения, приведен ниже.
Когда вы запустите вышеуказанную программу, вы получите следующий вывод.
Выполнение транзакций
Транзакции – это механизм, который обеспечивает согласованность данных. Транзакции должны иметь следующие четыре свойства –
Атомарность – либо транзакция завершена, либо ничего не происходит вообще.
Согласованность – транзакция должна начинаться в согласованном состоянии и оставлять систему в согласованном состоянии.
Изоляция – промежуточные результаты транзакции не видны за пределами текущей транзакции.
Долговечность – после совершения транзакции последствия сохраняются даже после сбоя системы.
Атомарность – либо транзакция завершена, либо ничего не происходит вообще.
Согласованность – транзакция должна начинаться в согласованном состоянии и оставлять систему в согласованном состоянии.
Изоляция – промежуточные результаты транзакции не видны за пределами текущей транзакции.
Долговечность – после совершения транзакции последствия сохраняются даже после сбоя системы.
Транзакция начинается с START TRANSACTION; и заканчивается оператором commit или rollback.
Начать транзакцию
Чтобы инициировать транзакцию, нам нужно выполнить следующую инструкцию в Lua, предполагая, что conn является открытым MySQL-соединением.
Откат транзакции
Нам нужно выполнить следующую инструкцию, чтобы откатить изменения, сделанные после запуска транзакции.
Совершить транзакцию
Нам нужно выполнить следующую инструкцию, чтобы зафиксировать изменения, сделанные после запуска транзакции.
Мы знали о MySQL из приведенного выше, а следующий раздел объясняет основные операции SQL. Запомните транзакции, хотя они не объяснены снова для SQLite3, но те же операторы должны работать и для SQLite3.
Импорт SQLite
Мы можем использовать простой оператор require для импорта библиотеки SQLite, предполагая, что ваша реализация Lua была выполнена правильно. Во время установки, папка libsql, которая содержит файлы, связанные с базой данных.
Переменная sqlite3 предоставит доступ к функциям, ссылаясь на основную таблицу sqlite3.
Настройка подключения
Мы можем установить соединение, запустив среду SQLite, а затем создав соединение для этой среды. Это показано ниже.
Вышеуказанное соединение подключится к существующему файлу SQLite или создаст новый файл SQLite и установит соединение с вновь созданным файлом.
Выполнить функцию
В соединении есть простая функция execute, которая поможет нам выполнить все операции с базами данных: создание, вставка, удаление, обновление и так далее. Синтаксис показан ниже –
В приведенном выше синтаксисе мы должны убедиться, что conn открыта и существует соединение sqlite3, и заменить SQLite3STATEMENT на правильное выражение.
Пример создания таблицы
Простой пример создания таблицы показан ниже. Создает таблицу с двумя параметрами id типа integer и именем типа varchar.
Когда вы запустите вышеупомянутую программу, будет создана таблица с именем sample с двумя столбцами, а именно id и name.
В случае ошибки вы получите сообщение об ошибке вместо nil. Простое сообщение об ошибке показано ниже.
Пример вставки выписки
Оператор вставки для SQLite показан ниже.
Выберите пример выписки
Что касается оператора select, нам нужно пройтись по каждой строке и извлечь необходимые данные. Простой оператор выбора показан ниже.
В приведенном выше коде conn является открытым соединением sqlite3. С помощью курсора, возвращаемого оператором execute, вы можете перебрать ответ таблицы и получить необходимые данные выбора.
Полный пример
Полный пример, включающий все приведенные выше утверждения, приведен ниже.
Когда вы запустите вышеуказанную программу, вы получите следующий вывод.
Мы можем выполнить все доступные запросы с помощью этой библиотеки libsql. Поэтому, пожалуйста, не останавливайтесь на этих примерах. Поэкспериментируйте различные операторы запросов, доступные в соответствующих MySQL, SQLite3 и других поддерживаемых БД в Lua.
Lua – программирование игр
Lua используется во многих игровых движках благодаря своей простой языковой структуре и синтаксису. Функция сборки мусора часто очень полезна в играх, которые потребляют много памяти из-за богатой графики, которая используется. Некоторые игровые движки, которые используют Lua, включают в себя –
- Corona SDK
- Гидерос Мобайл
- ShiVa3D
- Моаи SDK
- ЛЮБИТЬ
- CryEngine
Каждый из этих игровых движков основан на Lua, и в каждом из этих движков доступен богатый набор API. Мы рассмотрим возможности каждого вкратце.
Corona SDK
Corona SDK – это кроссплатформенный движок для мобильных игр, который поддерживает платформы iPhone, iPad и Android. Существует бесплатная версия Corona SDK, которую можно использовать для небольших игр с ограниченными возможностями. При необходимости вы можете перейти на другие версии.
Corona SDK предоставляет ряд функций, которые включают в себя следующее –
- API для обработки физики и столкновений
- Веб и сетевые API
- API игровой сети
- API объявлений
- API аналитики
- API базы данных и файловой системы
- Крипто и математические API
- Аудио и медиа API
Легче и быстрее разрабатывать приложения с использованием вышеуказанных API, а не использовать собственные API отдельно для iOS и Android.
Гидерос Мобайл
Gideros предоставляет кроссплатформенный SDK для создания игр для iOS и Android. Его можно использовать с выплеском Gideros. Некоторые из поразительных преимуществ Gideoros включают в себя следующее:
Разработка IDE – предоставляет собственную IDE, которая облегчает разработку приложений Gideros.
Мгновенное тестирование. При разработке игры ее можно протестировать на реальном устройстве через Wi-Fi всего за 1 секунду. Вам не нужно тратить свое время на процесс экспорта или развертывания.
Плагины – Вы можете легко расширить ядро с помощью плагинов. Импортируйте свой существующий (C, C ++, Java или Obj-C) код, свяжите его с Lua и интерпретируйте их напрямую. Десятки плагинов с открытым исходным кодом уже разработаны и готовы к использованию.
Чистый ООП подход – Gideros предоставляет собственную систему классов со всеми основными стандартами ООП, что позволяет вам писать чистый и многократно используемый код для любой из ваших будущих игр.
Собственная скорость – разработанная на основе C / C ++ и OpenGL, ваша игра работает на родной скорости и полностью использует мощность процессоров и графических процессоров.
Разработка IDE – предоставляет собственную IDE, которая облегчает разработку приложений Gideros.
Мгновенное тестирование. При разработке игры ее можно протестировать на реальном устройстве через Wi-Fi всего за 1 секунду. Вам не нужно тратить свое время на процесс экспорта или развертывания.
Плагины – Вы можете легко расширить ядро с помощью плагинов. Импортируйте свой существующий (C, C ++, Java или Obj-C) код, свяжите его с Lua и интерпретируйте их напрямую. Десятки плагинов с открытым исходным кодом уже разработаны и готовы к использованию.
Чистый ООП подход – Gideros предоставляет собственную систему классов со всеми основными стандартами ООП, что позволяет вам писать чистый и многократно используемый код для любой из ваших будущих игр.
Собственная скорость – разработанная на основе C / C ++ и OpenGL, ваша игра работает на родной скорости и полностью использует мощность процессоров и графических процессоров.
ShiVa3D
ShiVa3D – это один из игровых 3D-движков, который предоставляет графический редактор, предназначенный для создания приложений и видеоигр для Интернета, консолей и мобильных устройств. Он поддерживает несколько платформ, включая Windows, Mac, Linux, iOS, Android, BlackBerry, Palm OS, Wii и WebOS.
Некоторые из основных функций включают в себя
- Стандартные плагины
- API модификации сетки
- IDE
- Встроенный редактор Terrain, Ocean и анимации
- Поддержка физического движка ODE
- Полный контроль над картой света
- Предварительный просмотр материалов, частиц, следов и HUD
- Поддержка формата обмена Collada
Веб-версия Shiva3d абсолютно бесплатна, и другие издания, на которые вы подписаны.
Моаи SDK
Moai SDK – это кроссплатформенный движок для мобильных игр, который поддерживает платформы iPhone, iPad и Android. Платформа Moai изначально состояла из Moai SDK, игрового движка с открытым исходным кодом, и Moai Cloud, облачной платформы как службы для размещения и развертывания игровых сервисов. Теперь Moai Cloud отключен и доступен только игровой движок.
Moai SDK работает на нескольких платформах, включая iOS, Android, Chrome, Windows, Mac и Linux.
ЛЮБИТЬ
LOVE – это фреймворк, который вы можете использовать для создания 2D-игр. Это бесплатно и с открытым исходным кодом. Он поддерживает платформы Windows, Mac OS X и Linux.
Он предоставляет несколько функций, которые включают в себя,
- Аудио API
- API файловой системы
- API клавиатуры и джойстика
- Математический API
- API окна и мыши
- Физика API
- Системные и таймерные API
CryEngine
CryEngine – игровой движок, разработанный немецким разработчиком игр Crytek. Он эволюционировал от поколения 1 до поколения 4 и является передовым решением для разработки. Он поддерживает игры для ПК, Xbox 360, PlayStation3 и WiiU.
Он предоставляет несколько функций, которые включают в себя,
Визуальные эффекты, такие как Естественное освещение и Динамические мягкие тени, Динамическое глобальное освещение в реальном времени, Объем распространения света, Затенение частиц, Тесселяция и так далее.
Система анимации персонажей и система индивидуализации персонажей.
Параметрическая анимация скелета и уникальный специализированный редактор анимации лица
Системы искусственного интеллекта, такие как многослойная навигационная сетка и система тактических точек. Также предоставляет Дизайнерскую систему редактирования AI.
В микшировании и профилировании игр, управляемой данными звуковой системе, динамических звуках, интерактивной музыке и т. Д.
Физические особенности как Процессуальная Деформация и Продвинутая Физика Веревки.
Визуальные эффекты, такие как Естественное освещение и Динамические мягкие тени, Динамическое глобальное освещение в реальном времени, Объем распространения света, Затенение частиц, Тесселяция и так далее.
Система анимации персонажей и система индивидуализации персонажей.
Параметрическая анимация скелета и уникальный специализированный редактор анимации лица
Системы искусственного интеллекта, такие как многослойная навигационная сетка и система тактических точек. Также предоставляет Дизайнерскую систему редактирования AI.
В микшировании и профилировании игр, управляемой данными звуковой системе, динамических звуках, интерактивной музыке и т. Д.
Физические особенности как Процессуальная Деформация и Продвинутая Физика Веревки.
Конечная записка
Каждый из этих игровых SDK / фреймворков имеет свои преимущества и недостатки. Правильный выбор между ними облегчит вашу задачу, и вы сможете лучше с ней справиться. Поэтому, прежде чем использовать его, вам необходимо знать требования к вашей игре, а затем проанализировать, которые удовлетворяют все ваши потребности, а затем использовать их.
Lua – Стандартные библиотеки
Стандартные библиотеки Lua предоставляют богатый набор функций, которые реализуются непосредственно с C API и встроены в язык программирования Lua. Эти библиотеки предоставляют сервисы на языке программирования Lua, а также сторонние сервисы, такие как операции с файлами и БД.
Эти стандартные библиотеки, встроенные в официальный C API, предоставляются как отдельные модули C. Это включает в себя следующее –
- Основная библиотека, которая включает в себя подпрограмму сопрограммы
- Библиотека модулей
- Струнные манипуляции
- Таблица манипуляций
- Математическая библиотека
- Ввод и вывод файла
- Средства операционной системы
- Средства отладки
Основная библиотека
Мы использовали базовую библиотеку на протяжении всего урока по различным темам. В следующей таблице приведены ссылки на связанные страницы и перечислены функции, которые рассматриваются в различных частях этого учебного пособия по Lua.
Обработка ошибок
Включает в себя функции обработки ошибок, такие как assert, error, как описано в Lua – Error Errorling .
Управление памятью
Включает функции автоматического управления памятью, связанные со сборкой мусора, как описано в Lua – Сборка мусора .
dofile ([имя файла])
Он открывает файл и выполняет содержимое файла как чанк. Если параметр не передан, то эта функция выполняет содержимое стандартного ввода. Ошибки будут переданы вызывающей стороне.
Таким образом, глобальная переменная содержит глобальную среду (то есть _G._G = _G). Сам Lua не использует эту переменную.
Возвращает текущую среду, используемую функцией. f может быть функцией Lua или числом, которое определяет функцию на этом уровне стека. Уровень 1 – это функция, вызывающая getfenv. Если данная функция не является функцией Lua или если f равно 0, getfenv возвращает глобальную среду. Значением по умолчанию для f является 1.
getmetatable (объект)
Если объект не имеет метатаблицы, возвращает ноль. В противном случае, если у метатаблицы объекта есть поле «__metatable», возвращается соответствующее значение. В противном случае возвращает метатаблицу данного объекта.
Эта функция выбирает индексы и значения таблиц.
load (func [, chunkname])
Загружает кусок, используя функцию func, чтобы получить его части. Каждый вызов func должен возвращать строку, которая объединяется с предыдущими результатами.
файл загрузки ([имя файла]))
Аналогичен загрузке, но получает фрагмент из имени файла или из стандартного ввода, если имя файла не указано.
loadstring (строка [, chunkname])
Аналогично загрузке, но получает фрагмент из заданной строки.
следующий (таблица [, индекс])
Позволяет программе пересекать все поля таблицы. Его первый аргумент – это таблица, а второй аргумент – это индекс в этой таблице. next возвращает следующий индекс таблицы и связанное с ней значение.
Приостанавливает запущенную сопрограмму. Параметр, передаваемый этому методу, действует как дополнительные возвращаемые значения функции возобновления.
Приостанавливает запущенную сопрограмму. Параметр, передаваемый этому методу, действует как дополнительные возвращаемые значения функции возобновления.
rawequal (v1, v2)
Проверяет, равен ли v1 v2, не вызывая метаметод. Возвращает логическое значение.
rawget (таблица, индекс)
Получает реальное значение таблицы [index], не вызывая метаметод. таблица должна быть таблицей; Индекс может быть любым значением.
rawset (таблица, индекс, значение)
Устанавливает реальное значение таблицы [индекс] в значение, не вызывая метаметод. table должен быть таблицей, индексировать любое значение, отличное от nil, и value любое значение Lua. Эта функция возвращает таблицу.
выберите (индекс, …)
Если index является числом, возвращает все аргументы после индекса номера аргумента. В противном случае index должен быть строкой «#», а select возвращает общее количество дополнительных аргументов, которые он получил.
setfenv (f, таблица)
Устанавливает среду, которая будет использоваться данной функцией. f может быть функцией Lua или числом, которое определяет функцию на этом уровне стека. Уровень 1 – это функция, вызывающая setfenv. setfenv возвращает данную функцию. В качестве особого случая, когда f равно 0, setfenv изменяет среду работающего потока. В этом случае setfenv не возвращает значений.
setmetatable (таблица, метатабельный)
Устанавливает метатаблицу для данной таблицы. (Вы не можете изменить метатабель других типов из Lua, только из C.) Если метатабил равен нулю, удаляет метатабиль данной таблицы. Если исходный метатабль имеет поле «__metatable», возникает ошибка. Эта функция возвращает таблицу.
tonumber (e [, base])
Пытается преобразовать свой аргумент в число. Если аргумент уже является числом или строкой, конвертируемой в число, то tonumber возвращает это число; в противном случае возвращается ноль.
Получает аргумент любого типа и преобразует его в строку в приемлемом формате. Для полного контроля над тем, как числа конвертируются, используйте string.format.
Возвращает тип единственного аргумента, закодированного в виде строки. Возможные результаты этой функции: «nil» (строка, а не значение nil), «number», «string», «boolean», «table», «function», «thread» и «userdata».
распаковать (список [, i [, j]])
Возвращает элементы из данной таблицы.
Глобальная переменная (не функция), которая содержит строку, содержащую текущую версию интерпретатора. Текущее содержимое этой переменной – «Lua 5.1».
Сопрограммы
Включает функции манипулирования сопрограммой, как описано в Lua – Coroutines .
Обработка ошибок
Включает в себя функции обработки ошибок, такие как assert, error, как описано в Lua – Error Errorling .
Управление памятью
Включает функции автоматического управления памятью, связанные со сборкой мусора, как описано в Lua – Сборка мусора .
dofile ([имя файла])
Он открывает файл и выполняет содержимое файла как чанк. Если параметр не передан, то эта функция выполняет содержимое стандартного ввода. Ошибки будут переданы вызывающей стороне.
Таким образом, глобальная переменная содержит глобальную среду (то есть _G._G = _G). Сам Lua не использует эту переменную.
Возвращает текущую среду, используемую функцией. f может быть функцией Lua или числом, которое определяет функцию на этом уровне стека. Уровень 1 – это функция, вызывающая getfenv. Если данная функция не является функцией Lua или если f равно 0, getfenv возвращает глобальную среду. Значением по умолчанию для f является 1.
getmetatable (объект)
Если объект не имеет метатаблицы, возвращает ноль. В противном случае, если у метатаблицы объекта есть поле «__metatable», возвращается соответствующее значение. В противном случае возвращает метатаблицу данного объекта.
Эта функция выбирает индексы и значения таблиц.
load (func [, chunkname])
Загружает кусок, используя функцию func, чтобы получить его части. Каждый вызов func должен возвращать строку, которая объединяется с предыдущими результатами.
файл загрузки ([имя файла]))
Аналогичен загрузке, но получает фрагмент из имени файла или из стандартного ввода, если имя файла не указано.
loadstring (строка [, chunkname])
Аналогично загрузке, но получает фрагмент из заданной строки.
следующий (таблица [, индекс])
Позволяет программе пересекать все поля таблицы. Его первый аргумент – это таблица, а второй аргумент – это индекс в этой таблице. next возвращает следующий индекс таблицы и связанное с ней значение.
Приостанавливает запущенную сопрограмму. Параметр, передаваемый этому методу, действует как дополнительные возвращаемые значения функции возобновления.
Приостанавливает запущенную сопрограмму. Параметр, передаваемый этому методу, действует как дополнительные возвращаемые значения функции возобновления.
rawequal (v1, v2)
Проверяет, равен ли v1 v2, не вызывая метаметод. Возвращает логическое значение.
rawget (таблица, индекс)
Получает реальное значение таблицы [index], не вызывая метаметод. таблица должна быть таблицей; Индекс может быть любым значением.
rawset (таблица, индекс, значение)
Устанавливает реальное значение таблицы [индекс] в значение, не вызывая метаметод. table должен быть таблицей, индексировать любое значение, отличное от nil, и value любое значение Lua. Эта функция возвращает таблицу.
выберите (индекс, …)
Если index является числом, возвращает все аргументы после индекса номера аргумента. В противном случае index должен быть строкой «#», а select возвращает общее количество дополнительных аргументов, которые он получил.
setfenv (f, таблица)
Устанавливает среду, которая будет использоваться данной функцией. f может быть функцией Lua или числом, которое определяет функцию на этом уровне стека. Уровень 1 – это функция, вызывающая setfenv. setfenv возвращает данную функцию. В качестве особого случая, когда f равно 0, setfenv изменяет среду работающего потока. В этом случае setfenv не возвращает значений.
setmetatable (таблица, метатабельный)
Устанавливает метатаблицу для данной таблицы. (Вы не можете изменить метатабель других типов из Lua, только из C.) Если метатабил равен нулю, удаляет метатабиль данной таблицы. Если исходный метатабль имеет поле «__metatable», возникает ошибка. Эта функция возвращает таблицу.
tonumber (e [, base])
Пытается преобразовать свой аргумент в число. Если аргумент уже является числом или строкой, конвертируемой в число, то tonumber возвращает это число; в противном случае возвращается ноль.
Получает аргумент любого типа и преобразует его в строку в приемлемом формате. Для полного контроля над тем, как числа конвертируются, используйте string.format.
Возвращает тип единственного аргумента, закодированного в виде строки. Возможные результаты этой функции: «nil» (строка, а не значение nil), «number», «string», «boolean», «table», «function», «thread» и «userdata».
распаковать (список [, i [, j]])
Возвращает элементы из данной таблицы.
Глобальная переменная (не функция), которая содержит строку, содержащую текущую версию интерпретатора. Текущее содержимое этой переменной – «Lua 5.1».
Сопрограммы
Включает функции манипулирования сопрограммой, как описано в Lua – Coroutines .
Библиотека модулей
Библиотека модулей предоставляет основные функции для загрузки модулей в Lua. Он экспортирует одну функцию напрямую в глобальную среду: требуется. Все остальное экспортируется в пакет таблицы. Подробности о библиотеке модулей описаны в предыдущей главе Lua – Модули .
Струнные манипуляции
Lua предоставляет богатый набор функций для работы со строками. В предыдущем уроке по Lua – Strings это подробно описано.
Таблица манипуляций
Lua зависит от таблиц почти во всех операциях. В предыдущем уроке Lua – Tables это подробно описано.
Ввод и вывод файла
Нам часто требуется средство хранения данных при программировании, и это обеспечивается стандартными библиотечными функциями для файлового ввода-вывода в Lua. Это обсуждалось в предыдущем уроке Lua – File I / O.
Средства отладки
Lua предоставляет библиотеку отладки, которая предоставляет нам все примитивные функции для создания нашего собственного отладчика. Это обсуждалось ранее в Lua – Руководство по отладке .
Lua – математическая библиотека
Нам часто нужны математические операции в научных и инженерных расчетах, и мы можем использовать это, используя стандартную библиотеку математики Lua. Список функций, доступных в математической библиотеке, показан в следующей таблице.
Возвращает абсолютное значение х.
Возвращает арккосинус от x (в радианах).
Возвращает арксинус x (в радианах).
математика (х)
Возвращает арктангенс х (в радианах).
math.atan2 (у, х)
Возвращает арктангенс y / x (в радианах), но использует знаки обоих параметров, чтобы найти квадрант результата. (Он также правильно обрабатывает случай, когда х равен нулю.)
Возвращает наименьшее целое число, большее или равное x.
Возвращает косинус x (предполагается в радианах).
Возвращает гиперболический косинус x.
Возвращает угол x (в радианах) в градусах.
Возвращает значение e power x.
math.floor (x)
Возвращает наибольшее целое число, меньшее или равное x.
math.fmod (x, y)
Возвращает остаток от деления x на y, которое округляет частное к нулю.
math.frexp (x)
Возвращает m и e, такие что x = m2e, e является целым числом, а абсолютное значение m находится в диапазоне [0,5, 1) (или ноль, когда x равен нулю).
Значение HUGE_VAL, значение больше или равно любому другому числовому значению.
math.ldexp (м, е)
Возвращает m2e (e должно быть целым числом).
Возвращает натуральный логарифм x.
math.log10 (x)
Возвращает основание-10 логарифм х.
Возвращает максимальное значение среди своих аргументов.
Возвращает минимальное значение среди своих аргументов.
Возвращает два числа, неотъемлемую часть x и дробную часть x.
math.pow (x, y)
Возвращает ху. (Вы также можете использовать выражение x ^ y для вычисления этого значения.)
Возвращает угол x (в градусах) в радианах.
math.random ([m [, n]])
Эта функция является интерфейсом к простой функции генератора псевдослучайных рандов, предоставляемой ANSI C. При вызове без аргументов возвращает равномерное псевдослучайное действительное число в диапазоне [0,1). При вызове с целым числом m, math.random возвращает равномерное псевдослучайное целое число в диапазоне [1, m]. При вызове с двумя целыми числами m и n math.random возвращает равномерное псевдослучайное целое число в диапазоне [m, n].
математика. случайное семя (х)
Устанавливает x в качестве «начального числа» для псевдослучайного генератора: равные начальные числа создают равные последовательности чисел.
математика (х)
Возвращает синус х (предполагается в радианах).
Возвращает гиперболический синус x.
Возвращает квадратный корень из х. (Вы также можете использовать выражение x ^ 0.5 для вычисления этого значения.)
математика (х)
Возвращает тангенс x (предполагается в радианах).
математика (х)
Возвращает гиперболический тангенс x.
Возвращает абсолютное значение х.
Возвращает арккосинус от x (в радианах).
Возвращает арксинус x (в радианах).
математика (х)
Возвращает арктангенс х (в радианах).
math.atan2 (у, х)
Возвращает арктангенс y / x (в радианах), но использует знаки обоих параметров, чтобы найти квадрант результата. (Он также правильно обрабатывает случай, когда х равен нулю.)
Возвращает наименьшее целое число, большее или равное x.
Возвращает косинус x (предполагается в радианах).
Возвращает гиперболический косинус x.
Возвращает угол x (в радианах) в градусах.
Возвращает значение e power x.
math.floor (x)
Возвращает наибольшее целое число, меньшее или равное x.
math.fmod (x, y)
Возвращает остаток от деления x на y, которое округляет частное к нулю.
math.frexp (x)
Возвращает m и e, такие что x = m2e, e является целым числом, а абсолютное значение m находится в диапазоне [0,5, 1) (или ноль, когда x равен нулю).
Значение HUGE_VAL, значение больше или равно любому другому числовому значению.
math.ldexp (м, е)
Возвращает m2e (e должно быть целым числом).
Возвращает натуральный логарифм x.
math.log10 (x)
Возвращает основание-10 логарифм х.
Возвращает максимальное значение среди своих аргументов.
Возвращает минимальное значение среди своих аргументов.
Возвращает два числа, неотъемлемую часть x и дробную часть x.
math.pow (x, y)
Возвращает ху. (Вы также можете использовать выражение x ^ y для вычисления этого значения.)
Возвращает угол x (в градусах) в радианах.
math.random ([m [, n]])
Эта функция является интерфейсом к простой функции генератора псевдослучайных рандов, предоставляемой ANSI C. При вызове без аргументов возвращает равномерное псевдослучайное действительное число в диапазоне [0,1). При вызове с целым числом m, math.random возвращает равномерное псевдослучайное целое число в диапазоне [1, m]. При вызове с двумя целыми числами m и n math.random возвращает равномерное псевдослучайное целое число в диапазоне [m, n].
математика. случайное семя (х)
Устанавливает x в качестве «начального числа» для псевдослучайного генератора: равные начальные числа создают равные последовательности чисел.
математика (х)
Возвращает синус х (предполагается в радианах).
Возвращает гиперболический синус x.
Возвращает квадратный корень из х. (Вы также можете использовать выражение x ^ 0.5 для вычисления этого значения.)
математика (х)
Возвращает тангенс x (предполагается в радианах).
математика (х)
Возвращает гиперболический тангенс x.
Тригонометрические функции
Простой пример использования тригонометрической функции показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Другие общие математические функции
Простой пример использования общих математических функций показан ниже.
Когда мы запустим вышеуказанную программу, мы получим следующий вывод.
Приведенные выше примеры являются лишь некоторыми из распространенных примеров, мы можем использовать математическую библиотеку в зависимости от наших потребностей, поэтому попробуйте использовать все функции, чтобы быть более знакомыми.
Lua – Возможности операционной системы
В любом приложении это часто требуется для доступа к функциям уровня операционной системы, и оно доступно с библиотекой операционной системы. Список доступных функций приведен в следующей таблице.
Возвращает приблизительную величину в секундах процессорного времени, используемого программой.
os.date ([формат [, время]])
Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданным форматом строки.
os.difftime (t2, t1)
Возвращает количество секунд от времени t1 до времени t2. В POSIX, Windows и некоторых других системах это значение точно равно t2-t1.
os.execute ([команда])
Эта функция эквивалентна системе функций ANSI C. Он передает команду для выполнения оболочкой операционной системы. Его первый результат – true, если команда завершилась успешно, или nil в противном случае.
os.exit ([code [, close])
Вызывает выход из функции ANSI C, чтобы завершить программу хоста. Если код равен true, возвращаемый статус – EXIT_SUCCESS; если код ложен, возвращаемый статус – EXIT_FAILURE; если код – число, возвращаемое состояние – это число.
os.getenv (varname)
Возвращает значение переменной среды процесса varname или nil, если переменная не определена.
os.remove (имя файла)
Удаляет файл (или пустой каталог в системах POSIX) с указанным именем. Если эта функция завершается ошибкой, она возвращает nil плюс строку, описывающую ошибку и код ошибки.
os.rename (старое имя, новое имя)
Переименовывает файл или каталог с именем oldname в newname. Если эта функция завершается ошибкой, она возвращает nil плюс строку, описывающую ошибку и код ошибки.
os.setlocale (locale [, category])
Устанавливает текущую локаль программы. locale – системно-зависимая строка, определяющая локаль; категория – необязательная строка, описывающая, какую категорию изменить: «all», «collate», «ctype», «денежный», «числовой» или «время»; категория по умолчанию – «все». Функция возвращает имя новой локали или nil, если запрос не может быть выполнен.
os.time ([таблица])
Возвращает текущее время при вызове без аргументов или время, представляющее дату и время, указанные в данной таблице. Эта таблица должна содержать поля year, month и day и может иметь поля hour (по умолчанию 12), min (по умолчанию 0), sec (по умолчанию 0) и isdst (по умолчанию nil). Описание этих полей см. В функции os.date.
Возвращает строку с именем файла, которую можно использовать для временного файла. Файл должен быть явно открыт перед использованием и явно удален, когда он больше не нужен.
Возвращает приблизительную величину в секундах процессорного времени, используемого программой.
os.date ([формат [, время]])
Возвращает строку или таблицу, содержащую дату и время, отформатированные в соответствии с заданным форматом строки.
os.difftime (t2, t1)
Возвращает количество секунд от времени t1 до времени t2. В POSIX, Windows и некоторых других системах это значение точно равно t2-t1.
os.execute ([команда])
Эта функция эквивалентна системе функций ANSI C. Он передает команду для выполнения оболочкой операционной системы. Его первый результат – true, если команда завершилась успешно, или nil в противном случае.
os.exit ([code [, close])
Вызывает выход из функции ANSI C, чтобы завершить программу хоста. Если код равен true, возвращаемый статус – EXIT_SUCCESS; если код ложен, возвращаемый статус – EXIT_FAILURE; если код – число, возвращаемое состояние – это число.
os.getenv (varname)
Возвращает значение переменной среды процесса varname или nil, если переменная не определена.
os.remove (имя файла)
Удаляет файл (или пустой каталог в системах POSIX) с указанным именем. Если эта функция завершается ошибкой, она возвращает nil плюс строку, описывающую ошибку и код ошибки.
os.rename (старое имя, новое имя)
Переименовывает файл или каталог с именем oldname в newname. Если эта функция завершается ошибкой, она возвращает nil плюс строку, описывающую ошибку и код ошибки.
os.setlocale (locale [, category])
Устанавливает текущую локаль программы. locale – системно-зависимая строка, определяющая локаль; категория – необязательная строка, описывающая, какую категорию изменить: «all», «collate», «ctype», «денежный», «числовой» или «время»; категория по умолчанию – «все». Функция возвращает имя новой локали или nil, если запрос не может быть выполнен.
os.time ([таблица])
Возвращает текущее время при вызове без аргументов или время, представляющее дату и время, указанные в данной таблице. Эта таблица должна содержать поля year, month и day и может иметь поля hour (по умолчанию 12), min (по умолчанию 0), sec (по умолчанию 0) и isdst (по умолчанию nil). Описание этих полей см. В функции os.date.
Возвращает строку с именем файла, которую можно использовать для временного файла. Файл должен быть явно открыт перед использованием и явно удален, когда он больше не нужен.
Общие функции ОС
Простой пример использования общих математических функций показан ниже.
Когда мы запустим вышеуказанную программу, мы получим вывод, аналогичный следующему.
Приведенные выше примеры являются лишь некоторыми из распространенных примеров, мы можем использовать библиотеку ОС в зависимости от наших потребностей, поэтому попробуйте использовать все функции, чтобы быть более знакомыми. Существуют такие функции, как удаление, которое помогает в удалении файла, выполнение, которое помогает нам выполнять команды ОС, как описано выше.