Extension:Scribunto/Lua reference manual/vi

Giới thiệu
Cẩm nang này cung cấp tài liệu về Lua theo cách sử dụng trong MediaWiki qua phần mở rộng Scribunto. Một số phần bắt nguồn từ cẩm nang tra cứu Lua 5.1, cẩm nang này được phát hành theo một giấy phép kiểu MIT.

Cẩm nang dẫn xuất này cũng có thể được sao chép theo các điều kiện của cùng giấy phép.

Bắt đầu
Trên một wiki chạy MediaWiki có kích hoạt Lua, hãy tạo ra trang mới có tên bắt đầu với “Module:”, thí dụ “Module:Xôi gấc”. Hãy sao chép văn bản sau vào mô đun mới:

Hãy lưu nội dung đó. Tại một trang khác (không phải mô đun), viết:

Thay thế “Xôi gấc” bằng tên gọi của mô đun. Đoạn mã này sẽ gọi hàm “hello” được xuất phát từ mô đun và sẽ được tự động thay thế bằng văn bản mà hàm  cho ra, tức “Xin chào thế giới!” trong thí dụ này.

Vì cú pháp bình thường để định rõ hàm không cho phép bỏ dấu, bạn cũng có thể sử dụng cú pháp sau để định rõ một hàm có tên tiếng Việt:

Và gọi hàm dùng đoạn mã sau:

Khuyến khích bạn gọi đến mã nguồn Lua trong bản mẫu thay vì trang nội dung, để cho các trang nội dung chỉ cần gọi bản mẫu với cú pháp bản mẫu bình thường, không cần phân biệt Lua và mã wiki. Kiểu này cũng tránh đưa cú pháp phức tạp vào không gian tên nội dung của wiki.

Tài liệu mô đun
Scribunto cho phép cung cấp tài liệu về mô đun dùng trang con trong không gian tên Module. Theo mặc định, trang con là “/tài liệu” và được hiển thị ở trên mã nguồn tại trang mô đun. Thí dụ tài liệu về “Module:Xôi gấc” được viết tại “Module:Xôi gấc/tài liệu”.

Có thể cấu hình hệ thống này dùng các thông điệp trong không gian tên MediaWiki được liệt kê ở dưới:
 * scribunto-doc-subpage-name: Đặt tên của trang con tài liệu. Các trang con với tên này được phân tích như mã wiki, thay vì mã nguồn Lua, và không gọi được dùng cú pháp . Mặc định là “tài liệu”.
 * scribunto-doc-subpage-does-not-exist: Thông điệp được hiển thị khi trang con tài liệu không tồn tại. Tên trang con được cung cấp qua tham số . Mặc định là lời giải thích đơn giản in xiên.
 * scribunto-doc-subpage-show: Thông điệp được hiển thị khi trang con tài liệu có tồn tại. Tên trang con được cung cấp qua tham số . Mặc định là nhúng trang con tài liệu.
 * scribunto-doc-subpage-header: Đầu đề được hiển thị khi xem trang con tài liệu riêng. Tên mô đun được cung cấp qua tham số . Thông điệp mặc định là lời giải thích đơn giản in đậm.

Lưu ý không thể xếp các mô đun trực tiếp vào thể loại hoặc đặt liên kết liên wiki trực tiếp vào mô đun. Tuy nhiên, bạn có thể đưa các thể loại và liên kết này vào trang con tài liệu ở trong khối thẻ, khối này chỉ hiển thị khi được tự động nhúng vào trang mô đun.

Các dấu hiệu
Tên gọi (còn được gọi định danh) trong Lua là bất cứ loạt chữ tiếng Anh, con số, và dấu gạch dưới, miễn là không bắt đầu với con số. Lua phân biệt chữ hoa/thường trong các tên gọi: “foo”, “Foo”, và “FOO” đều khác nhau.

Các từ khóa sau được bảo lưu và không được phép sử dụng làm tên gọi:  Các tên gọi bắt đầu với dấu gạch dưới và một loạt chữ hoa dẫn sau được bảo lưu để Lua dùng làm biến số toàn cầu.
 * and
 * break
 * do
 * else
 * elseif
 * end
 * false
 * for
 * function
 * if
 * in
 * local
 * nil
 * not
 * or
 * repeat
 * return
 * then
 * true
 * until
 * while

Các dấu hiệu khác là: 
 * &#x25;
 * &#x3a;
 * &#x3b;
 * ]
 * }
 * &#x3a;
 * &#x3b;
 * ]
 * }
 * &#x3a;
 * &#x3b;
 * ]
 * }
 * &#x3b;
 * ]
 * }
 * ]
 * }
 * ]
 * }
 * ]
 * }
 * }
 * }
 * }

