-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontents_ru.html
8825 lines (6936 loc) · 461 KB
/
contents_ru.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Lua 5.3 Руководство</TITLE>
<LINK REL="stylesheet" TYPE="text/css" HREF="css/lua.css">
<LINK REL="stylesheet" TYPE="text/css" HREF="css/manual.css">
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=utf-8">
</HEAD>
<link rel="stylesheet" href="styles/github.css">
<script src="highlight.pack.js"></script>
<script>
hljs.configure({
languages: ['lua']
});
hljs.initHighlightingOnLoad();
</script>
<BODY>
<H1>
<A HREF="index.html"><IMG SRC="images/logo.png" ALT="Lua"></A>
Lua 5.3 Руководство
</H1>
<DIV CLASS="menubar">
<A HREF="main.html#about">Lua</A>
· <A HREF="main.html#documentation">Документация</A>
</DIV>
<!-- ====================================================================== -->
<SMALL>
<P>by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes<br />
перевел Ведерников Николай, Лысьва.</P>
</SMALL>
<p>
<!-- $Id: manual.of,v 1.151 2015/06/10 21:08:57 roberto Exp $ -->
<h1>1 – <a name="1">Введение</a></h1>
<p>
Lua - язык программирования расширений, разработан для поддержки
общего процедурного программирования с возможностью описания данных.
Lua также предлагает хорошую поддержку объектно-ориентированного,
функционального и управляемого данными (data-driven) программирования.
Lua предлагается как мощный и лёгкий встраиваемый скриптовый язык
для любой программы, которая в этом нуждается.
Lua реализован как библиотека, написан на <em>чистом C</em>, общее подмножетво
стандартного C и C++.
<p>
Как язык расширений, Lua не имеет понятия "главной" программы:
он работает только как <em>встроенный</em> в основную программу клиент,
<em>встраивающая программа</em> называется <em>хост</em> (host).
Встраивающая программа может вызывать функции для запуска кусочков Lua кода,
может писать и читать Lua переменные,
может регистрировать C-функции чтобы вызывать их из Lua кода.
Через использование С-функций Lua может быть расширен для решения различных задач,
таким образом созданные адаптированные языки программирования имеют общую синтаксическую базу.
Дистрибутив Lua включает простую хост-программу <code>lua</code>,
которая использует библиотеку Lua для реализации полного независимого Lua интерпретатора,
для интерактивного или пакетного использования.
<p>
Lua бесплатное программное обеспечение и предоставляется безо всяких гарантий.
Официальный сайт <code>www.lua.org</code>.
<p>
Как и любое другое руководство, это руководство местами сухо.
Описание решений принятых в основе дизайна Lua есть на технических страницах официального сайта.
Детальное введение в программирование на Lua представлено в книге
Роберто Иерусалимского <em>Programming in Lua</em>.
<h1>2 – <a name="2">Базовые концепции</a></h1>
<p>
Этот раздел описывает базовые концепции языка.
<h2>2.1 – <a name="2.1">Значения и типы</a></h2>
<p>
Lua <em>динамически типизированный язык</em>.
Это означает, что значения не имеют типов; только значения.
Язык не имеет определений типов.
Все значения несут свой собственный тип.
<p>
Все значения в Lua <em>первоклассные</em>.
Это означает что все значения могут быть сохранены в переменных,
переданы как аргументы другим функциям, и возвращены как результаты.
<p>
В Lua существует восемь базовых типов:
<em>nil</em>, <em>boolean</em>, <em>number</em>,
<em>string</em>, <em>function</em>, <em>userdata</em>,
<em>thread</em> и <em>table</em>.
<p>
Тип <em>nil</em> (нуль) имеет одно единственное значение, <b>nil</b>,
его главное свойство это отличаться от любых других значений;
обычно это означает отсутствие используемого значения.
<p>
Тип <em>boolean</em> (логический) имеет два значения: <b>false</b> (ложь) и <b>true</b> (истина).
Оба <b>nil</b> и <b>false</b> означают false;
любое другое значение означает true.
<p>
Тип <em>number</em> (число) представляет целые
(integer) и вещественные (float) числа.
<p>
Тип <em>string</em> (строка) представляет неизменные последовательности байт.
Строки в Lua могут содержать любое 8-битное значение,
включая нули ('<code>\0</code>').
Также Lua противник кодировок;
никаких предположений о содержимом строки не делается.
<p>
Тип <em>number</em> использует два внутренних представления,
или два подтипа,
один называется <em>integer</em> (целое), второй <em>float</em> (число с плавающей запятой).
Lua имеет явные правила о том, когда какое представление использовать,
но при необходимости автоматически конвертирует значение между ними (см. <a href="#3.4.3">§3.4.3</a>).
Следовательно, в большистве случаев программист может игнорировать
разницу между целыми и реальными числами,
или получить полный контроль над представлением каждого числа.
Стандартный Lua использует 64-битные целые (integer) и вещественные числа двойной точности (double 64-bit),
но также возможно скомпилировать Lua так, чтобы использовались
32-битные целые и/или вещественные числа одинарной точности (float 32-bit).
Эта опция с 32 битами для целых и вещественных чисел особенно актуальна
для малых машин и встроенных систем.
(Смотри макрос <code>LUA_32BITS</code> в файле <code>luaconf.h</code>.)
<p>
Lua может вызывать и манипулировать функциями написанными на Lua и на С (см. <a href="#3.4.10">§3.4.10</a>).
Оба типа функций в Lua представлены типом <em>function</em> (функция).
<p>
Тип <em>userdata</em> (пользовательские данные) предназначен для хранения
произвольных С данных в Lua переменных.
Значение userdata представляет блок памяти (raw memory).
Существуют два типа пользовательских данных:
<em>full userdata</em> (полные пользовательские данные) -
объект с блоком памяти, которым управляет Lua,
и <em>light userdata</em> (лёгкие пользовательские данные) - простой С указатель.
Пользовательские данные не имеют предопределенных операторов в Lua,
кроме оператора присвоения и сравнения на идентичность.
Используя <em>метатаблицы</em>,
программист может определить операции для значений full userdata (см. <a href="#2.4">§2.4</a>).
Значения userdata не могут быть созданы или изменены в Lua, это возможно только через C API.
Это гарантирует целостность данных, которыми владеет хост-программа.
<p>
Тип <em>thread</em> (поток) представляет независимый поток выполнения
и используется для реализации сопрограмм (coroutine) (см. <a href="#2.6">§2.6</a>).
Lua потоки это не реальные потоки операционной системы.
Lua поддерживает сопрограммы на всех системах, даже на тех, где это не поддерживается операционной системой.
<p>
Тип <em>table</em> (таблица) реализует ассоциативные массивы,
это значит, что массив может быть проиндексирован не только числами,
но и любым Lua значением, кроме <b>nil</b> и NaN.
(<em>Not a Number</em> специальное значение для представления неопределенных и
непредставимых числовых результатов, таких как <code>0/0</code>.)
Таблицы могут быть <em>гетерогенными</em> (разнородными);
т.е. могут содержать значения всех типов (кроме <b>nil</b>).
Любой ключ со значением <b>nil</b> не считается частью таблицы.
И наоборот, любой ключ, не являющийся частью таблицы, имеет ассоциированное значение <b>nil</b>.
<p>
Таблицы единственный механизм структурирования данных в Lua;
они могут использоваться для представления обычных массивов, последовательностей,
таблиц символов, множеств, записей, графов, деревьев и т.п.
Для представления записей, Lua использует имена полей как индекс.
Язык поддерживает представление <code>a.name</code>, как синтаксическое украшение <code>a["name"]</code>.
Существуют различные пути создания таблиц в Lua
(см. <a href="#3.4.9">§3.4.9</a>).
<p>
Мы используем термин <em>последовательность</em> (sequence)
чтобы обозначить таблицу, где все ключи это натуральные числа {1..<em>n</em>} (1,2,3,...),
где <em>n</em> - длина последовательности (см. <a href="#3.4.7">§3.4.7</a>).
<p>
Как и индексы, значения полей в таблице могут быть любого типа.
В частности, т.к. функции это первоклассные значения,
поля таблицы могут содержать функции.
Такие таблицы также могут содержать <em>методы</em> (см. <a href="#3.4.11">§3.4.11</a>).
<p>
Индексирование в таблицах следует принципу "сырого" (raw) равенства в языке.
Выражения <code>a[i]</code> и <code>a[j]</code>
определяют один и тот же элемент таблицы,
если и только если <code>i</code> и <code>j</code> равны (raw equal)
(значит, равны без метаметодов).
В частности, вещественные числа (float) с целыми значениями
равны соответствующим целым (integer), т.е., <code>1.0 == 1</code>.
Во избежание неоднозначностей, любое реальное число с целым значением, которое испльзуется как ключ,
конвертируется в соответствующее ему целое число.
Например, если написать <code>a[2.0] = true</code>,
фактически в таблицу будет вставлен целочисленный (integer) ключ <code>2</code>.
С другой стороны, 2 and "<code>2</code>" разные Lua значения и следовательно обозначают
разные данные в таблице.
<p>
Таблицы, функции, потоки и пользовательские данные (userdata) - это <em>объекты</em>:
переменные фактически не <em>содержат</em> их значений, только <em>ссылки</em> на них.
Присвоение, передача параметров и возврат из функций
всегда манипулируют ссылками на эти значения;
эти операции не подразумевают никакого типа копирования.
<p>
Библиотечная функция <a href="#pdf-type"><code>type</code></a>
возвращает строку с названием переданного ей типа (см. <a href="#6.1">§6.1</a>).
<h2>2.2 – <a name="2.2">Окружения и глобальное окружение</a></h2>
<p>
Как будет описано в <a href="#3.2">§3.2</a> и <a href="#3.3.3">§3.3.3</a>,
любая ссылка на свободное имя
(т.е., имя не связанное ни с каким определением) <code>var</code>
синтаксически транслируется в <code>_ENV.var</code>.
Кроме того, каждый кусок (chunk) компилируется в области внешней локальной переменной,
называемой <code>_ENV</code> (см. <a href="#3.3.2">§3.3.2</a>),
таким образом <code>_ENV</code> само никогда не бывает свободным именем в куске.
<p>
Несмотря на существование этой внешней переменной <code>_ENV</code> и
трансляцию свободных имен,
<code>_ENV</code> полностью регулярное имя.
В частности, вы можете определить новые переменные и параметры с этим именем.
Каждая ссылка на свободное имя использует <code>_ENV</code>, которая видима
в данной точке программы, следуя обычным правилам видимости Lua (см. <a href="#3.5">§3.5</a>).
<p>
Любая таблица, используемая как значение переменной <code>_ENV</code>,
называется <em>окружение</em> (environment).
<p>
Lua хранит особое окружение, называемое <em>глобальное окружение</em>.
Это значение хранится по специальному индексу в С реестре (см. <a href="#4.5">§4.5</a>).
В Lua, глобальная переменная <a href="#pdf-_G"><code>_G</code></a> инициализируется тем же значением.
(<a href="#pdf-_G"><code>_G</code></a> никогда не используется непосредственно.)
<p>
Когда Lua загружает кусок (chunk),
по умолчанию его <code>_ENV</code> upvalue присваивается значение глобального окружения
(см. <a href="#pdf-load"><code>load</code></a>).
Следовательно, по умолчанию,
свободные имена в Lua коде ссылаются на элементы в глобальном окружении
(и, следовательно, они также называются <em>глобальными переменными</em>).
Кроме того, все стандартные библиотеки загружаются в глобальное окружение
и некоторые их функции действуют в этом окружении.
Вы можете использовать <a href="#pdf-load"><code>load</code></a> (или <a href="#pdf-loadfile"><code>loadfile</code></a>)
для загрузки куска с другим окружением.
(В C, вы загружаете кусок и затем изменяете его первое upvalue.)
<h2>2.3 – <a name="2.3">Обработка ошибок</a></h2>
<p>
Так как Lua встроенный язык расширений,
все Lua действия начинаются с C кода;
код в хостовой программе вызывает функцию в Lua библиотеке.
(При использовании автономного интерпретатора Lua,
программа <code>lua</code> выступает в качестве хоста.)
Всякий раз, когда происходит ошибка компиляции или выполнения куска Lua кода,
управление возвращается хостовой программе,
которая может предпринять соответствующие меры
(такие как печать сообщения об ошибке).
<p>
Lua код может явно сгенерировать ошибку, вызвав функцию
<a href="#pdf-error"><code>error</code></a>.
Если вы нуждаетесь в перехвате ошибок в Lua,
вы можете использовать <a href="#pdf-pcall"><code>pcall</code></a> или
<a href="#pdf-xpcall"><code>xpcall</code></a>
для вызова функции в <em>защищенном режиме</em>.
<p>
При каждой ошибке, создается
<em>объект ошибки</em> (также называемый <em>сообщением об ошибке</em>)
с информацией об ошибке.
Самостоятельно Lua генерирует только те ошибки, где объект ошибки содержит строку,
но программы могут генерировать ошибки с любым значением в объекте ошибки.
Объекты ошибки (исключения) пробрасываются вверх в Lua или в хост для обработки.
<p>
Когда вы используете <a href="#pdf-xpcall"><code>xpcall</code></a> или <a href="#lua_pcall"><code>lua_pcall</code></a>,
вы можете определить <em>обработчик сообщений</em>,
который будет вызываться в случае ошибок.
Эта функция вызывается с оригинальным сообщением об ошибке и
возвращает новое сообщение об ошибке.
Она вызывается до раскрутки стека,
так она сможет получить больше информации об ошибке,
например, проверяя стек и создавая историю стека (stack traceback).
Этот обработчик сообщений остается защищенным в защищенном вызове;
так, ошибка в обработчике сообщений лишь вызовет его снова.
Если этот цикл будет достаточно длинным,
Lua прервет его и вернет соответствующее сообщение.
<h2>2.4 – <a name="2.4">Метатаблицы и метаметоды</a></h2>
<p>
Каждое значение в Lua может иметь <em>метатаблицу</em>.
Эта <em>метатаблица</em> обычная Lua таблица,
которая определяет поведение оригинального значения
в определенных специальных операциях.
Вы можете изменять различные аспекты поведения
в операциях со значением, изменяя специфические поля в метатаблице.
Например, когда не цифровое значение является операндом в сложении,
Lua проверяет есть ли в его метатаблице поле "<code>__add</code>" с функцией.
И, если оно существует, Lua вызывает эту функцию для выполнения сложения.
<p>
Ключи в метатаблице это производные от имен <em>событий</em>;
соответствующие им значения называются <em>метаметоды</em>.
В предыдущем примере, событие - <code>"add"</code> (добавить)
и метаметод - функция, которая выполняет сложение.
<p>
Вы можете запросить метатаблицу любого значения, используя функцию
<a href="#pdf-getmetatable"><code>getmetatable</code></a>.
<p>
Вы можете заменить метатаблицу таблицы, используя <a href="#pdf-setmetatable"><code>setmetatable</code></a>.
Нельзя изменять метатаблицы других типов из Lua кода
(кроме, как используя библиотеку отладки (<a href="#6.10">§6.10</a>));
для этого вы должны использовать C API.
<p>
Таблицы и полные пользовательские данные (full userdata) имеют индивидуальные метатаблицы
(хотя таблицы и пользовательские данные могут совместно использовать свои метатаблицы).
Значения остальных типов используют одну метатаблицу на тип;
т.е, существует одна метатаблица для всех чисел, одна для всех строк и т.д.
По умолчанию, значения не имеют метатаблицу,
но строковая библиотека создает метатаблицу для строкового типа (см. <a href="#6.4">§6.4</a>).
<p>
Метатаблица контролирует, как объект ведет себя в арифметических и битовых операциях,
сравнениях при сортировке, конкатенации, определении длины, вызовах и индексировании.
Метатаблица также может определять функцию, которая будет вызвана
для таблицы или пользовательских данных при уничтожении сборщиком мусора
(<a href="#2.5">§2.5</a>).
<p>
Детальное описание событий, контролируемых метатаблицами, представлено ниже.
Каждая операция идентифицируется соответсвующим именем события.
Ключ для каждого события это строка начинающаяся с двух подчеркиваний, '<code>__</code>';
например, ключ для операции "add" строка "<code>__add</code>".
Имейте ввиду, что запросы метаметодов всегда прямые;
доступ к метаметоду не запускает других метаметодов
<p>
Для одноместных операторов (отрицание, длина и битовое отрицание),
метаметод вычисляется и вызывается с фиктивным вторым операндом,
равным первому.
Этот дополнительный операнд нужен лишь для упрощения реализации Lua,
и может быть убран в следующих версиях.
(Для большинства применений этот дополнительный операнд несущественнен.)
<ul>
<li><b>"add": </b>
<code>+</code> операция.
Если любой операнд при сложении не число
(и не строка, которую можно преобразовать в число),
Lua попробует вызвать метаметод.
Сначала, Lua проверит первый операнд (даже если он правильный).
Если этот операнд не определяет метаметод для события "<code>__add</code>",
Lua проверит второй операнд.
Если Lua найдет метаметод, он будет вызван с двумя операндами в качестве аргументов,
и результат вызова
(скорректированный до одного значения)
будет результатом операции.
Иначе будет сгенерирована ошибка.
</li>
<li><b>"sub": </b>
<code>-</code> операция (вычитание). Аналогично операции "add".
</li>
<li><b>"mul": </b>
<code>*</code> операция (умножение). Аналогично операции "add".
</li>
<li><b>"div": </b>
<code>/</code> операция (деление). Аналогично операции "add".
</li>
<li><b>"mod": </b>
<code>%</code> операция (остаток от деления). Аналогично операции "add".
</li>
<li><b>"pow": </b>
<code>^</code> операция (возведение в степень). Аналогично операции "add".
</li>
<li><b>"unm": </b>
<code>-</code> операция (одноместный минус). Аналогично операции "add".
</li>
<li><b>"idiv": </b>
<code>//</code> операция (целочисленное деление). Аналогично операции "add".
</li>
<li><b>"band": </b>
<code>&</code> операция (битовое И). Аналогично операции "add",
за исключением того, что Lua будет использовать метаметод, если любой из операндов
не целое и не значение приводимое к целому (см. <a href="#3.4.3">§3.4.3</a>).
</li>
<li><b>"bor": </b>
<code>|</code> операция (битовое ИЛИ). Аналогично операции "band".
</li>
<li><b>"bxor": </b>
<code>~</code> операция (битовое ИЛИ-НЕ). Аналогично операции "band".
</li>
<li><b>"bnot": </b>
<code>~</code> операция (битовое одноместное НЕ). Аналогично операции "band".
</li>
<li><b>"shl": </b>
<code><<</code> операция (битовый сдвиг влево). Аналогично операции "band".
</li>
<li><b>"shr": </b>
<code>>></code> операция (битовый сдвиг вправо). Аналогично операции "band".
</li>
<li><b>"concat": </b>
<code>..</code> операция (конкатенация). Аналогично операции "add",
за исключением того, что Lua будет использовать метаметод, если любой из операндов
не строка и не число (которое всегда приводимо к строке).
</li>
<li><b>"len": </b>
<code>#</code> операция (длина).
Если объект не строка, Lua попытается использовать этот метаметод;
Если метаметод определен, он будет вызван с объектом в качестве аргумента,
и результат вызова (обрезанный до одного значения)
будет использован как результат операции.
Если метаметод не определен и объект таблица, Lua использует
операцию длины таблицы (см. <a href="#3.4.7">§3.4.7</a>).
Иначе, Lua сгенерирует ошибку.
</li>
<li><b>"eq": </b>
<code>==</code> операция (равенство). Аналогично операции "add",
за исключением того, что Lua будет использовать метаметод,
только если оба сравниваемых значения таблицы или полные пользовательские данные
и они не примитивно равны.
Результат вызова всегда преобразуется к логическому (boolean).
</li>
<li><b>"lt": </b>
<code><</code> операция (меньше). Аналогично операции "add",
за исключением того, что Lua будет использовать метаметод,
только если оба сравниваемых значения не числа и не строки.
Результат вызова всегда преобразуется к логическому (boolean).
</li>
<li><b>"le": </b>
<code><=</code> операция (меньше или равно).
В отличие от других операций, операция "<=" может использовать два разных события.
Первое, Lua проверяет наличие метаметода "<code>__le</code>" в обоих операндах,
также как в операции "lt".
Если этот метаметод не найден, Lua попытается использовать событие "<code>__lt</code>",
предполагая, что <code>a <= b</code> эквивалентно <code>not (b < a)</code>.
Как и у других операторов сравнения, результат всегда логическое значение.
(Это использование события "<code>__lt</code>" может быть убрано в следующих версиях,
т.к. оно медленнее, чем реальный вызов метаметода "<code>__le</code>".)
</li>
<li><b>"index": </b>
индексированный доступ <code>table[key]</code>.
Это событие случается когда <code>table</code> не таблица или
когда <code>key</code> не существует в <code>table</code>.
Метаметод ищется в объекте <code>table</code>.
<p>
Несмотря на имя, метаметод для этого события может быть функцией или таблицей.
Если это функция, то она вызывается с <code>table</code> и <code>key</code> в качестве аргументов.
Если таблица, то конечный результат это результат индексирования этой таблицы с ключом <code>key</code>.
Это индексирование регулярное, не прямое, и оно также может вызывать срабатывание другого метаметода.
</li>
<li><b>"newindex": </b>
индексированное присваивание <code>table[key] = value</code>.
Как и событие "index", это событие случается когда <code>table</code> не таблица или
когда <code>key</code> не существует в <code>table</code>.
Метаметод ищется в объекте <code>table</code>.
<p>
Как и для индексированного доступа, метаметод для этого события может быть функцией или таблицей.
Если это функция, то она вызывается с <code>table</code>, <code>key</code>
и <code>value</code> в качестве аргументов.
Если таблица, Lua производит индексированное присваивание для этой таблицы с тем же ключом и значением.
Это присваивание регулярное, не прямое, и оно также может вызывать срабатывание другого метаметода.
<p>
Всякий раз, когда срабатывает метаметод "newindex",
Lua не выполняет примитивное присваивание.
(Если необходимо,
метаметод может самостоятельно вызвать <a href="#pdf-rawset"><code>rawset</code></a>
для выполнения присваивания.)
</li>
<li><b>"call": </b>
операция вызова <code>func(args)</code>.
Это событие случается когда Lua пытается вызвать значение, не являющееся функцией
(т.е., <code>func</code> это не функция).
Метаметод ищется в объекте <code>func</code>.
Если он существует, то он вызывается с <code>func</code> в качестве первого аргумента,
следом идут остальные аргументы из оригинального вызова (<code>args</code>).
</li>
</ul>
<p>
Хорошая практика, добавлять все необходимые метаметоды в таблицу
перед тем, как назначить её метатаблицей какого-то объекта.
В частности, метаметод "<code>__gc</code>" работает только если была соблюдена эта последовательность
(см. <a href="#2.5.1">§2.5.1</a>).
<h2>2.5 – <a name="2.5">Сборка мусора</a></h2>
<p>
Lua выполняет автоматическое управление памятью.
Это означает, что вы не должны беспокоиться о выделении памяти новым объектам
или об освобождении памяти, когда объекты больше не нужны.
Lua управляет памятью, запуская <em>сборщик мусора</em>
для сборки всех <em>мёртвых объектов</em>
(т.е., объектов более не доступных из Lua).
Вся память, используемая Lua, подлежит автоматическому управлению:
строки, таблицы, пользовательские данные, функции, потоки, внутренние структуры и т.д.
<p>
Lua реализует пошаговый отмечающий-и-очищающий сборщик.
Для контроля циклов очистки мусора используются два числа:
<em>пауза сборщика мусора</em> и
<em>множитель шагов сборщика мусора</em>.
Оба числа используют процентные пункты как единицы
(т.е., значение 100 означает внутреннее значение 1).
<p>
Пауза сборщика мусора контролирует, как долго сборщик ждет перед началом нового цикла.
Чем больше значение, тем менее агрессивен сборщик.
Значения меньше 100 означают, что сборщик не останавливается перед началом
нового цикла.
Значение 200 означает, что сборщик, перед тем как начать новый цикл,
ждет повышения использования общей памяти в два раза.
<p>
Множитель шагов сборщика мусора
контролирует относительную скорость сборщика по отношению к скорости выделения памяти.
Большие значения делают сборщик более агрессивным, но также
увеличивают размер каждого шага.
Вы не должны использовать значения меньше 100,
т.к. они сделают сборщик настолько медленным, что он никогда
не завершит цикл.
По умолчанию, используется значение 200,
которое означает, что сборщик выполняется в два раза быстрее
скорости выделения памяти.
<p>
Если вы установите множитель шагов очень большым
(больше чем 10% от максимального числа байт, которые может использовать программа),
сборщик поведет себя как останавливающий мир.
Если вы установите паузу 200,
сборщик будет вести себя как в старых версиях Lua,
производя полную очистку каждый раз, когда Lua удваивает использование памяти.
<p>
Вы можете изменять эти числа, вызывая <a href="#lua_gc"><code>lua_gc</code></a> в C
или <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> в Lua.
Вы также можете использовать эти функции для прямого контроля сборщика
(т.е., его остановки и перезапуска).
<h3>2.5.1 – <a name="2.5.1">Метаметоды сборки мусора</a></h3>
<p>
Вы можете установить метаметоды сборки мусора для таблиц и,
используя C API, для полных пользовательских данных (см. <a href="#2.4">§2.4</a>).
Эти метаметоды также называются <em>деструкторы</em> (finalizers).
Деструкторы позволяют координировать сборку мусора в Lua с
внешним управлением ресурсами
(таким как закрытие файлов, сетевый подключения, подключения к базам данных
или освобождение вашей памяти).
<p>
Для объекта (таблицы или пользовательских данных) чтобы быть уничтоженным при сборке мусора,
вы должны <em>отметить</em> его на уничтожение.
Вы отмечаете объект на уничтожение, когда устанавливаете для него метатаблицу,
содержащую поле "<code>__gc</code>".
Имейте ввиду, что если вы установите метатаблицу без поля <code>__gc</code>
и затем создадите это поле в метатаблице,
то объект не будет отмечен на уничтожение.
<p>
Когда отмеченный объект становится мусором,
он не уничтожается напрямую сборщиком мусора.
Вместо этого, Lua ложит его в список.
После завершения сборки, Lua проходит по этому списку.
Для каждого объекта в списке проверяется метаметод <code>__gc</code>:
если это функция, Lua вызывает её с объектом в качестве единственного аргумента;
если метаметод не функция, Lua просто игнорирует его.
<p>
В конце каждого цикла сборки мусора,
деструкторы объектов вызываются в порядке обратном
порядку их отметки на уничтожение;
т.е., первым деструктор будет вызван для последнего отмеченного на уничтожение объекта.
Выполнение каждого деструктора может произойти в любое время при выполнении основного кода.
<p>
Так как объект подлежащий уничтожению должен быть использован в деструкторе,
этот объект (и остальные объекты доступные через него)
должны быть <em>воскрешены</em> Lua.
Обычно, это воскрешение нерезидентно,
и память объекта освобождается при следующем цикле сборки мусора.
Тем не менее, если деструктор сохраняет объект в каком-то глобальном месте
(т.е. глобальной переменной), воскрешение постоянно.
Более того, если деструктор отмечает уничтожаемый объект для уничтожения снова,
его деструктор будет вызван снова в следующем цикле, где объект не доступен.
В любом случае, память объекта освобождается только в цикле сборки мусора, где
объект недоступен и не отмечен на уничтожение через деструктор.
<p>
Когда вы закрываете контекст (см. <a href="#lua_close"><code>lua_close</code></a>),
Lua вызывает деструкторы всех объектов отмеченных на уничтожение,
следуя порядку обратному порядку их отметки на уничтожение.
Если любой деструктор отмечает объекты для уничтожения в этой фазе,
эти отметки не имеют никакого эффекта.
<h3>2.5.2 – <a name="2.5.2">Слабые таблицы</a></h3>
<p>
<em>Слабая таблица</em> (weak table) - это таблица, элементы которой
это <em>слабые ссылки</em> (weak references).
Слабая ссылка игнорируется сборщиком мусора.
Другими словами,
если на объект существуют только слабые ссылки,
то объект будет уничтожен сборщиком мусора.
<p>
Слабая таблица может иметь слабые ключи, слабые значения или и то и другое.
Таблица со слабыми значениями позволяет уничтожать её значения,
но препятствует уничтожению её ключей.
Таблица со слабыми значениями и ключами позволяет уничтожать и ключи и значения.
В любом случае, если ключ или значение уничтожены, эта пара удаляется из таблицы.
Слабость таблицы контролируется полем <code>__mode</code> в её метатаблице.
Если поле <code>__mode</code> это строка содержащая символ '<code>k</code>',
в таблице слабые ключи.
Если поле <code>__mode</code> содержит '<code>v</code>',
в таблице слабые значения.
<p>
Таблица со слабыми ключами и сильными значениями
называется <em>эфемерной таблицей</em> (ephemeron table).
В эфемерной таблице, значение достижимо только если его ключ достижим.
В частности, если ссылка на ключ приходит через его значение, пара удаляется.
<p>
Любое изменение слабости таблицы будет иметь эффект только в следующем цикле сборки мусора.
В частности, если вы сменили слабый на сильный режим,
Lua может продолжить сбор некоторых элементов из этой таблицы,
пока изменения не будут иметь эффект.
<p>
Только объекты, имеющие явную конструкцию,
удаляются из слабых таблиц.
Значения, такие как числа и легкие C функции,
не являются субъектами для сборки мусора,
и следовательно не удаляются из слабых таблиц
(пока их ассоциированные значения не удалены).
Хотя строки субъекты для сборки мусора,
они не имеют явную конструкцию, и следовательно не удаляются из слабых таблиц.
<p>
Воскрешенные объекты
(т.е., объекты подлежащие уничтожению и объекты достпупные через них)
имеют специальное поведение в слабых таблицах.
Они удаляются из слабых значений перед запуском их деструкторов,
но удаляются из слабых ключей только в следующем цикле сборки,
после запуска их деструкторов, когда эти объекты действительно освобождены.
Это поведение позволяет деструктору получить доступ к свойствам,
ассоциированным с объектом через слабые таблицы.
<p>
Если слабая таблица среди воскрешенных объектов в цикле сборки,
она не может быть правильно очищена до следующего цикла сборки.
<h2>2.6 – <a name="2.6">Сопрограммы</a></h2>
<p>
Lua поддерживает сопрограммы,
так называемую <em>совместную многопоточность</em>.
Сопрограмма в Lua представляет независимый поток выполнения.
В отличе от потоков в многопоточных системах,
сопрограммма прерывает свое исполнение только явным вызовом функции yield (уступить).
<p>
Сопрограмма создается функцией <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>.
Единственный аргумент функции это главная функция сопрограммы.
Функция <code>create</code> только создает сопрограмму и возвращает её описатель
(объект типа <em>thread</em> - поток);
она не запускает сопрограмму.
<p>
Сопрограмма запускается вызовом <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
При первом вызове <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
в качестве первого аргумента передается поток,
возвращенный функцией <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
сопрограмма начинает свое исполнение с вызова своей главной функции.
Дополнительные аргументы, переданные в <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
передаются как аргументы этой функции.
После запуска сопрограммы, она выполняется пока не будет завершена или не <em>уступит</em> (yield).
<p>
Сопрограмма может завершить свое исполнение двумя путями:
нормально, когда её главная функция вернет управление
(явно или не явно, после последней инструкции);
и ненормально, если произойдет незащищенная ошибка.
В случае нормального завершения,
<a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> вернет <b>true</b> и
значения, возвращенные главной фунцией сопрограммы.
В случае ошибок, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> вернет <b>false</b>
и сообщение об ошибке.
<p>
Сопрограмма уступает, вызывая <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
Когда сопрограмма уступает,
соответсвующая <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> немедленно возвращает управление,
даже если уступка случилась внутри вложенной функции
(т.е., не в главной функции, а в функции прямо или косвенно вызванной из главной функции).
В случае уступки, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> также возвращает <b>true</b>
и значения, переданные в <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>.
В следующий раз, возобновление этой же сопрограммы
продолжает её выполнение с точки, где она уступила вызовом
<a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>,
возвращающим дополнительные аргументы, переданные в
<a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
<p>
Как и <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>,
функция <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> создает сопрограмму,
но вместо сопрограммы возвращает функцию, вызов которой возобновляет сопрограмму.
Аргументы, переданные этой функции, идут как дополнительные аргументы в
<a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>.
<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> возвращает все
значения полученные от <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
кроме первого (логический код ошибки).
В отличие от <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>,
<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> не перехватывает ошибки;
все ошибки передаются вызывающей стороне.
<p>
Для примера работы сопрограммы, рассмотрите следующий код:
<pre><code>
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))
</code></pre><p>
Запустив его, вы получите следующий результат:
<pre><code>
co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine
</code></pre>
<p>
Вы также можете создавать и манипулировать сопрограммами через C API:
см. функции <a href="#lua_newthread"><code>lua_newthread</code></a>, <a href="#lua_resume"><code>lua_resume</code></a>
и <a href="#lua_yield"><code>lua_yield</code></a>.
<h1>3 – <a name="3">Язык</a></h1>
<p>
Этот раздел описывает лексику, синтаксис и семантику Lua.
Другими словами, этот раздел описывает какие лексемы (tokens) правильны,
как они могут быть скомбинированы, и что их комбинации означают.
<p>
Языковые конструкции будут объясняться используя обычную расширенную БНФ нотацию,
в которой {<em>a</em>} означает 0 или больше <em>a</em>, и
[<em>a</em>] означает опциональную <em>a</em>.
Нетерминалы показаны как non-terminal,
ключевые слова показаны как <b>kword</b>,
и другие терминальные символы показаны как ‘<b>=</b>’.
Полный синтасис Lua описан в <a href="#9">§9</a> в конце руководства.
<h2>3.1 – <a name="3.1">Лексические соглашения</a></h2>
<p>
Lua - это язык свободной формы.
Он игнорирует пробелы (включая переходы на новую строку) и комментарии
между лексическими элементами, кроме разделителей между именами и ключевыми словами.
<p>
<em>Имена</em>
(также называемые <em>идентификаторами</em>)
в Lua могут быть любой строкой из букв, цифр и подчеркиваний,
не начинающейся с цифры.
Идентификаторы используются для именования значений, полей таблиц и меток (labels).
<p>
Следующие <em>ключевые слова</em> зарезервированы
и не могут использоваться как имена:
<pre><code>
and break do else elseif end
false for function goto if in
local nil not or repeat return
then true until while
</code></pre>
<p>
Язык Lua чувствителен к регистру символов:
<code>and</code> - зарезервированное слово, но <code>And</code> и <code>AND</code>
- два разных, допустимых имени.
Как соглашение, программы должны избегать создания имен,
которые начинаются с подчеркивания и следующими за ним одной или несколькими
прописными буквами (например, <a href="#pdf-_VERSION"><code>_VERSION</code></a>).
<p>
Следующие строки разделяют другие лексемы:
<pre><code>
+ - * / % ^ #
& ~ | << >> //
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ...
</code></pre>
<p>
<em>Литеральные строки</em>
могут быть ограничены сочетающимися одинарными или двойными кавычками,
и могут содержать С-подобные управляющие последовательности:
'<code>\a</code>' (bell),
'<code>\b</code>' (backspace),
'<code>\f</code>' (form feed),
'<code>\n</code>' (newline),
'<code>\r</code>' (carriage return),
'<code>\t</code>' (horizontal tab),
'<code>\v</code>' (vertical tab),
'<code>\\</code>' (backslash),
'<code>\"</code>' (двойная кавычка)
и '<code>\'</code>' (апостроф [одинарная кавычка]).
Обратный слеш, сопровождаемый реальным переходом на новую строку (newline),
формирует переход строки (newline) в строке (string).
Управляющая последовательность '<code>\z</code>' пропускает следующий за ней диапазон
пробелов, включая переходы строки;
это особенно полезно, чтобы разбить и отступить длинную литеральную строку
на несколько линий без добавления переводов строки и пробелов
в содержимое строки.
<p>
Строки в Lua могут содержать любое 8-битное значение, влючая встроенные нули,
которые могут быть записаны как '<code>\0</code>'.
Более того, возможно описать любой байт в литеральной строке его числовым значением.
Это может быть сделано с помощью управляющей последовательности <code>\x<em>XX</em></code>,
где <em>XX</em> - это пара шестнадцатиричных цифр,
или с помощью <code>\<em>ddd</em></code>,
где <em>ddd</em> - последовательность до трех десятичных цифр.
(Обратите внимание, что если десятичная управляющая последовательность сопровождается цифрой,
то она должна содержать ровно три цифры.)
<p>
Unicode-символ в кодировке UTF-8
может быть вставлен в литеральную строку
с помощью последовательности <code>\u{<em>XXX</em>}</code>
(обратите внимание на обязательные фигурные скобки),
где <em>XXX</em> - это одна или больше шестнадцатиричных цифр
описывающих код символа.
<p>
Литеральные строки также могут быть определены используя <em>длинные скобки</em>.
Мы определяем <em>открывающую длинную скобку уровня <em>n</em></em>, как открывающую
квадратную скобку, следующие за ней <em>n</em> знаков = и ещё одну открывающую квадратную скобку.
Так, открывающая длинная скобка уровня 0 запишется так: <code>[[</code>,
для уровня 1 - <code>[=[</code>, и так далее.
<em>Закрывающая длинная скобка</em> определяется аналогично;
например,
закрывающая длинная скобка уровня 4 запишется так: <code>]====]</code>.
<em>Длинный литерал</em> начинается с открывающей длинной скобки любого уровня
и завершается на первой закрывающей длинной скобке того же уровня.
Это позволяет содержать любой текст, кроме закрывающей скобки того же уровня.
Литералы в такой скобочной форме могут занимать несколько линий (строк),
управляющие последовательности в таких строках не работают,
длинные скобки других уровней игнорируются.
Любой вид последовательности завершения строки
(\r, \n, \r\n или \n\r) конвертируется в простой перевод строки \n.
<p>
Любой байт в литеральной строке не подвержен влиянию правил своего представления.
Тем не менее, Lua открывает файлы для парсинга в текстовом режиме,
и функции системы могут иметь проблемы с некоторыми управляющими символами.
Поэтому, для безопасного представления не текстовых данных в строке,
следует использовать управляющие последовательности.
<p>
Для удобства,
когда открывается длинная скобка с непосредственным переводом строки за ней,
перевод строки не включается в результирующую строку.
Например, в системе использующей ASCII
(в которой '<code>a</code>' кодируется как 97,
newline кодируется как 10 и '<code>1</code>' кодируется как 49),
пять литеральных строк ниже кодируют одинаковые строки:
<pre><code>
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]
</code></pre>
<p>
<em>Числовая константа</em> (или <em>цифра</em>)
может быть записана с опциональной дробной частью
и опциональной десятичной экспонентой,
обозначенной буквой '<code>e</code>' или '<code>E</code>'.
Lua также поддерживает шестнадцатиричные константы,
которые начинаются с <code>0x</code> или <code>0X</code>.
Шестнадцатиричные константы также допускают использование дробной части
и бинарной экспоненты,
обозначеной буквой '<code>p</code>' или '<code>P</code>'.
Цифровая константа с разделительной точкой или экспонентой означает вещественное число;
иначе она означает целое.
Примеры допустимых целых чисел:
<pre><code>
3 345 0xff 0xBEBADA
</code></pre><p>
Примеры допустимых вещественных чисел:
<pre><code>
3.0 3.1416 314.16e-2 0.31416E1 34e1
0x0.1E 0xA23p-4 0X1.921FB54442D18P+1
</code></pre>
<p>
<em>Комментарии</em> начинаются с двойного тире (<code>--</code>)
в любом месте за пределами литеральной строки.
Если текст, непосредственно следующий за <code>--</code>, не открывающая длинная скобка,
то это <em>короткий комментарий</em>, который продолжается до конца строки.
Иначе, это <em>длинный комментарий</em>,
который продолжается до соответствующей закрывающей длинной скобки.
Длинные комментарии часто используются для временного отключения кода.
<h2>3.2 – <a name="3.2">Переменные</a></h2>
<p>
Переменные - это место где хранятся значения.
Существует три вида переменных:
глобальные переменные, локальные переменные и поля таблиц.