`

СПЕЦИАЛЬНЫЕ
ПАРТНЕРЫ
ПРОЕКТА

Архив номеров

Как изменилось финансирование ИТ-направления в вашей организации?

Best CIO

Определение наиболее профессиональных ИТ-управленцев, лидеров и экспертов в своих отраслях

Человек года

Кто внес наибольший вклад в развитие украинского ИТ-рынка.

Продукт года

Награды «Продукт года» еженедельника «Компьютерное обозрение» за наиболее выдающиеся ИТ-товары

 

Еще один «летний» язык программирования. Часть 3

0 
 

В давние времена автору наивно казалось, что чудный синий карманный справочник по языку C (автор – М. И. Болски) позволяет изучить этот язык. Наивность подогревалась тем, что C как будто прост. Но наивность утрачивается с опытом, и наступает такой момент, когда обильно разукрашенный комментариями стандарт ISO/IEC 9899 становится настольной книгой.

Сказанное в преамбуле о C далеко не во всех случаях справедливо. Но все-таки... Изучение языка программирования – процесс непростой. И поспешность здесь совершенно не обязательна. Тем более когда речь идет о таком специфическом языке, как Lua. Так что никуда не спешите – балуйтесь в свое удовольствие и не форсируйте ситуацию. Обо всех нюансах языка мы непременно поговорим. И после этого обсуждения вы будете лучше подготовлены к дальнейшему самостоятельному изучению. А теперь, как обычно, немного не очень свежих не совсем новостей.

Как ни странно, но за прошедшие две недели событий незначительных, но значимых было не так уж и много. Из небольшого их перечня можно выбрать парочку достойных того, чтобы отнять пару минут вашего драгоценного времени. Два события произошли в области, не относящейся непосредственно к информационным технологиям, но косвенно снабжающей эти самые технологии рабочими местами, заказами на технику и программное обеспечение и, наконец, просто деньгами. Речь идет о медиаиндустрии. Здесь совершенно незаметно наступил практически переломный момент: по данным организации EMR (Entertainment Media Research), количество легальных потребителей музыки как товара стало соизмеримым с количеством нелегалов, иначе говоря, пиратов. Текущее соотношение 35% к 40% (легальных покупателей к пиратам соответственно) считается очень высоким, а по оценкам аналитиков, оно еще будет увеличиваться в 2006 г. Правда, все сказанное справедливо пока только для Великобритании.

Британский опыт интересен в первую очередь возможностью найти хоть несколько вариантов ответов на самый сложный вопрос: из-за чего человек платит за то, что можно получить бесплатно? (Все варианты ответов, безусловно, отыскать невозможно.) Как выяснилось, боязнь репрессий все-таки пугает британских потребителей. Равно как и боязнь подцепить какую-либо «заразу» при использовании underground-сервисов. Но большинство жителей туманного Альбиона предпочитают платить за музыку вовсе не из-за какой-то боязни. Напротив, платят они не «из-за», а «за»: две трети предпочитающих легальный путь получения оцифрованной услады души готовы отдать свои деньги именно за быструю доступность свежей музыки. В списке предпочтений на втором месте находится удобство сервисов при покупке МР3-музыки. К слову, о МР3. Современная система коммерческого распространения музыки невозможна как без этого формата компрессии, так и без его конкурентов. Компрессия позволяет уменьшить объем загружаемых покупателями файлов, что означает, по большому счету, снижение их стоимости. По этой причине все, что связано с аудиокомпрессией, денежно (и значит, важно). Особый раздел этого «всего» – аппаратные средства, в первую очередь позволяющие создавать дешевые, долго работающие от батареи и удобные МР3-плееры. Ведь именно ими замыкается цепочка создания–распространения музыки. Удачная конструкция МР3-плеера, как показал опыт Apple iPOD, может стать отправной точкой для реализации масштабной инфраструктуры. А вот удачность конструкции, кроме очевидно неформальных, но доступных потребительской оценке критериев (красота, изящество, стиль и т. п.) определяется во многом и невидимой потребителю «начинкой». Продолжительность непрерывной работы, качество звука и стоимость – критерии более чем немаловажные, и никакой «симпатичностью» дизайна их не заменишь. Для стремящихся улучшить эти показатели «МР3-плееростроителей» известный «неизвестный монополист» – компания ARM – разработала технологию цифровой обработки звука OptimoDE. Основа OptimoDE – пригодное к синтезу ядро процессора обработки сигналов, обладающее завидными энергетическими характеристиками. Так, при реализации декодера МР3 по технологии OptimoDE можно добиться декодирования стереофонического потока 320 KBps при потреблении всего 800 мкВт (напряжение питания 1,2 В). ARM сразу позаботилась и о программной поддержке OptimoDE – такой серьезный поставщик ПО для всех видов цифровых аудиоустройств, как ESPICO, уже заключил договор о партнерстве с ARM.

Из всего этого каждый может сделать много далеко идущих выводов. Очевидно же одно: для нас, потребителей, это означает, что хороших музыкальных сервисов и качественных МР3-плееров станет больше, и они будут еще доступнее. И вполне вероятно, что наступит такой замечательный день, когда мы сможем позволить себе платить не «из-за», а все-таки «за» (а вот это надежда, а вовсе не вывод).

На этом отступление завершено, и мы возвращаемся от музыки денег к музыке байтов. То есть к Lua.

Lua – таблицы

«Таблица» в Lua – это не только базовый тип данных. И даже не столько. Это фундаментальная основа языка, предопределяющая чуть ли не все возможности Lua. Но мы начнем знакомство с таблицами именно как с типом данных, продолжая предыдущий «выпуск» статьи о Lua.

Таблица (table) – это так называемый ассоциативный массив. Представьте себе набор пар вида «ключ, значение», в котором возможен быстрый (даже почти мгновенный) поиск по «ключу». Если в качестве ключей таблицы выступает последовательность целых неотрицательных чисел, начинающаяся с нуля, такая таблица моделирует массив, характерный для многих языков программирования. Но для таблиц Lua этот массив – всего лишь частный случай, потому что «ключом» в таблицах Lua может быть значение любого допустимого в языке типа, исключая уникальное специальное значение типа nil. Впрочем, это всего лишь признак полноценной «ассоциативности» таблиц Lua, у которых есть еще ряд интересных свойств. Главное в перечне этих свойств то, что таблицы являются как бы отдельным, особенным «существом» в Lua, не относящимся ни к миру значений, ни к миру контейнеров-переменных, в которых значения могут храниться. Таблицы Lua – это динамически размещаемые объекты, манипуляции с которыми осуществляются только с помощью ссылок на них. Собственно объекты-таблицы доступны лишь внутренней подсистеме управления памятью Lua – «сборщику мусора». Соответственно, Lua-программист не просто не должен объявлять таблицы перед их созданием. Lua-программист просто не может объявлять таблицы – в языке не существует средств для их объявления. Таблицы можно непосредственно создавать с помощью механизма Lua, называемого выражением-конструктором (в дальнейшем – просто конструктором). При каждом использовании программистом конструктор создает новую таблицу и возвращает ссылку на нее. Именно этой ссылкой и будет оперировать Lua-программист.

Теперь давайте попробуем создать в Lua массив, аналогичный массиву в языке C, объявленному с помощью следующего C-выражения:

double ArD[5] =  1.5, 2.0, 2.5, 3.0, 3.5  ;

Для незнакомых с языком C и ему подобными: в этой строке объявлен и создан массив с именем ArD, содержащий пять значений, каждое из которых имеет тип double (число с плавающей точкой двойной точности). По совершенно очевидным (смайлики в бумажных изданиях ставить не положено) правилам языка C первый элемент массива (в этом примере – число 1.5) принято считать нулевым. В виде пар «индекс-ключ, значение» этот массив можно представить так:

0, 1.5
1, 2.0
2, 2.5
3, 3.0
4, 3.5

Массив C позволяет с помощью исключительно быстрого механизма «поиска» по индексу-ключу «находить» соответствующее значение, скажем по индексу 3 – значение 3.5 (если серьезно, то упомянутая «очевидность» C – расплата за эффективность). Заметьте, что в объявлении C-массива мы явно указали его размерность (число элементов) и тип используемых элементов, а оператор "=" в этом примере является оператором инициализации.

В Lua C-подобный массив можно создать так:

ArD = 
ArD[0] = 1.5
ArD[1] = 2.0
ArD[2] = 2.5
ArD[3] = 3.0
ArD[4] = 3.5
Еще один «летний» язык программирования. Часть 3
Рис. 1

Проверим тип результата с помощью уже известных нам функций Lua – print(type(ArD) и получим подтверждение: то, что хранится в ArD, это таблица (рис. 1). На этой же иллюстрации особое внимание стоит обратить на значение того, что хранится в переменной-контейнере ArD. Данное значение мы можем просмотреть посредством вызова print(ArD). Полученный результат (набор цифр 0032AAE0) совершенно не похож на то, что было использовано при создании таблицы, на которую ссылается содержимое переменной ArD. 0032AAE0 – это значение ссылки на таблицу (32-разрядный адрес в шестнадцатеричной форме).

Еще один «летний» язык программирования. Часть 3
Рис. 2

Теперь можно испытать механизм поиска по ключу в массиве – с помощью выражений вида ссылка_на_таблицу[ключ]. Как видно на рис. 2, «адская механика» работает, и Lua уверенно находит ассоциированные с цифрами 0–4 значения.

Этот простенький пример на самом деле показывает колоссальные отличия между массивами C (и большинства компилируемых языков) и таблицами Lua. В Lua мы сначала создали пустую таблицу с помощью самой простой формы конструктора ("") и записали возвращаемое конструктором значение ссылки на таблицу в переменную с именем ArD:

ArD = 

Затем мы добавляли к пустой таблице новые элементы. Никакой необходимости в явном или неявном указании количества данных элементов в Lua нет, потому что, как уже говорилось ранее, таблицы имеют динамический характер. Давайте сразу же опробуем этот характер на деле – добавим к нашей таблице, на которую ссылается содержимое переменной ArD, еще один элемент, с ключом-индексом, например, 10:

ArD[10] = 6.5

Lua спокойно «съедает» и это. А что при этом случилось со ссылкой на таблицу? Давайте проверим. Содержимое переменной ArD после добавления элемента не изменилось – 0032AAE0. То есть ссылка на таблицу осталась прежней, что является косвенным подтверждением высокой эффективности реализации механизма ассоциативных таблиц в Lua – в нем нет скрытых дорогих (в терминах вычислительных ресурсов) операций копирования или создания новых таблиц!

Последняя модификация таблицы, на которую ссылается значение, хранящееся в переменной ArD (обратите внимание на эту как будто избыточную, но единственно правильную формулировку), уже демонстрирует отличие динамического «массива» Lua от статического массива C. А теперь давайте попробуем использовать больше возможностей таблиц Lua. Попытаемся создать элемент, ассоциирующий нецелый индекс-ключ с нецелым же значением. Например, так:

ArD[1.2] = 2.225
ArD[1.75] = 2.543

К этим парам можно добавить и такую:

ArD["discounted"] = 199.99

После всех этих процедур изобразить таблицу, на которую ссылается содержимое ArD, в виде пар «индекс-ключ, значение» можно следующим образом:

0, 1.5
1, 2.0
2, 2.5
3, 3.0
4, 3.5
10, 6.5
1.2, 2.225
1.75, 2.543
"discounted", 199.99

Давайте убедимся в справедливости данного утверждения. Немного забегая вперед, ознакомимся с одной (пока что назовем ее идиоматической) конструкцией Lua, позволяющей «обойти» все пары какой-то таблицы и выполнить со значениями каждой пары необходимые программисту действия. В нашем случае эти действия просты: мы просто хотим «напечатать» все пары таблицы, на которую ссылается содержимое переменной ArD. Для этого наберите chunk следующего содержания и передайте его на исполнение интерпретатору Lua:

for i,j in pairs(ArD) do
print(i,j) end
Еще один «летний» язык программирования. Часть 3
Рис. 3

Как видно из рис. 3, полученный практическим путем результат идентичен предыдущему предположению. Мы не будем обсуждать семантику приведенного фрагмента кода, ограничимся лишь сведениями о том, что этот chunk можно использовать как шаблон для отображения всех пар определенной таблицы, ссылка на которую хранится в переменной с именем TABLE_NAME:

for i,j in pairs(TABLE_NAME) do
print(i,j) end

Пока мы рассматривали динамический характер таблицы как-то однобоко – только добавляли к ней новые пары. Lua, естественно, позволяет не только это – ранее созданные пары «индекс-ключ, значение» можно и удалять. Причем процедура удаления крайне проста: для ее осуществления достаточно в паре изменить «значение» на уникальное типа nil. Давайте попробуем удалить пару, ассоциирующую нецелый индекс-ключ 1.2 со значением 2.225:

ArD[1.2]=nil
Еще один «летний» язык программирования. Часть 3
Рис. 4

Повторное использование шаблонной конструкции вывода перечня всех пар таблицы ArD показывает, что пара 1.2, 2.225 бесследно исчезла (рис. 4).

Еще один важный эксперимент с таблицами Lua направлен на то, чтобы не допустить заблуждения, которое может возникнуть из-за аналогий. Не прерывая работы в интерпретаторе Lua, попробуйте такой фрагмент кода:

Var_A = 3 ; Var_B = Var_A ;
print(Var_A, Var_B)

В нем мы создали переменную с именем Var_A и записали в нее значение 3. Затем создали переменную с именем Var_B и скопировали в нее значение, хранящееся в переменной с именем Var_A. Так что теперь у нас есть два значения (пусть одинаковых, но два), хранящиеся в двух разных переменных. Проверить это можно, освободив первую переменную, Var_A, присвоением ей специального уникального значения nil:

Var_A = nil ; print(Var_B)
Еще один «летний» язык программирования. Часть 3
Рис. 5

Результат подтверждает предположение (рис. 5) – в переменной Var_B хранится значение 3.

А теперь вспомним, что мы говорили о таблицах как о специальном «существе» в Lua, и попробуем повторить этот пример. Первая переменная, хранящая ссылку на таблицу, у нас есть – ArD. Создадим вторую переменную, скажем, с именем DrA, и повторим «фокус»:

DrA = ArD ; ArD = nil ;
print(DrA)

В результате мы видим, что DrA содержит все те же примелькавшиеся цифры 0032AAE0 – все ту же ссылку на все ту же таблицу. Ни к какой новой сущности, ни к какому копированию значения этот пример не привел!

0 
 

Напечатать Отправить другу

Читайте также

 
 
IDC
Реклама

  •  Home  •  Рынок  •  ИТ-директор  •  CloudComputing  •  Hard  •  Soft  •  Сети  •  Безопасность  •  Наука  •  IoT