Chú thích
Một lời chú thích bắt đầu với  ở bất cứ phần nào bên ngoài chuỗi. Nếu ngay đằng sau  có dấu ngoặc dài bên trái, lời chú thích tiếp tục cho đến dấu ngoặc dài bên phải; nếu không, lời chú thích tiếp tục cho đến cuối dòng hiện tại.

Kiểu dữ liệu
Lua là một ngôn ngữ tạo kiểu động, có nghĩa rằng các biến số và đối số hàm không có kiểu, chỉ có các giá trị được chỉ định. Mọi giá trị có kiểu.

Lua có tám kiểu dữ liệu cơ bản; trong số này chỉ có sáu được sử dụng đối với phần mở rộng Scribunto. Hàm  cho ra kiểu của một giá trị.

Hàm  chuyển đổi một giá trị thành chuỗi. Hàm  chuyển đổi một giá trị thành số nếu có thể; nếu không thì cho ra vô-giá-trị. Không có hàm đặc biệt để chuyển đổi một giá trị thành các kiểu dữ liệu kia.

Các số được tự động chuyển đổi thành chuỗi khi được sử dụng như một chuỗi, chẳng hạn khi là một toán tử của phép nối chuỗi. Các chuỗi được  chấp nhận được tự động chuyển đổi thành số khi được sử dụng làm toán tử của một phép tính số học. Ở những chỗ cần giá trị luận lý,  và   là sai, còn   và bất cứ giá trị khác là thực.

Vô-giá-trị (nil)
Kiểu dữ liệu của  là vô-giá-trị (nil). Không có thể sử dụng vô-giá-trị là một chìa khóa trong bảng, và một chìa khóa không được chỉ định là bằng với một chìa khóa được chỉ định vô-giá-trị.

Vô-giá-trị được chuyển đổi thành chuỗi là “nil”. Vô-giá-trị được chuyển đổi thành giá trị luận lý là giá trị sai.

Luận lý (boolean)
Các giá trị luận lý (giá trị Boole, boolean) là  (thực) và   (sai).

được chuyển đổi thành chuỗi là “true”, còn  là “false”. Không giống nhiều ngôn ngữ khác, Lua không cho phép chuyển đổi giá trị luận lý trực tiếp thành số. Hơn nữa, không giống nhiều ngôn ngữ, chỉ có giá trị sai và vô-giá-trị được coi là sai đối với luận lý; số 0 và chuỗi rỗng đều được coi là thực.

Chuỗi (string)
Các chuỗi Lua được coi là loạt các byte có 8 bit; ứng dụng có trách nhiệm phải giải bảng mã.

Các chuỗi trực tiếp được phân cách bằng dấu ngoặc kép đơn hoặc đúp ( hoặc  ); giống JavaScript và khác với PHP, Lua không phân biệt dấu ngoặc kép đơn với dấu ngoặc kép đúp. Các trình tự thoát sau được chấp nhận:  (chuông),   (xóa trái),   (tiếp mẫu),   (dòng mới),   (về đầu dòng),   (lập bảng ngang),   (lập bảng đứng),   (chéo ngược),   (ngoặc kép đúp), và   (ngoặc kép đơn). Để đưa dòng mới trực tiếp vào chuỗi, chèn dấu chéo ngược đằng trước dòng mới. Để định rõ ký tự theo giá trị byte, sử dụng trình tự thoát, với ddd là giá trị thập phân của byte từ 0 đến 255. Để chèn ký tự Unicode dùng các trình tự thoát, phải định rõ các byte riêng theo bảng mã UTF-8; nhập các ký tự Unicode trực tiếp đáng lẽ tiện hơn.

Có thể định rõ các chuỗi trực tiếp dài dùng khối dấu ngoặc dài. Dấu ngoặc dài bên trái có hai dấu ngoặc vuông bên trái liền nhau hoặc bất cứ số dấu bằng ở giữa hai dấu ngoặc vuông này, chẳng hạn   hoặc. Dấu ngoặc dài bên trái phải có dấu ngoặc dài bên phải tương ứng để đóng khối, chẳng hạn,  , hoặc. Trong các chuỗi sử dụng dấu ngoặc dài, các trình tự thoát không có ý nghĩa đặc biệt được miêu tả ở trên. Một dòng mới ở đầu chuỗi trực tiếp, ngay đằng sau dấu ngoặc dài bên trái, không được bao gồm trong chuỗi.

Lưu ý rằng bất cứ mọi chuỗi là thực khi chuyển đổi thành giá trị luận lý. (Điều này khác với phần nhiều ngôn ngữ kịch bản khác đánh giá chuỗi rỗng là sai.

Số (number)
Lua chỉ có một kiểu số, kiểu này được lưu giữ nội bộ theo định dạng số thực dấu phẩy động có độ chính xác kép. Theo định dạng này, các số nguyên từ &minus;9.007.199.254.740.992 đến 9.007.199.254.740.992 có thể được lưu giữ chính xác, trong khi các số cao hoặc thấp hơn chịu lỗi do làm tròn.

Các số trực tiếp có dấu chấm là dấu thập phân và không có dấu phân cách hàng ngàn, chẳng hạn   (tức 123.456,78). Có thể viết số theo ký hiệu E không có khoảng cách, chẳng hạn  (tức 1,23&times;10&minus;10),   (123,45&times;1020), hoặc   (1,23&times;105). Cũng có thể viết số nguyên theo ký hiệu thập lục phân với tiền tố, chẳng hạn   (tức 58).

Tuy NaN, dương vô cực, và âm vô cực được lưu trữ và xử lý chính xác, Lua không có cách viết trực tiếp các số lượng này. Hằng số, cũng như phép chia cho không (chẳng hạn  ), có giá trị dương vô cực, và NaN được tính dễ dàng qua phép chia.

Lưu ý rằng tất cả các số là thực khi chuyển đổi thành giá trị luận lý. Điều này khác với phần nhiều ngôn ngữ khác cho 0 là sai. Khi được chuyển đổi thành chuỗi, các số hữu hạn được trình bày dạng thập phân, có thể theo ký hiệu E. NaN được trình bày là “nan” hoặc “-nan”, và vô cực là “inf” hoặc “-inf”.

Bảng (table)
Các bảng trong Lua là mảng kết hợp (associative array), giống như mảng trong PHP và đối tượng trong JavaScript.

Các bảng được tạo bằng dấu ngoặc xoắn. Bảng rỗng là. Để đưa các giá trị vào các trường vào lúc tạo bảng, định rõ các trường trong danh sách được phân tách bằng dấu phẩy và/hoặc dấu chấm phẩy ở giữa các dấu ngoặc xoắn. Có vài cách định rõ các trường:
 * sử dụng giá trị (ban đầu) của bieuThuc1 là chìa khóa và giá trị (ban đầu) của bieuThuc2 là giá trị.
 * tương đương với
 * tương tự với, với i là một số nguyên bắt đầu từ 1 và mỗi định rõ trường kiểu này tăng lên một. Nếu đây là định rõ trường cuối cùng và biểu thức có hơn một giá trị, tất cả các giá trị được sử dụng; nếu không, chỉ có giá trị đầu tiên được giữ.

Các trường bảng được truy cập dùng cú pháp dấu ngoặc kép, chẳng hạn. Nếu một chìa khóa chuỗi cũng là tên gọi hợp lệ, có thể truy cập nó qua cú pháp dấu chấm, chẳng hạn  tương đương với. Gọi giá trị hàm của một trường bảng thì có thể sử dụng cú pháp dấu hai chấm, chẳng hạn  tương đương với.

Dãy là bảng có giá trị (không phải vô-giá-trị) cho các số nguyên dương từ 1 đến N và không có giá trị (có vô-giá-trị) cho các số nguyên dương hơn N. Nhiều hàm Lua chỉ sử dụng các dãy và bỏ qua các chìa khóa không phải số nguyên dương, chẳng hạn 0 hoặc &minus;2,5.

Tuy nhiên, khác với PHP và JavaScript, có thể sử dụng bất cứ giá trị nào, trừ vô-giá-trị và NaN, làm chìa khóa, và chìa khóa không được chuyển đổi kiểu. Các thí dụ sau đều hợp lệ và khác nhau:

Có thể sử dụng bất cứ giá trị trừ vô-giá-trị làm giá trị trong bảng. Đưa vô-giá-trị vào một trường bảng là tương đương với việc xóa chìa khóa khỏi bảng, và vô-giá-trị là kết quả truy cập một chìa khóa không được chỉ định trong bảng.

Lưu ý rằng các bảng không bao giờ được sao chép ngầm trong Lua; nếu một bảng được cho vào hàm qua đối số và hàm thay đổi những chìa khóa hoặc giá trị trong bảng, bảng gốc trong đoạn mã gọi hàm sẽ cũng được thay đổi.

Một bảng được chuyển đổi thành chuỗi thường là chuỗi “table”, nhưng có thể ghi đè kết quả này bằng cách định rõ siêu phương thức. Ngay cả bảng rỗng là thực khi được chuyển đổi thành giá trị luận lý.

Hàm (function)
Các hàm trong Lua là giá trị hạng nhất (first-class value): có thể tạo vô danh, cho vào hàm qua tham số, chỉ định cho biến số, v.v.

Hàm được tạo dùng từ khóa  và được gọi dùng dấu ngoặc đơn. Có sẵn cú pháp đặc biệt để định rõ các hàm có tên, hàm địa phương, và hàm làm phương thức của bảng. Xem các chi tiết trong các phần “Lời khai báo hàm” và “Lời gọi hàm” ở dưới.

Các hàm Lua là hàm đóng (closure), tức là nó giữ một tham chiếu đến phạm vi khai báo nó và có thể truy cập và thay đổi các biến số trong phạm vi đó.

Tương tự với bảng, nếu một hàm được chỉ định cho biến số khác hoặc cho vào hàm khác qua tham số, nó vẫn tương đương với “đối tượng hàm” ban đầu.

Hàm được chuyển đổi thành chuỗi là chuỗi “function”.

Các kiểu không hỗ trợ
Kiểu dữ liệu người dùng (userdata) chứa các giá trị mờ đục dành cho những phần mở rộng Lua được viết trong ngôn ngữ khác, chẳng hạn có thể sử dụng dữ liệu người dùng để chứa con trỏ hoặc cấu trúc struct C. Vì nhiều môi trường host không cho phép chạy trình biên dịch tùy biến, Scribunto không cho phép sử dụng các phần mở rộng.

Kiểu luồng (thread) đại diện cho các đặc tả thường trình phụ (coroutine handle), nhưng các thường trình phụ không hoạt động trong hộp cát của Scribunto.

Siêu bảng
Mọi bảng có thể có bảng đính kèm gọi là siêu bảng (metatable). Các trường trong siêu bảng được một số phép tính và hàm sử dụng để định rõ cách xử lý khác hoặc dự trữ cho bảng. Có thể truy cập siêu bảng của một bảng qua hàm  và đặt siêu bảng dùng hàm.

Khi truy cập siêu hàm trong trường siêu bảng, giống như thể trường siêu bảng được truy cập qua.

Các trường siêu bảng ảnh hưởng đến chính bảng là:
 * __index : Được sử dụng khi việc truy cập trường bảng dùng  sẽ cho ra vô-giá-trị. Nếu giá trị của trường này là bảng, việc truy cập được lặp lại trong bảng đó, chẳng hạn   (có thể gọi cho   của siêu bảng của bảng đó). Nếu giá trị của trường này là hàm, hàm sẽ được gọi như  . Hàm   đi vòng siêu phương thức này.
 * __newindex : Được sử dụng khi chỉ định chìa khóa của bảng dùng  với   cho ra vô-giá-trị. Nếu giá trị của trường là bảng, việc chỉ định được lặp lại trong bảng đó, chẳng hạn   (có thể gọi cho   của siêu bảng của bảng đó). Nếu giá trị của trường là hàm, hàm sẽ được gọi như  . Hàm   đi vòng siêu phương thức này.
 * __call : Được sử dụng khi gọi hàm trong bảng dùng cú pháp gọi hàm, tức . Giá trị phải là hàm, hàm được gọi giống như.
 * __mode : Được sử dụng để tạo bảng chứa các tham chiếu yếu. Giá trị phải là chuỗi. Theo mặc định, bất cứ giá trị được sử dụng như chìa khóa hoặc giá trị trong bảng sẽ không được dọn rác (garbage collected). Nhưng nếu siêu trường này có chữ “k”, các chìa khóa có thể được dọn rác lúc không còn tham chiếu mạnh, và nếu siêu trường này có chữ “v” thì các giá trị có thể được dọn rác. Trường cả hai trường hợp, cả chìa khóa và giá trị tương ứng đều được gỡ khỏi bảng. Lưu ý rằng cách xử lý không được định rõ nếu trường này bị thay đổi sau khi bảng này được sử dụng như siêu bảng.

Các trường siêu bảng khác bao gồm:
 * __add
 * __sub
 * __mul
 * __div
 * __mod
 * __pow
 * __unm
 * __concat
 * __eq
 * __lt
 * __le
 * __pairs
 * __ipairs
 * __metatable
 * __tostring

Lưu ý: Trong Lua, tất cả các chuỗi cũng nằm trong một siêu bảng, trong siêu bảng này  chỉ đến bảng. Siêu bảng này không truy cập được trong Scribunto, và bảng  được tham chiếu cũng không truy cập được; mô đun chỉ có thể truy cập một bản sao của bảng chuỗi.

Biến số
Biến số là đồ đựng giá trị. Lua có ba loại biến số: biến số toàn cầu, biến số địa phương, và trường bảng.

Một tên gọi đại diện cho một biến số toàn cầu hoặc địa phương (hoặc một tham số hàm, nó chỉ là một loại biến số địa phương). Biến số được cho là toàn cầu nếu không được khai báo rõ ràng là biến số địa phương dùng từ khóa. bất cứ biến số không được chỉ định giá trị là vô-giá-trị.

Các biến số toàn cầu được lưu trong bảng Lua chuẩn được gọi là môi trường (environment); bảng này thường có sẵn qua biến số toàn cầu. Có thể đặt một siêu bảng cho bảng biến số toàn cầu này; các siêu phương thức  và   sẽ được gọi để truy cập hoặc chỉ đinh cho các biến số toàn cầu, không khác biệt với việc truy cập hoặc chỉ định cho trường trong bất cứ bảng khác.

Có thể truy cập môi trường của hàm qua  và thay đổi nó dùng hàm. Trong Scribunto, các hàm này bị hạn chế chặt chẽ hoặc không có sẵn.

Các biến số địa phương có phạm vi từ vựng (lexical scope); xem chi tiết trong phần “Lời khai báo biến số địa phương”.

Biểu thức
Biểu thức là gì đó có giá trị: các giá trị trực tiếp (số, chuỗi,,  ,  ), lệnh khai báo hàm vô danh, lệnh tạo bảng, tham chiếu biến số, lời gọi hàm, biểu thức tham lượng động (vararg), biểu thức để trong ngoặc đơn, phép tính đơn phân có toán tử là biểu thức, và biểu thức được phép tính nhị phân liên kết.

Phần nhiều biểu thức có một giá trị, nhưng các lời gọi hàm và biểu thức tham lượng động có thể có bất cứ bao nhiêu giá trị. Một lời gọi hàm hoặc biểu thức tham lượng động để trong ngoặc đơn loại bỏ các giá trị chỉ còn gia trị đầu tiên.

Danh sách biểu thức là danh sách biểu thức phân tách bởi dấu phẩy. Tất cả các biểu thức trừ biểu thức cuối cùng được thu lại thành một giá trị (bằng cách bỏ qua các giá trị còn dư hoặc sử dụng vô-giá-trị nếu biểu thức không có giá trị); các giá trị của danh sách biểu thức sẽ là tất cả các giá trị của biểu thức cuối.

Phép tính số học
Lua hỗ trợ các phép tính thông dụng: cộng, trừ, nhân, chia, mô đun, lũy thừa, và phủ định.

Nếu tất cả các toán tử là số hoặc chuỗi mà  có thể chuyển đổi thành số (không phải vô-giá-trị), các phép tính có ý nghĩa bình thường.

Nếu một toán tử là bảng có siêu phương thức hợp lý, siêu phương thức được gọi.

Phép tính quan hệ
Các phép tính quan hệ trong Lua là,  ,  ,  ,  , và. Kết quả của phép tính quan hệ luôn là giá trị luận lý (thực hay sai).

Phép tương đương ban đầu so sánh kiểu của các toán tử; nếu các kiểu khác nhau, kết quả là sai. Sau đó nó so sánh các giá trị: vô-giá-trị, luận lý, số, và chuỗi cũng được so sánh như vậy. Các hàm tương đương với nhau nếu các hàm chỉ đến cùng đối tượng hàm:  có giá trị sai vì hai hàm vô danh khác nhau được so sánh. Các bảng cũng được so sánh như vậy, nhưng có thể thay đổi cách đánh giá này bằng cách định rõ siêu phương thức.

Phép bất tương đương là phép phủ định phép tương đương.

Đối với các phép tính sắp xếp, nếu cả hai toán tử đều là số hoặc cả hai đều là chuỗi, các toán tử được so sánh trực tiếp. Sau đó, các siêu phương thức được gọi: Nếu các siêu phương phép hợp lý không được định rõ, phép tính gây lỗi.
 * gọi
 * gọi  nếu có sẵn, hoặc nếu   có sẵn thì phép tính này tương đương với
 * tương đương với
 * tương đương với

Phép tính lôgic
Các phép tính lôgic là  (và),   (hoặc), và   (phủ định). Các phép tính này đều có định nghĩa chuẩn rằng vô-giá-trị và  là sai còn bất cứ giá trị khác là thực.

Đối với, nếu toán tử bên trái là sai thì nó là kết quả và toán tử bên phải không được đánh giá; nếu toán tử bên trái là thực thì toán tử bên phải là kết quả.

Đối với, nếu toán tử bên trái là thực thì nó là kết quả và toán tử bên phải không được đánh giá; nếu toán tử bên trái là sai thì toán tử bên phải là kết quả.

Đối với, kết quả luôn là thực hay sai.

Lưu ý rằng  và   có tính đoản mạch. Thí dụ,  chỉ gọi   nếu   cho ra sau hoặc vô-giá-trị là giá trị đầu tiên.

Phép tính nối
Phép tính nối là hai dấu chấm, chẳng hạn. Nếu cả hai toán tử đều là số hoặc chuỗi, các toán tử được chuyển đổi thành chuỗi và nối liền với nhau. Nếu không và siêu phương thức  được định rõ, siêu phương thức này được gọi. Nếu không, phép tính gây lỗi.

Lưu ý rằng các chuỗi Lua không biến đổi và Lua không có chức năng “xây dựng chuỗi”, thành thử một vòng lặp  nhiều lần phải tạo một chuỗi mới mỗi vòng và cuối cùng dọn rác các chuỗi cũ không còn sử dụng. Nếu nhiều chuỗi cần được nối liền với nhau, có lẽ nên sử dụng  hoặc chèn tất cả các chuỗi vào dãy và nối liền dùng table.concat sau cùng để nhanh hơn.

Phép tính độ dài
Phép tính độ dài là, chẳng hạn. Nếu  là chuỗi, phép tính này có giá trị là số byte trong chuỗi. Nếu  là bảng dãy, nó có giá trị là số giá trị trong dãy.

Nếu  là bảng mà không phải là dãy,   có một giá trị N nào đó để cho   không phải vô-giá-trị và   là vô-giá-trị, dù mà có giá trị không phải vô-giá-trị ở các chỉ số cao hơn. Thí dụ:

Thứ tự ưu tiên phép tính
Thứ tự ưu tiên phép tính của Lua, từ mức cao nhất đến thấp nhất:


 * (phủ định)
 * (trừ)
 * (trừ)
 * (trừ)

Trong một mức ưu tiên, phần nhiều phép tính nhị phân kết hợp trái, chẳng hạn  được đánh giá là. Các phép lũy thừa và nối liền là kết hợp phải, chẳng hạn  được đánh giá là.

Lời gọi hàm
Các lời gọi hàm trong Lua nhìn giống lời gọi trong nhiều ngôn ngữ khác: một tên rồi một danh sách đối số để trong ngoặc đơn:

ham( danh sách biểu thức )

Như thường lệ của danh sách biểu thức trong Lua, biểu thức cuối cùng trong danh sách có thể có nhiều giá trị đối số.

Nếu hàm được gọi mà cung cấp ít giá trị hơn trong danh sách biểu thức đối với các tham số được định rõ trong lời khai báo hàm, các tham số còn dư là vô-giá-trị. Nếu danh sách biểu thức có nhiều giá trị hơn các tham số, các giá trị còn dư được bỏ qua. Hàm cũng có khả năng nhận bất cứ bao nhiêu tham số; xem chi tiết trong phần “Lời khai báo hàm”.

Lua cũng cho phép gọi trực tiếp một giá trị hàm được cho ra hàm, chẳng hạn. Nếu cần phân tích một biểu thức phức tạp hơn lệnh truy cập biến số để biết một hàm có cần được gọi hay không, có thể sử dụng một biểu thức để trong ngoặc đơn thay vì lệnh truy cập biến số.

Lua có cú pháp đặc biệt trong hai trường hợp thường gặp. Trường hợp thứ nhất là sử dụng bảng như đối tượng và gọi hàm như một phương thức của đối tượng. Cú pháp:

bang:ten( danh sách biểu thức )

là tương đương với:

bang.ten( bang, danh sách biểu thức )

Trường hợp thường gặp thứ hai là cung cấp đối tượng có tên trong Lua bằng cách cho bảng tương quan các tên tham số với giá trị vào hàm chỉ có một tham số. Trong trường hợp này không cần để danh sách đối tượng trong ngoặc đơn. Gọi hàm mà chỉ cho một chuỗi trực tiếp vào hàm thì cũng có thể bỏ qua các dấu ngoặc đơn. Thí dụ các lời gọi:

ham{ thamSo1 = biểu thức, thamSo2 = biểu thức } ham"chuỗi" ham "chuỗi"

là tương đương với:

ham( { thamSo1 = biểu thức, thamSo2 = biểu thức } ) ham( "chuỗi" ) ham( "chuỗi" )

Có thể sử dụng hai cú pháp đặc biệt này cùng lúc, nên các lời gọi sau là tương đương với nhau:

bang:ten{ thamSo1 = biểu thức, thamSo2 = biểu thức } bang.ten( bang, { thamSo1 = biểu thức, thamSo2 = biểu thức } )

Lời khai báo hàm
Cú pháp khai báo hàm theo định dạng:

function ( danh sách biến số ) đoạn mã end

Tất cả các biến số trong danh sách biến số có phạm vi địa phương là hàm, và các giá trị được chỉ định theo danh sách biểu thức trong lời gọi hàm. Có thể khai báo thêm biến số địa phương ở trong đoạn mã.

Khi gọi hàm, các câu lệnh trong đoạn mã được chạy sau khi các biến số địa phương ứng với danh sách biến số được tạo và chỉ định các giá trị. Hễ khi nào gặp câu lệnh trả về thì thoát đoạn mã và các giá trị của biểu thức gọi hàm là các giá trị được cho ra qua câu lệnh trả về. Nếu gặp cuối đoạn mã của hàm mà không gặp câu lệnh trả về, kết quả của biểu thức gọi hàm không có giá trị nào.

Các hàm Lua là hàm đóng từ vựng (lexical closure). Người ta thường khai báo các biến số “tĩnh riêng tư" là biến số địa phương trong phạm vi lời khai báo hàm. Thí dụ:

Hàm tham lượng động (varargs function) có thể nhận bất cứ bao nhiêu tham số, bằng cách định rõ  là tham số cuối cùng trong danh sách biến số:

function ( danh sách biến số, ⋯ ) đoạn mã end

Có thể sử dụng biểu thức tham lượng động  trong đoạn mã để có kết quả là tất cả các đối số còn dư từ lời gọi hàm. Thí dụ:

Hàm  dành cho biểu thức tham lượng động; nói riêng, bạn nên sử dụng   thay vì   để đếm số giá trị trong biểu thức tham lượng động.

Lua có cú pháp đặc biệt để khai báo hàm và chỉ định nó cho một biến số cùng lúc; xem chi tiết trong phần “Câu lệnh khai báo hàm”.

Lưu ý rằng thí dụ này gây lỗi:

Vì lời khai báo hàm được phân tích trước khi câu lệnh chỉ định biến số địa phương được kết thúc, tên “giaiThua” ở trong đoạn mã của hàm chỉ đến biến số toàn cầu (có lẽ không được định nghĩa) có tên đó. Có thể tránh vấn đề này bằng cách khai báo biến số địa phương trước tiên rồi chỉ định hàm cho nó trong câu lệnh riêng ở dưới.

Câu lệnh
Câu lệnh là đơn vị chạy cơ bản: câu lệnh chỉ định, cấu trúc điều khiển, lời gọi hàm, lời khai báo biến số, v.v.

Bó lệnh (chunk) là loạt câu lệnh được phân cách bởi dòng mới và/hoặc dấu chấm phẩy. Bó lệnh thường được coi là thân của hàm vô danh, nên bó lệnh có thể khai báo biến số địa phương, nhận đối số, và trả về giá trị.

Đoạn mã (block) cũng là loạt câu lệnh giống bó lệnh. Có thể để đoạn mã giữa các từ khóa để tạo câu lệnh:. Có thể sử dụng đoạn mã để hạn chế phạm vi của biến số địa phương hoặc thêm  hay   vào giữa đoạn mã khác.

Lời chỉ định
Danh sách biến số là danh sách biến số được phân cách bởi dấu phẩy; danh sách biểu thức là danh sách một biểu thức trở lên được phân cách bởi dấu phẩy. Tất cả các biểu thức được đánh giá trước khi thực hiện chỉ định biến số, nên  sẽ trao đổi các giá trị   và.

Lời khai báo biến số địa phương
Có thể khai báo biến số địa phương ở nơi nào trong đoạn mã. Cú pháp đầu tiên, tức không có danh sách biểu thức, khai báo các biến số nhưng không chỉ định một giá trị, nên các biến số là vô-giá-trị (nil). Cú pháp thứ hai chỉ định các giá trị cho các biến số địa phương, theo phương pháp được miêu tả trong phần “Lời chỉ định” ở trên.

Lưu ý rằng phạm vi truy cập được biến số địa phương bắt đầu ở câu lệnh đằng sau câu lệnh khai báo biến số địa phương. Cho nên một lệnh khai báo như  khai báo biến số địa phương   và chỉ định giá trị   từ phạm vi bên ngoài cho biến số đó. Biến số địa phương vẫn còn truy cập được cho đến cuối đoạn mã ở trong tận cùng mà có lời khai báo biến số địa phương.

Cấu trúc điều khiển
Câu lệnh  lặp lại một đoạn mã cho đến khi biểu thức không còn có giá trị thực.

Câu lệnh  lặp lại một đoạn mã cho đến lúc biểu thức có giá trị thực. Biểu thức có thể truy cập các biến số được khai báo trong đoạn mã.

Hình dạng thứ nhất của vòng lặp  khai báo một biến số địa phương và lặp lại đoạn mã một lần mỗi giá trị từ biểu thức 1 đến biểu thức 2, với biểu thức 3 được cộng vào tên mọi vòng. Nếu không định rõ biểu thức 3 mỗi vòng là cộng 1 vào tên. Tất cả các biểu thức được đánh giá một lần trước khi bắt đầu vòng lặp.

Hình dạng vòng lặp  này tương tự với:

do    local bienSo, hanMuc, buoc = tonumber( biểu thức 1 ), tonumber( biểu thức 2 ), tonumber( biểu thức 3 ) if not ( bienSo and hanMuc and buoc ) then error end while ( buoc > 0 and bienSo <= hanMuc ) or ( buoc <= 0 and bienSo >= hanMuc ) do        local tên = bienSo đoạn mã bienSo = bienSo + buoc end end

nhưng không thể truy cập các biến số,  , và   ở ngoài cấu trúc này. Lưu ý rằng biến số  có phạm vi địa phương là đoạn mã; để sử dụng giá trị sau cuối vòng lặp, phải sao chép nó cho một biến số được khai báo ở ngoài vòng lặp.

Hình dạng thứ hai của vòng lặp  được sử dụng với các hàm bộ lặp. Giống trong hình dạng thứ nhất, danh sách biểu thức chỉ được đánh giá một lần trước khi bắt đầu vòng lặp.

Hình dạng vòng lặp  này tương tự với:

do    local ham, tinh, bienSo = danh sách biểu thức while true do        local danh sách biến số = ham( tinh, bienSo ) var = biến số 1 -- biến số 1 là biến số đầu tiên trong danh sách biến số if bienSo == nil then break end đoạn mã end end

nhưng không thể truy cập các biến số,  , và   ở ngoài cấu trúc này. Lưu rằng các biến số trong danh sách biến số có phạm vi địa phương là đoạn mã; để sử dụng nó sau cuối vòng lặp, phải sao chép nó cho các biến số được khai báo ở ngoài vòng lặp.

Nhiều khi danh sách biểu thức chỉ là một lời gọi hàm mà cho ra ba giá trị. Vòng lặp có hiệu suất cao nhất khi hàm bộ lặp chỉ phụ thuộc các đối số được cho vào nó. Hàm phải phụ thuộc các biến số khác, cẩm nang Programming in Lua khuyến khích sử dụng hàm đóng thay vì trả về bảng như một biến số tĩnh và cập nhật các phần tử mọi vòng.

Cấu trúc này chạy đoạn mã 1 nếu biểu thức 1 là thực, nếu không thì chạy đoạn mã 2 nếu biểu thức 2 là thực, nếu không thì chạy biểu thức 3. Không cần có phần, và có thể lặp lại hoặc không đưa vào phần.

Câu lệnh  trả về các giá trị từ một hàm hoặc bó lệnh (bó lệnh chỉ là loại hàm). Danh sách biểu thức là danh sách có bất cứ bao nhiêu biểu thức được phân cách bởi dấu phẩy.

Lua sử dụng lời gọi đuôi (tail call): nếu danh sách biểu thức chỉ có một biểu thức và biểu thức đó là lời gọi hàm, khung ngăn xếp hiện tại được dùng lại để gọi hàm đó. Cách xử lý này ảnh hưởng đến những hàm có liên quan đến ngăn xếp gọi hàm, chẳng hạn  và.

Câu lệnh trả về phải là câu lệnh cuối cùng của đoạn mã. Nếu vì lý do nào đó cần trả về vào giữa đoạn mã, có thể tạo ra một đoạn mã đơn giản.

Câu lệnh  thoát một vòng lặp ,  , hoặc   và nhảy đến câu lệnh sau vòng lặp.

Câu lệnh  phải là câu lệnh cuối cùng trong đoạn mã. Nếu vì lý do nào đó cần thoát từ giữa đoạn mã, có thể tạo ra một đoạn mã đơn giản.

Câu lệnh gọi hàm
Có thể sử dụng một lời gọi hàm như một câu lệnh; trong trường hợp này, hàm chỉ được gọi để thực hiện những ảnh hưởng phụ (thí dụ  đưa các giá trị ra đầu ra) và bỏ qua các giá trị cho ra.

Câu lệnh khai báo hàm
Lua có cú pháp đặc biệt để khai báo hàm và chỉ định nó cho một biến số một cách tự nhiên hơn. Các đôi lời khai báo sau là tương đương với nhau:

-- Lời khai báo cơ bản function ham( danh sách biến số ) đoạn mã end func = ham ( danh sách biến số ) đoạn mã end

-- Hàm địa phương local function ham( danh sách biến số ) đoạn mã end local ham; ham = function ( danh sách biến số ) đoạn mã end

-- Hàm trong trường bảng function bang.ham( danh sách biến số ) đoạn mã end bang.ham = function ( danh sách biến số ) đoạn mã end

-- Hàm như phương thức bảng function bang:ham( danh sách biểu thức ) đoạn mã end bang.ham = function ( self, danh sách biến số ) đoạn mã end

Lưu ý rằng cú pháp dấu hai châm ở trên ứng với cú pháp gọi hàm. Cả hai cú pháp cho một tham số có tên  vào đầu danh sách tham số.