Bài 28 : Lua tóm tắt 1 số hướng dẫn học Lua

Bài 28 : Lua tóm tắt 1 số hướng dẫn học Lua

Lua – Tổng quan Lua là một ngôn ngữ lập trình nhẹ, có thể mở rộng được viết bằng C. […]

Learn more »

Lua – Tổng quan

Lua là một ngôn ngữ lập trình nhẹ, có thể mở rộng được viết bằng C. Nó bắt đầu như một dự án nội bộ vào năm 1993 bởi Roberto Ierusalimschy, Luiz Henrique de Figueosystemo và Waldemar Celes.

Nó được thiết kế ngay từ đầu để trở thành một phần mềm có thể được tích hợp với mã viết bằng C và các ngôn ngữ thông thường khác. Sự tích hợp này mang lại nhiều lợi ích. Nó không cố gắng làm những gì C đã có thể làm mà nhằm đưa ra những gì C không giỏi: khoảng cách tốt với phần cứng, cấu trúc động, không dư thừa, dễ kiểm tra và gỡ lỗi. Đối với điều này, Lua có một môi trường an toàn, quản lý bộ nhớ tự động và các phương tiện tốt để xử lý các chuỗi và các loại dữ liệu khác với kích thước động.

Đặc trưng

Lua cung cấp một tập hợp các tính năng độc đáo làm cho nó khác biệt với các ngôn ngữ khác. Chúng bao gồm –

  • Có thể mở rộng
  • Đơn giản
  • Có hiệu quả
  • Cầm tay
  • Miễn phí và mở

Mã mẫu

print("Hello World!")

Lua được thực hiện như thế nào?

Lua bao gồm hai phần – phần thông dịch Lua và hệ thống phần mềm hoạt động. Hệ thống phần mềm hoạt động là một ứng dụng máy tính thực tế có thể thông dịch các chương trình được viết bằng ngôn ngữ lập trình Lua. Trình thông dịch Lua được viết bằng ANSI C, do đó nó có tính di động cao và có thể chạy trên nhiều thiết bị từ các máy chủ mạng cao cấp đến các thiết bị nhỏ.

Cả ngôn ngữ của Lua và thông dịch viên của nó đều thuần thục, nhỏ và nhanh. Nó đã phát triển từ các ngôn ngữ lập trình khác và các tiêu chuẩn phần mềm hàng đầu. Kích thước nhỏ giúp nó có thể chạy trên các thiết bị nhỏ với bộ nhớ thấp.

Học Lua

Điểm quan trọng nhất khi học Lua là tập trung vào các khái niệm mà không bị lạc vào các chi tiết kỹ thuật của nó.

Mục đích của việc học một ngôn ngữ lập trình là để trở thành một lập trình viên giỏi hơn; nghĩa là, để trở nên hiệu quả hơn trong việc thiết kế và triển khai các hệ thống mới cũng như duy trì các hệ thống cũ.

Một số công dụng của Lua

  • Lập trình trò chơi
  • Viết kịch bản trong các ứng dụng độc lập
  • Viết kịch bản trong Web
  • Các tiện ích mở rộng và tiện ích bổ sung cho cơ sở dữ liệu như MySQL Proxy và MySQL WorkBench
  • Hệ thống an ninh như Hệ thống phát hiện xâm nhập.

Lua – Môi trường

Thiết lập môi trường cục bộ

Nếu bạn vẫn sẵn sàng thiết lập môi trường của mình cho ngôn ngữ lập trình Lua, bạn cần có các phần mềm sau trên máy tính của mình – (a) Trình soạn thảo văn bản, (b) Trình thông dịch Lua và (c) Trình biên dịch Lua.

Trình soạn thảo văn bản

Bạn cần một trình soạn thảo văn bản để nhập chương trình của mình. Ví dụ về một số trình chỉnh sửa bao gồm Windows Notepad, lệnh Chỉnh sửa hệ điều hành, Tóm tắt, Epsilon, EMACS và vim hoặc vi.

Tên và phiên bản của trình soạn thảo văn bản có thể khác nhau trên các hệ điều hành khác nhau. Ví dụ: Notepad sẽ được sử dụng trên Windows và vim hoặc vi có thể được sử dụng trên Windows cũng như Linux hoặc UNIX.

Các tệp bạn tạo bằng trình chỉnh sửa của mình được gọi là tệp nguồn và các tệp này chứa mã nguồn của chương trình. Các tệp nguồn cho các chương trình Lua thường được đặt tên với phần mở rộng là “.lua” .

Thông dịch viên Lua

Nó chỉ là một chương trình nhỏ cho phép bạn gõ lệnh Lua và thực thi chúng ngay lập tức. Nó dừng việc thực thi tệp Lua trong trường hợp nó gặp lỗi không giống như trình biên dịch thực thi đầy đủ.

Trình biên dịch Lua

Khi chúng tôi mở rộng Lua sang các ngôn ngữ / ứng dụng khác, chúng tôi cần Bộ phát triển phần mềm có trình biên dịch tương thích với Giao diện chương trình ứng dụng Lua.

Cài đặt trên Windows

Có một IDE riêng có tên “SciTE” được phát triển cho môi trường windows, bạn có thể tải xuống từ https://code.google.com/p/luaforwindows/ phần tải xuống.

Chạy tệp thực thi đã tải xuống để cài đặt Lua IDE.

Vì đó là một IDE, bạn có thể vừa tạo và xây dựng mã Lua bằng cách sử dụng cùng một mã.

Trong trường hợp bạn quan tâm đến việc cài đặt Lua ở chế độ dòng lệnh, bạn cần cài đặt MinGW hoặc Cygwin, sau đó biên dịch và cài đặt Lua trong windows.

Cài đặt trên Linux

Để tải xuống và xây dựng Lua, hãy sử dụng lệnh sau:

$ wget http://www.lua.org/ftp/lua-5.2.3.tar.gz $ tar zxf lua-5.2.3.tar.gz $ cd lua-5.2.3 $ make linux test 

Để cài đặt trên các nền tảng khác như aix, ansi, bsd, linux chung, mingw, posix, solaris bằng cách thay thế Linux bằng tạo Linux, hãy thử nghiệm với tên nền tảng tương ứng.

Chúng tôi có một helloWorld.lua, trong Lua như sau:

print("Hello World!")

Bây giờ, chúng ta có thể xây dựng và chạy tệp Lua nói helloWorld.lua, bằng cách chuyển sang thư mục chứa tệp bằng cd, sau đó sử dụng lệnh sau:

$ lua helloWorld 

Chúng ta có thể xem kết quả sau.

Hello World! 

Cài đặt trên Mac OS X

Để xây dựng / kiểm tra Lua trong Mac OS X, hãy sử dụng lệnh sau:

$ curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz $ tar zxf lua-5.2.3.tar.gz $ cd lua-5.2.3 $ make macosx test 

Trong một số trường hợp nhất định, bạn có thể chưa cài đặt công cụ Xcode và dòng lệnh. Trong những trường hợp như vậy, bạn sẽ không thể sử dụng lệnh make. Cài đặt Xcode từ cửa hàng ứng dụng mac. Sau đó đi tới Tùy chọn của Xcode, rồi chuyển sang Tải xuống và cài đặt thành phần có tên “Công cụ dòng lệnh”. Sau khi quá trình hoàn tất, lệnh make sẽ có sẵn cho bạn.

Bạn không bắt buộc phải thực hiện câu lệnh “thực hiện kiểm tra macosx”. Ngay cả khi không thực hiện lệnh này, bạn vẫn có thể sử dụng Lua trong Mac OS X.

Chúng tôi có một helloWorld.lua, trong Lua, như sau:

print("Hello World!")

Bây giờ, chúng ta có thể xây dựng và chạy tệp Lua say helloWorld.lua bằng cách chuyển sang thư mục chứa tệp bằng cd và sau đó sử dụng lệnh sau:

$ lua helloWorld 

Chúng ta có thể thấy kết quả sau:

Hello World! 

Lua IDE

Như đã đề cập trước đó, đối với Windows SciTE, Lua IDE là IDE mặc định được cung cấp bởi nhóm tạo Lua. IDE thay thế có sẵn là từ ZeroBrane Studio, có sẵn trên nhiều nền tảng như Windows, Mac và Linux.

Ngoài ra còn có các plugin cho eclipse cho phép phát triển Lua. Sử dụng IDE giúp phát triển dễ dàng hơn với các tính năng như hoàn thành mã và rất được khuyến khích. IDE cũng cung cấp lập trình chế độ tương tác tương tự như phiên bản dòng lệnh của Lua.

Lua – Cú pháp cơ bản

Hãy để chúng tôi bắt đầu tạo chương trình Lua đầu tiên của chúng tôi!

Chương trình Lua đầu tiên

Lập trình chế độ tương tác

Lua cung cấp một chế độ gọi là chế độ tương tác. Trong chế độ này, bạn có thể gõ lần lượt các hướng dẫn và nhận được kết quả tức thì. Điều này có thể được gọi trong shell bằng cách sử dụng lua -i hoặc chỉ lệnh lua. Sau khi bạn nhập vào đây, hãy nhấn Enter và chế độ tương tác sẽ được bắt đầu như hình dưới đây.

$ lua -i  $ Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio quit to end; cd, dir and edit also available 

Bạn có thể in thứ gì đó bằng cách sử dụng câu lệnh sau:

print("test")

Sau khi nhấn enter, bạn sẽ nhận được kết quả sau:

test 

Lập trình chế độ mặc định

Việc gọi trình thông dịch với tham số tên tệp Lua bắt đầu thực thi tệp và tiếp tục cho đến khi tập lệnh kết thúc. Khi tập lệnh kết thúc, trình thông dịch không còn hoạt động.

Hãy để chúng tôi viết một chương trình Lua đơn giản. Tất cả các tệp Lua sẽ có phần mở rộng là .lua. Vì vậy, hãy đặt mã nguồn sau vào tệp test.lua.Bản thử trực tiếp

print("test")

Giả sử, môi trường lua được thiết lập chính xác, hãy chạy chương trình bằng đoạn mã sau:

$ lua test.lua 

Chúng ta sẽ nhận được kết quả sau:

test 

Hãy thử một cách khác để thực thi một chương trình Lua. Dưới đây là tệp test.lua đã được sửa đổi –Bản thử trực tiếp

#!/usr/local/bin/lua  print("test")

Ở đây, chúng tôi đã giả định rằng bạn có sẵn trình thông dịch Lua trong thư mục / usr / local / bin của bạn. Dòng đầu tiên bị trình thông dịch bỏ qua nếu nó bắt đầu bằng dấu #. Bây giờ, hãy thử chạy chương trình này như sau:

$ chmod a+rx test.lua $./test.lua 

Chúng ta sẽ nhận được kết quả sau.

test 

Bây giờ chúng ta hãy xem cấu trúc cơ bản của chương trình Lua, để bạn có thể dễ dàng hiểu được các khối xây dựng cơ bản của ngôn ngữ lập trình Lua.

Token trong Lua

Một chương trình Lua bao gồm các mã thông báo khác nhau và mã thông báo là một từ khóa, một mã định danh, một hằng số, một chuỗi ký tự hoặc một ký hiệu. Ví dụ: câu lệnh Lua sau đây bao gồm ba mã thông báo:

io.write("Hello world, from ",_VERSION,"!\n") 

Các mã thông báo riêng lẻ là –

io.write (    "Hello world, from ",_VERSION,"!\n" ) 

Bình luận

Nhận xét giống như văn bản trợ giúp trong chương trình Lua của bạn và chúng bị thông dịch viên bỏ qua. Chúng bắt đầu bằng – [[và kết thúc bằng các ký tự -]] như hình dưới đây –

--[[ my first program in Lua --]] 

Định danh

Mã định danh Lua là tên được sử dụng để xác định một biến, hàm hoặc bất kỳ mục nào khác do người dùng xác định. Mã định danh bắt đầu bằng chữ cái ‘A đến Z’ hoặc ‘a đến z’ hoặc dấu gạch dưới ‘_’ theo sau là không hoặc nhiều chữ cái, dấu gạch dưới và chữ số (0 đến 9).

Lua không cho phép các ký tự dấu câu như @, $ và% trong số nhận dạng. Lua là một ngôn ngữ lập trình phân biệt chữ hoa chữ thường . Như vậy Nhân lực và nhân lực là hai định danh khác nhau trong Lúa. Dưới đây là một số ví dụ về các số nhận dạng được chấp nhận –

mohd         zara      abc     move_name    a_123 myname50     _temp     j       a23b9        retVal 

Từ khóa

Danh sách sau đây cho thấy một số từ dành riêng trong Lua. Những từ dành riêng này không được dùng làm hằng số hoặc biến hoặc bất kỳ tên định danh nào khác.

nghỉlàmkhác
elseifkết thúcsai
hàm sốnếu nhưtrongđịa phương
khôngkhông phảihoặclặp lại
trở lạisau đóthậtcho đến khi
trong khi

Khoảng trắng trong Lua

Một dòng chỉ chứa khoảng trắng, có thể có chú thích, được gọi là dòng trống và trình thông dịch Lua hoàn toàn bỏ qua nó.

Khoảng trắng là thuật ngữ được sử dụng trong Lua để mô tả khoảng trống, tab, ký tự dòng mới và nhận xét. Khoảng trắng phân tách một phần của một câu lệnh với phần khác và cho phép trình thông dịch xác định vị trí một phần tử trong một câu lệnh, chẳng hạn như int kết thúc và phần tử tiếp theo bắt đầu. Do đó, trong câu lệnh sau:

local age 

Phải có ít nhất một ký tự khoảng trắng (thường là khoảng trắng) giữa địa phương và tuổi để trình thông dịch có thể phân biệt chúng. Mặt khác, trong câu lệnh sau:

fruit = apples + oranges   --get the total fruit 

Không cần ký tự khoảng trắng nào giữa trái cây và =, hoặc giữa = và táo, mặc dù bạn có thể thêm một số ký tự nếu muốn vì mục đích dễ đọc.

Lua – Các biến

Một biến không là gì ngoài tên được đặt cho một vùng lưu trữ mà chương trình của chúng ta có thể thao tác. Nó có thể chứa các loại giá trị khác nhau bao gồm các hàm và bảng.

Tên của một biến có thể bao gồm các chữ cái, chữ số và ký tự gạch dưới. Nó phải bắt đầu bằng một chữ cái hoặc một dấu gạch dưới. Chữ hoa và chữ thường khác nhau vì Lua phân biệt chữ hoa chữ thường. Có tám loại giá trị cơ bản trong Lua –

Trong Lua, mặc dù chúng ta không có kiểu dữ liệu biến, nhưng chúng ta có ba kiểu dựa trên phạm vi của biến.

  • Biến toàn cục – Tất cả các biến được coi là toàn cục trừ khi được khai báo rõ ràng là cục bộ.
  • Biến cục bộ – Khi kiểu được chỉ định là cục bộ cho một biến thì phạm vi của nó bị giới hạn với các hàm bên trong phạm vi của chúng.
  • Trường bảng – Đây là một loại biến đặc biệt có thể chứa bất kỳ thứ gì ngoại trừ nil bao gồm các hàm.

Định nghĩa biến trong Lua

A variable definition means to tell the interpreter where and how much to create the storage for the variable. A variable definition have an optional type and contains a list of one or more variables of that type as follows −

type variable_list; 

Here, type is optionally local or type specified making it global, and variable_list may consist of one or more identifier names separated by commas. Some valid declarations are shown here −

local    i, j local    i local    a,c 

The line local i, j both declares and defines the variables i and j; which instructs the interpreter to create variables named i, j and limits the scope to be local.

Variables can be initialized (assigned an initial value) in their declaration. The initializer consists of an equal sign followed by a constant expression as follows −

type variable_list = value_list; 

Some examples are −

local d , f = 5 ,10     --declaration of d and f as local variables.  d , f = 5, 10;          --declaration of d and f as global variables.  d, f = 10               --[[declaration of d and f as global variables.                             Here value of f is nil --]] 

Đối với định nghĩa không có bộ khởi tạo: các biến có thời lượng lưu trữ tĩnh được khởi tạo ngầm định bằng nil.

Khai báo biến trong Lua

Như bạn có thể thấy trong các ví dụ trên, các phép gán cho nhiều biến tuân theo định dạng danh sách biến và giá trị. Trong ví dụ trên local d, f = 5,10 chúng ta có d và f trong danh sách biến và 5 và 10 trong danh sách giá trị.

Việc gán giá trị trong Lua diễn ra giống như biến đầu tiên trong danh sách biến với giá trị đầu tiên trong danh sách giá trị, v.v. Do đó, giá trị của d là 5 và giá trị của f là 10.

Thí dụ

Hãy thử ví dụ sau, trong đó các biến đã được khai báo ở trên cùng, nhưng chúng đã được xác định và khởi tạo bên trong hàm chính:Bản thử trực tiếp

-- Variable definition: local a, b  -- Initialization a = 10 b = 30  print("value of a:", a)  print("value of b:", b)  -- Swapping of variables b, a = a, b  print("value of a:", a)  print("value of b:", b)  f = 70.0/3.0 print("value of f", f)

Khi đoạn mã trên được xây dựng và thực thi, nó tạo ra kết quả sau:

value of a:	10 value of b:	30 value of a:	30 value of b:	10 value of f	23.333333333333 

Giá trị và giá trị trong Lua

Có hai loại biểu thức trong Lua –

  • lvalue – Các biểu thức tham chiếu đến một vị trí bộ nhớ được gọi là biểu thức “lvalue”. Giá trị có thể xuất hiện ở dạng bên trái hoặc bên phải của bài tập.
  • rvalue – Thuật ngữ rvalue đề cập đến một giá trị dữ liệu được lưu trữ tại một số địa chỉ trong bộ nhớ. Giá trị là một biểu thức không thể có giá trị được gán cho nó, có nghĩa là giá trị có thể xuất hiện ở phía bên phải, nhưng không xuất hiện ở phía bên trái của phép gán.

Các biến là giá trị và do đó có thể xuất hiện ở phía bên trái của phép gán. Các chữ số là các giá trị và do đó có thể không được chỉ định và không thể xuất hiện ở phía bên trái. Sau đây là một tuyên bố hợp lệ –

g = 20 

Nhưng sau đây không phải là một tuyên bố hợp lệ và sẽ tạo ra lỗi thời gian xây dựng –

10 = 20 

Trong ngôn ngữ lập trình Lua, ngoài các kiểu gán trên, có thể có nhiều giá trị và giá trị trong cùng một câu lệnh. Nó được hiển thị bên dưới.

g,l = 20,30 

Trong câu lệnh trên, 20 được gán cho g và 30 được gán cho l.

Lua – Các kiểu dữ liệu

Lua là một ngôn ngữ được định kiểu động, vì vậy các biến không có kiểu, chỉ có các giá trị mới có kiểu. Giá trị có thể được lưu trữ trong các biến, được truyền dưới dạng tham số và trả về dưới dạng kết quả.

Trong Lua, mặc dù chúng ta không có kiểu dữ liệu biến đổi, nhưng chúng ta có kiểu cho các giá trị. Dưới đây là danh sách các kiểu dữ liệu cho các giá trị.

Sr.NoLoại giá trị & Mô tả
1khôngĐược sử dụng để phân biệt giá trị có một số dữ liệu hoặc không có dữ liệu (nil).
2booleanBao gồm giá trị true và false. Thường được sử dụng để kiểm tra tình trạng.
3con sốĐại diện cho các số thực (dấu phẩy động chính xác kép).
4dâyĐại diện cho mảng ký tự.
5hàm sốĐại diện cho một phương thức được viết bằng C hoặc Lua.
6dữ liệu người dùngBiểu diễn dữ liệu C tùy ý.
7chủ đềĐại diện cho các luồng thực thi độc lập và nó được sử dụng để triển khai các coroutines.
số 8bànBiểu diễn các mảng thông thường, bảng ký hiệu, tập hợp, bản ghi, đồ thị, cây, v.v. và triển khai các mảng kết hợp. Nó có thể giữ bất kỳ giá trị nào (ngoại trừ nil).

Loại chức năng

Trong Lua, có một hàm gọi là ‘kiểu’ cho phép chúng ta biết kiểu của biến. Một số ví dụ được đưa ra trong đoạn mã sau.Bản thử trực tiếp

print(type("What is my type"))   --> string t = 10  print(type(5.8*t))               --> number print(type(true))                --> boolean print(type(print))               --> function print(type(nil))                 --> nil print(type(type(ABC)))           --> string

Khi bạn xây dựng và thực thi chương trình trên, nó tạo ra kết quả sau trên Linux:

string number boolean function nil string 

By default, all the variables will point to nil until they are assigned a value or initialized. In Lua, zero and empty strings are considered to be true in case of condition checks. Hence, you have to be careful when using Boolean operations. We will know more using these types in the next chapters.

Lua – Operators

An operator is a symbol that tells the interpreter to perform specific mathematical or logical manipulations. Lua language is rich in built-in operators and provides the following type of operators −

  • Arithmetic Operators
  • Relational Operators
  • Logical Operators
  • Misc Operators

This tutorial will explain the arithmetic, relational, logical, and other miscellaneous operators one by one.

Arithmetic Operators

Following table shows all the arithmetic operators supported by Lua language. Assume variable A holds 10 and variable B holds 20 then −

Show Examples

OperatorDescriptionExample
+Adds two operandsA + B will give 30
Subtracts second operand from the firstA – B will give -10
*Multiply both operandsA * B will give 200
/Divide numerator by de-numeratorB / A will give 2
%Modulus Operator and remainder of after an integer divisionB % A will give 0
^Exponent Operator takes the exponentsA^2 will give 100
Unary – operator acts as negation-A will give -10

Relational Operators

Following table shows all the relational operators supported by Lua language. Assume variable A holds 10 and variable B holds 20 then −

Show Examples

OperatorDescriptionExample
==Checks if the value of two operands are equal or not, if yes then condition becomes true.(A == B) is not true.
~=Checks if the value of two operands are equal or not, if values are not equal then condition becomes true.(A ~= B) is true.
>Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.(A > B) is not true.
<Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.(A < B) is true.
>=Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.(A >= B) is not true.
<=Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.(A <= B) is true.

Logical Operators

Following table shows all the logical operators supported by Lua language. Assume variable A holds true and variable B holds false then −

Show Examples

OperatorDescriptionExample
andCalled Logical AND operator. If both the operands are non zero then condition becomes true.(A and B) is false.
orCalled Logical OR Operator. If any of the two operands is non zero then condition becomes true.(A or B) is true.
notCalled Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.!(A and B) is true.

Misc Operators

Miscellaneous operators supported by Lua Language include concatenation and length.

Show Examples

OperatorDescriptionExample
..Concatenates two strings.a..b trong đó a là “Hello” và b là “World”, sẽ trả về “Hello World”.
#Một toán tử một ngôi trả về độ dài của một chuỗi hoặc một bảng.# “Xin chào” sẽ trả về 5

Mức độ ưu tiên của nhà khai thác trong Lua

Mức độ ưu tiên của toán tử xác định nhóm các thuật ngữ trong một biểu thức. Điều này ảnh hưởng đến cách một biểu thức được đánh giá. Một số toán tử nhất định có quyền ưu tiên cao hơn những toán tử khác; ví dụ, toán tử nhân có mức độ ưu tiên cao hơn toán tử cộng –

Ví dụ: x = 7 + 3 * 2; Ở đây x được gán 13, không phải 20 vì toán tử * có mức độ ưu tiên cao hơn + nên trước tiên nó được nhân với 3 * 2 và sau đó cộng thành 7.

Ở đây, các toán tử có mức độ ưu tiên cao nhất xuất hiện ở đầu bảng, những toán tử có mức độ ưu tiên thấp nhất xuất hiện ở cuối bảng. Trong một biểu thức, các toán tử có mức độ ưu tiên cao hơn sẽ được đánh giá đầu tiên.

Hiển thị các ví dụ

LoạiNhà điều hànhSự liên kết
Một ngôikhông phải # –Phải sang trái
Sự kết hợp..Phải sang trái
Phép nhân* /%Trái sang phải
Phụ gia+ –Trái sang phải
Quan hệ<> <=> = == ~ = Trái sang phải
Bình đẳng== ~ =Trái sang phải
Logic ANDTrái sang phải
Lôgic HOẶChoặcTrái sang phải

Lua – Vòng lặp

Có thể có một tình huống khi bạn cần thực thi một khối mã nhiều lần. Nói chung, các câu lệnh được thực thi tuần tự: câu lệnh đầu tiên trong một hàm được thực thi trước tiên, tiếp theo là câu lệnh thứ hai, v.v.

Các ngôn ngữ lập trình cung cấp các cấu trúc điều khiển khác nhau cho phép các đường dẫn thực thi phức tạp hơn.

Một câu lệnh lặp cho phép chúng ta thực hiện một câu lệnh hoặc một nhóm câu lệnh nhiều lần. Sau đây là dạng chung của câu lệnh lặp trong hầu hết các ngôn ngữ lập trình:

Kiến trúc vòng lặp

Lua cung cấp các loại vòng lặp sau để xử lý các yêu cầu về vòng lặp.

Sr.No.Loại vòng lặp & Mô tả
1trong khi lặp lạiLặp lại một câu lệnh hoặc một nhóm câu lệnh trong khi một điều kiện đã cho là đúng. Nó kiểm tra điều kiện trước khi thực thi phần thân của vòng lặp.
2vòng lặp forThực thi một chuỗi các câu lệnh nhiều lần và viết tắt đoạn mã quản lý biến vòng lặp.
3lặp lại … cho đến khi lặp lạiLặp lại hoạt động của nhóm câu lệnh cho đến khi điều kiện được đáp ứng.
4vòng lồng nhauBạn có thể sử dụng một hoặc nhiều vòng lặp bên trong bất kỳ vòng lặp while , for hoặc do.. while nào khác .

Tuyên bố kiểm soát vòng lặp

Câu lệnh điều khiển vòng lặp thay đổi việc thực thi từ trình tự bình thường của nó. Khi việc thực thi rời khỏi một phạm vi, tất cả các đối tượng tự động được tạo trong phạm vi đó sẽ bị phá hủy.

Lua hỗ trợ các câu lệnh điều khiển sau.

Sr.No.Tuyên bố & Mô tả Kiểm soát
1tuyên bố ngắtTerminates the loop and transfers execution to the statement immediately following the loop or switch.

The Infinite Loop

A loop becomes infinite loop if a condition never becomes false. The while loop is often used for this purpose. Since we directly give true for the condition, it keeps executing forever. We can use the break statement to break this loop.

while( true ) do    print("This loop will run forever.") end

Lua – Decision Making

Decision making structures require that the programmer specifies one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed, if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.

Sau đây là dạng chung của cấu trúc ra quyết định điển hình được tìm thấy trong hầu hết các ngôn ngữ lập trình:

Tuyên bố ra quyết định trong Lua

Ngôn ngữ lập trình Lua giả định bất kỳ sự kết hợp nào của các giá trị Boolean true và non-nil là true , và nếu nó là boolean false hoặc nil , thì nó được giả định là false . Cần lưu ý rằng trong Lua, số 0 sẽ được coi là đúng.

Ngôn ngữ lập trình Lua cung cấp các loại câu lệnh ra quyết định sau.

Sr.No.Tuyên bố & Mô tả
1câu lệnh ifMột khi tuyên bố bao gồm một biểu thức boolean theo sau là một hoặc nhiều câu lệnh.
2câu lệnh if … elseMột khi tuyên bố có thể được theo sau bởi một tùy chọn khác tuyên bố, mà thực hiện khi biểu thức boolean là sai.
3câu lệnh if lồng nhauBạn có thể sử dụng một câu lệnh if hoặc else if bên trong một câu lệnh if hoặc else if khác .

Lua – Chức năng

Hàm là một nhóm các câu lệnh cùng thực hiện một tác vụ. Bạn có thể chia mã của mình thành các chức năng riêng biệt. Cách bạn phân chia mã của mình giữa các chức năng khác nhau là tùy thuộc vào bạn, nhưng về mặt logic, sự phân chia thường là duy nhất, vì vậy mỗi chức năng thực hiện một nhiệm vụ cụ thể.

Ngôn ngữ Lua cung cấp nhiều phương thức tích hợp sẵn mà chương trình của bạn có thể gọi. Ví dụ, phương thức print () để in đối số được truyền dưới dạng đầu vào trong bảng điều khiển.

Một hàm được biết đến với nhiều tên khác nhau như một phương thức hoặc một quy trình con hoặc một thủ tục, v.v.

Xác định một chức năng

Dạng tổng quát của định nghĩa phương thức trong ngôn ngữ lập trình Lua như sau:

optional_function_scope function function_name( argument1, argument2, argument3........,  argumentn) function_body return result_params_comma_separated end 

Định nghĩa phương thức trong ngôn ngữ lập trình Lua bao gồm tiêu đề phương thức và thân phương thức . Đây là tất cả các phần của một phương pháp –

  • Phạm vi chức năng tùy chọn – Bạn có thể sử dụng từ khóa cục bộ để giới hạn phạm vi của hàm hoặc bỏ qua phần phạm vi, điều này sẽ làm cho nó trở thành một hàm toàn cục.
  • Tên hàm – Đây là tên thực của hàm. Tên hàm và danh sách tham số cùng nhau tạo thành chữ ký hàm.
  • Đối số – Một đối số giống như một trình giữ chỗ. Khi một hàm được gọi, bạn truyền một giá trị cho đối số. Giá trị này được gọi là tham số hoặc đối số thực tế. Danh sách tham số đề cập đến kiểu, thứ tự và số lượng các đối số của một phương thức. Đối số là tùy chọn; nghĩa là, một phương thức có thể không chứa đối số.
  • Phần thân của hàm – Phần thân của phương thức chứa một tập hợp các câu lệnh xác định chức năng của phương thức.
  • Return – Trong Lua, có thể trả về nhiều giá trị bằng cách theo sau từ khóa return với các giá trị trả về được phân tách bằng dấu phẩy.

Thí dụ

Sau đây là mã nguồn của một hàm có tên là max () . Hàm này nhận hai tham số num1 và num2 và trả về giá trị lớn nhất giữa hai tham số:

--[[ function returning the max between two numbers --]] function max(num1, num2)     if (num1 > num2) then       result = num1;    else       result = num2;    end     return result;  end

Đối số hàm

If a function is to use arguments, it must declare the variables that accept the values of the arguments. These variables are called the formal parameters of the function.

The formal parameters behave like other local variables inside the function and are created upon entry into the function and destroyed upon exit.

Calling a Function

While creating a Lua function, you give a definition of what the function has to do. To use a method, you will have to call that function to perform the defined task.

When a program calls a function, program control is transferred to the called function. A called function performs the defined task and when its return statement is executed or when its function’s end is reached, it returns program control back to the main program.

To call a method, you simply need to pass the required parameters along with the method name and if the method returns a value, then you can store the returned value. For example −Live Demo

function max(num1, num2)     if (num1 > num2) then       result = num1;    else       result = num2;    end     return result;  end  -- calling a function print("The maximum of the two numbers is ",max(10,4)) print("The maximum of the two numbers is ",max(5,6))

When we run the above code, we will get the following output.

The maximum of the two numbers is 	10 The maximum of the two numbers is 	6 

Assigning and Passing Functions

In Lua, we can assign the function to variables and also can pass them as parameters of another function. Here is a simple example for assigning and passing a function as parameter in Lua.Live Demo

myprint = function(param)    print("This is my print function -   ##",param,"##") end  function add(num1,num2,functionPrint)    result = num1 + num2    functionPrint(result) end  myprint(10) add(2,5,myprint)

When we run the above code, we will get the following output.

This is my print function -   ##	10	## This is my print function -   ##	7	## 

Function with Variable Argument

It is possible to create functions with variable arguments in Lua using ‘…’ as its parameter. We can get a grasp of this by seeing an example in which the function will return the average and it can take variable arguments.Live Demo

function average(...)    result = 0    local arg = {...}    for i,v in ipairs(arg) do       result = result + v    end    return result/#arg end  print("The average is",average(10,5,3,4,5,6))

When we run the above code, we will get the following output.

The average is	5.5 

Lua – Strings

String is a sequence of characters as well as control characters like form feed. String can be initialized with three forms which includes −

  • Characters between single quotes
  • Characters between double quotes
  • Characters between [[ and ]]

An example for the above three forms are shown below.Live Demo

string1 = "Lua" print("\"String 1 is\"",string1)  string2 = 'Tutorial' print("String 2 is",string2)  string3 = [["Lua Tutorial"]] print("String 3 is",string3)

When we run the above program, we will get the following output.

"String 1 is" Lua String 2 is	Tutorial String 3 is	"Lua Tutorial" 

Escape sequence characters are used in string to change the normal interpretation of characters. For example, to print double inverted commas (“”), we have used \” in the above example. The escape sequence and its use is listed below in the table.

Escape SequenceUse
\aBell
\bBackspace
\fFormfeed
\nNew line
\rCarriage return
\tTab
\vVertical tab
\\Backslash
\”Double quotes
\’Single quotes
\[Left square bracket
\]Right square bracket

String Manipulation

Lua supports string to manipulate strings −

Sr.No.Method & Purpose
1string.upper(argument)Returns a capitalized representation of the argument.
2string.lower(argument)Returns a lower case representation of the argument.
3string.gsub(mainString,findString,replaceString)Returns a string by replacing occurrences of findString with replaceString.
4string.find(mainString,findString,optionalStartIndex,optionalEndIndex)Returns the start index and end index of the findString in the main string and nil if not found.
5string.reverse(arg)Returns a string by reversing the characters of the passed string.
6string.format(…)Returns a formatted string.
7string.char(arg) and string.byte(arg)Returns internal numeric and character representations of input argument.
8string.len(arg)Returns a length of the passed string.
9string.rep(string, n))Returns a string by repeating the same string n number times.
10..Thus operator concatenates two strings.

Now, let’s dive into a few examples to exactly see how these string manipulation functions behave.

Case Manipulation

A sample code for manipulating the strings to upper and lower case is given below.Live Demo

string1 = "Lua";  print(string.upper(string1)) print(string.lower(string1))

When we run the above program, we will get the following output.

LUA lua 

Replacing a Substring

A sample code for replacing occurrences of one string with another is given below.Live Demo

string = "Lua Tutorial"  -- replacing strings newstring = string.gsub(string,"Tutorial","Language") print("The new string is "..newstring)

When we run the above program, we will get the following output.

The new string is Lua Language 

Finding and Reversing

A sample code for finding the index of substring and reversing string is given below.Live Demo

string = "Lua Tutorial"  -- replacing strings print(string.find(string,"Tutorial")) reversedString = string.reverse(string) print("The new string is",reversedString)

When we run the above program, we will get the following output.

5	12 The new string is	lairotuT auL 

Formatting Strings

Many times in our programming, we may need to print strings in a formatted way. You can use the string.format function to format the output as shown below.Live Demo

string1 = "Lua" string2 = "Tutorial"  number1 = 10 number2 = 20  -- Basic string formatting print(string.format("Basic formatting %s %s",string1,string2))  -- Date formatting date = 2; month = 1; year = 2014 print(string.format("Date formatting %02d/%02d/%03d", date, month, year))  -- Decimal formatting print(string.format("%.4f",1/3))

When we run the above program, we will get the following output.

Basic formatting Lua Tutorial Date formatting 02/01/2014 0.3333 

Character and Byte Representations

A sample code for character and byte representation, which is used for converting the string from string to internal representation and vice versa.Live Demo

-- Byte conversion  -- First character print(string.byte("Lua"))  -- Third character print(string.byte("Lua",3))  -- first character from last print(string.byte("Lua",-1))  -- Second character print(string.byte("Lua",2))  -- Second character from last print(string.byte("Lua",-2))  -- Internal Numeric ASCII Conversion print(string.char(97))

When we run the above program, we will get the following output.

76 97 97 117 117 a 

Other Common Functions

The common string manipulations include string concatenation, finding length of string and at times repeating the same string multiple times. The example for these operations is given below.Live Demo

string1 = "Lua" string2 = "Tutorial"  -- String Concatenations using .. print("Concatenated string",string1..string2)  -- Length of string print("Length of string1 is ",string.len(string1))  -- Repeating strings repeatedString = string.rep(string1,3) print(repeatedString)

When we run the above program, we will get the following output.

Concatenated string	LuaTutorial Length of string1 is 	3 LuaLuaLua 

Lua – Arrays

Arrays are ordered arrangement of objects, which may be a one-dimensional array containing a collection of rows or a multi-dimensional array containing multiple rows and columns.

In Lua, arrays are implemented using indexing tables with integers. The size of an array is not fixed and it can grow based on our requirements, subject to memory constraints.

One-Dimensional Array

A one-dimensional array can be represented using a simple table structure and can be initialized and read using a simple for loop. An example is shown below.Live Demo

array = {"Lua", "Tutorial"}  for i = 0, 2 do    print(array[i]) end

When we run the above code, we wil get the following output.

nil Lua Tutorial 

As you can see in the above code, when we are trying to access an element in an index that is not there in the array, it returns nil. In Lua, indexing generally starts at index 1. But it is possible to create objects at index 0 and below 0 as well. Array using negative indices is shown below where we initialize the array using a for loop.Live Demo

array = {}  for i= -2, 2 do    array[i] = i *2 end  for i = -2,2 do    print(array[i]) end

When we run the above code, we will get the following output.

-4 -2 0 2 4 

Multi-Dimensional Array

Multi-dimensional arrays can be implemented in two ways.

  • Array of arrays
  • Single dimensional array by manipulating indices

An example for multidimensional array of 3. 3 is shown below using array of arrays.Live Demo

-- Initializing the array array = {}  for i=1,3 do    array[i] = {} 	    for j=1,3 do       array[i][j] = i*j    end 	 end  -- Accessing the array  for i=1,3 do     for j=1,3 do       print(array[i][j])    end 	 end

When we run the above code, we will get the following output.

1 2 3 2 4 6 3 6 9 

An example for multidimensional array is shown below using manipulating indices.Live Demo

-- Initializing the array  array = {}  maxRows = 3 maxColumns = 3  for row=1,maxRows do     for col=1,maxColumns do       array[row*maxColumns +col] = row*col    end 	 end  -- Accessing the array  for row=1,maxRows do     for col=1,maxColumns do       print(array[row*maxColumns +col])    end 	 end

When we run the above code, we will get the following output.

1 2 3 2 4 6 3 6 9 

As you can see in the above example, data is stored based on indices. It is possible to place the elements in a sparse way and it is the way Lua implementation of a matrix works. Since it does not store nil values in Lua, it is possible to save lots of memory without any special technique in Lua as compared to special techniques used in other programming languages.

Lua – Iterators

Iterator is a construct that enables you to traverse through the elements of the so called collection or container. In Lua, these collections often refer to tables, which are used to create various data structures like array.

Generic For Iterator

A generic for iterator provides the key value pairs of each element in the collection. A simple example is given below.Live Demo

array = {"Lua", "Tutorial"}  for key,value in ipairs(array)  do    print(key, value) end

When we run the above code, we will get the following output −

1  Lua 2  Tutorial 

The above example uses the default ipairs iterator function provided by Lua.

In Lua we use functions to represent iterators. Based on the state maintenance in these iterator functions, we have two main types −

  • Stateless Iterators
  • Stateful Iterators

Stateless Iterators

By the name itself we can understand that this type of iterator function does not retain any state.

Let us now see an example of creating our own iterator using a simple function that prints the squares of n numbers.Live Demo

function square(iteratorMaxCount,currentNumber)     if currentNumber<iteratorMaxCount    then       currentNumber = currentNumber+1       return currentNumber, currentNumber*currentNumber    end 	 end  for i,n in square,3,0 do    print(i,n) end

When we run the above program, we will get the following output.

1	1 2	4 3	9 

The above code can be modified slightly to mimic the way ipairs function of iterators work. It is shown below.Live Demo

function square(iteratorMaxCount,currentNumber)     if currentNumber<iteratorMaxCount    then       currentNumber = currentNumber+1       return currentNumber, currentNumber*currentNumber    end 	 end  function squares(iteratorMaxCount)    return square,iteratorMaxCount,0 end    for i,n in squares(3) do     print(i,n) end

When we run the above program, we will get the following output.

1	1 2	4 3	9 

Stateful Iterators

The previous example of iteration using function does not retain the state. Each time the function is called, it returns the next element of the collection based on a second variable sent to the function. To hold the state of the current element, closures are used. Closure retain variables values across functions calls. To create a new closure, we create two functions including the closure itself and a factory, the function that creates the closure.

Let us now see an example of creating our own iterator in which we will be using closures.Live Demo

array = {"Lua", "Tutorial"}  function elementIterator (collection)     local index = 0    local count = #collection 	    -- The closure function is returned 	    return function ()       index = index + 1 		       if index <= count       then          -- return the current element of the iterator          return collection[index]       end 		    end 	 end  for element in elementIterator(array) do    print(element) end

When we run the above program, we will get the following output.

Lua Tutorial 

In the above example, we can see that elementIterator has another method inside that uses the local external variables index and count to return each of the element in the collection by incrementing the index each time the function is called.

We can create our own function iterators using closure as shown above and it can return multiple elements for each of the time we iterate through the collection.

Lua – Tables

Introduction

Tables are the only data structure available in Lua that helps us create different types like arrays and dictionaries. Lua uses associative arrays and which can be indexed with not only numbers but also with strings except nil. Tables have no fixed size and can grow based on our need.

Lua uses tables in all representations including representation of packages. When we access a method string.format, it means, we are accessing the format function available in the string package.

Representation and Usage

Tables are called objects and they are neither values nor variables. Lua uses a constructor expression {} to create an empty table. It is to be known that there is no fixed relationship between a variable that holds reference of table and the table itself.

--sample table initialization mytable = {}  --simple table value assignment mytable[1]= "Lua"  --removing reference mytable = nil  -- lua garbage collection will take care of releasing memory 

When we have a table a with set of elements and if we assign it to b, both a and b refer to the same memory. No separate memory is allocated separately for b. When a is set to nil, table will be still accessible to b. When there are no reference to a table, then garbage collection in Lua takes care of cleaning up process to make these unreferenced memory to be reused again.

An example is shown below for explaining the above mentioned features of tables.

-- Simple empty table mytable = {} print("Type of mytable is ",type(mytable))  mytable[1]= "Lua" mytable["wow"] = "Tutorial"  print("mytable Element at index 1 is ", mytable[1]) print("mytable Element at index wow is ", mytable["wow"])  -- alternatetable and mytable refers to same table alternatetable = mytable  print("alternatetable Element at index 1 is ", alternatetable[1]) print("alternatetable Element at index wow is ", alternatetable["wow"])  alternatetable["wow"] = "I changed it"  print("mytable Element at index wow is ", mytable["wow"])  -- only variable released and and not table alternatetable = nil print("alternatetable is ", alternatetable)  -- mytable is still accessible print("mytable Element at index wow is ", mytable["wow"])  mytable = nil print("mytable is ", mytable)

When we run the above program we will get the following output −

Type of mytable is 	table mytable Element at index 1 is 	Lua mytable Element at index wow is 	Tutorial alternatetable Element at index 1 is 	Lua alternatetable Element at index wow is 	Tutorial mytable Element at index wow is 	I changed it alternatetable is 	nil mytable Element at index wow is 	I changed it mytable is 	nil 

Table Manipulation

There are in built functions for table manipulation and they are listed in the following table.

Sr.No.Method & Purpose
1table.concat (table [, sep [, i [, j]]])Nối các chuỗi trong bảng dựa trên các tham số đã cho. Xem ví dụ để biết chi tiết.
2table.insert (table, [pos,] value)Chèn một giá trị vào bảng ở vị trí đã chỉ định.
3table.maxn (bảng)Trả về chỉ mục số lớn nhất.
4table.remove (table [, pos])Xóa giá trị khỏi bảng.
5table.sort (table [, comp])Sắp xếp bảng dựa trên đối số so sánh tùy chọn.

Hãy cùng chúng tôi xem một số mẫu của các chức năng trên.

Kết nối bảng

Chúng ta có thể sử dụng hàm concat để ghép hai bảng như hình dưới đây:Bản thử trực tiếp

fruits = {"banana","orange","apple"}  -- returns concatenated string of table print("Concatenated string ",table.concat(fruits))  --concatenate with a character print("Concatenated string ",table.concat(fruits,", "))  --concatenate fruits based on index print("Concatenated string ",table.concat(fruits,", ", 2,3))

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Concatenated string 	bananaorangeapple Concatenated string 	banana, orange, apple Concatenated string 	orange, apple 

Chèn và Xóa

Việc chèn và loại bỏ các mục trong bảng là phổ biến nhất trong thao tác trên bảng. Nó được giải thích dưới đây.Bản thử trực tiếp

fruits = {"banana","orange","apple"}  -- insert a fruit at the end table.insert(fruits,"mango") print("Fruit at index 4 is ",fruits[4])  --insert fruit at index 2 table.insert(fruits,2,"grapes") print("Fruit at index 2 is ",fruits[2])  print("The maximum elements in table is",table.maxn(fruits))  print("The last element is",fruits[5])  table.remove(fruits) print("The previous last element is",fruits[5])

Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được kết quả sau:

Fruit at index 4 is 	mango Fruit at index 2 is 	grapes The maximum elements in table is	5 The last element is	mango The previous last element is	nil 

Bảng phân loại

Chúng tôi thường yêu cầu sắp xếp một bảng theo một thứ tự cụ thể. Các hàm sắp xếp sắp xếp các phần tử trong bảng theo thứ tự bảng chữ cái. Một mẫu cho điều này được hiển thị dưới đây.Bản thử trực tiếp

fruits = {"banana","orange","apple","grapes"}  for k,v in ipairs(fruits) do    print(k,v) end  table.sort(fruits) print("sorted table")  for k,v in ipairs(fruits) do    print(k,v) end

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

1	banana 2	orange 3	apple 4	grapes sorted table 1	apple 2	banana 3	grapes 4	orange 

Lua – Mô-đun

Mô-đun là gì?

Mô-đun giống như một thư viện có thể được tải bằng cách sử dụng request và có một tên chung duy nhất chứa một bảng. Mô-đun này có thể bao gồm một số hàm và biến. Tất cả các hàm và biến này được bao bọc trong bảng, đóng vai trò như một không gian tên. Ngoài ra, một mô-đun hoạt động tốt có các điều khoản cần thiết để trả lại bảng này theo yêu cầu.

Tính đặc biệt của Mô-đun Lua

The usage of tables in modules helps us in numerous ways and enables us to manipulate the modules in the same way we manipulate any other Lua table. As a result of the ability to manipulate modules, it provides extra features for which other languages need special mechanisms. Due to this free mechanism of modules in Lua, a user can call the functions in Lua in multiple ways. A few of them are shown below.

-- Assuming we have a module printFormatter -- Also printFormatter has a funtion simpleFormat(arg) -- Method 1 require "printFormatter" printFormatter.simpleFormat("test")  -- Method 2 local formatter = require "printFormatter" formatter.simpleFormat("test")  -- Method 3 require "printFormatter" local formatterFunction = printFormatter.simpleFormat formatterFunction("test")

In the above sample code, you can see how flexible programming in Lua is, without any special additional code.

The require Function

Lua has provided a high level function called require to load all the necessary modules. It is kept as simple as possible to avoid having too much information on module to load it. The require function just assumes the modules as a chunk of code that defines some values, which is actually functions or tables containing functions.

Example

Let us consider a simple example, where one function has the math functions. Let’s call this module as mymath and filename being mymath.lua. The file content is as follows −

local mymath =  {}  function mymath.add(a,b)    print(a+b) end  function mymath.sub(a,b)    print(a-b) end  function mymath.mul(a,b)    print(a*b) end  function mymath.div(a,b)    print(a/b) end  return mymath	

Now, in order to access this Lua module in another file, say, moduletutorial.lua, you need to use the following code segment.

mymathmodule = require("mymath") mymathmodule.add(10,20) mymathmodule.sub(30,20) mymathmodule.mul(10,20) mymathmodule.div(30,20)

In order to run this code, we need to place the two Lua files in the same directory or alternatively, you can place the module file in the package path and it needs additional setup. When we run the above program, we will get the following output.

30 10 200 1.5 

Things to Remember

  • Place both the modules and the file you run in the same directory.
  • Module name and its file name should be the same.
  • It is a best practice to return modules for require function and hence the module should be preferably implemented as shown above eventhough you can find other types of implementations elsewhere.

Old Way of Implementing Modules

Let me now rewrite the same example in the older way, which uses package.seeall type of implementation. This was used in Lua versions 5.1 and 5.0. The mymath module is shown below.

module("mymath", package.seeall)  function mymath.add(a,b)    print(a+b) end  function mymath.sub(a,b)    print(a-b) end  function mymath.mul(a,b)    print(a*b) end  function mymath.div(a,b)    print(a/b) end

The usage of modules in moduletutorial.lua is shown below.

require("mymath") mymath.add(10,20) mymath.sub(30,20) mymath.mul(10,20) mymath.div(30,20)

When we run the above, we will get the same output. But it is advised on to use the older version of the code and it is assumed to less secure. Many SDKs that use Lua for programming like Corona SDK has deprecated the use of this.

Lua – Metatables

A metatable is a table that helps in modifying the behavior of a table it is attached to with the help of a key set and related meta methods. These meta methods are powerful Lua functionality that enables features like −

  • Changing/adding functionalities to operators on tables.
  • Looking up metatables when the key is not available in the table using __index in metatable.

There are two important methods that are used in handling metatables which includes −

  • setmetatable(table,metatable) − This method is used to set metatable for a table.
  • getmetatable (table) – Phương pháp này được sử dụng để lấy metatable của một bảng.

Trước tiên, hãy xem cách đặt một bảng giống như một bảng khác. Nó được hiển thị bên dưới.

mytable = {} mymetatable = {} setmetatable(mytable,mymetatable) 

Đoạn mã trên có thể được biểu diễn trong một dòng như hình dưới đây.

mytable = setmetatable({},{}) 

_mục lục

Dưới đây là một ví dụ đơn giản về khả năng đáp ứng để tra cứu bảng meta khi nó không có sẵn trong bảng.Bản thử trực tiếp

mytable = setmetatable({key1 = "value1"}, {    __index = function(mytable, key) 	       if key == "key2" then          return "metatablevalue"       else          return mytable[key]       end    end })  print(mytable.key1,mytable.key2)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

value1 metatablevalue 

Hãy để chúng tôi giải thích những gì đã xảy ra trong ví dụ trên theo các bước.

  • Mytable ở đây là {key1 = “value1”} .
  • Metatable được đặt cho mytable có chứa một hàm cho __index, mà chúng tôi gọi là metamethod.
  • Metamethod thực hiện một công việc đơn giản là tìm kiếm một chỉ mục “key2”, nếu nó được tìm thấy, nó sẽ trả về “metatablevalue”, nếu không thì trả về giá trị của mytable cho chỉ mục tương ứng.

Chúng ta có thể có một phiên bản đơn giản của chương trình trên như hình dưới đây.

mytable = setmetatable({key1 = "value1"},     { __index = { key2 = "metatablevalue" } }) print(mytable.key1,mytable.key2)

__newindex

Khi chúng tôi thêm __newindex vào metatable, nếu các khóa không có sẵn trong bảng, hoạt động của các khóa mới sẽ được xác định bằng các phương thức meta. Dưới đây là một ví dụ đơn giản trong đó chỉ mục của metatable được đặt khi chỉ mục không có sẵn trong bảng chính.Bản thử trực tiếp

mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })  print(mytable.key1)  mytable.newkey = "new value 2" print(mytable.newkey,mymetatable.newkey)  mytable.key1 = "new  value 1" print(mytable.key1,mymetatable.newkey1)

Khi bạn chạy chương trình trên, bạn nhận được kết quả sau.

value1 nil	new value 2 new  value 1	nil 

Bạn có thể thấy trong chương trình trên, nếu một khóa tồn tại trong bảng chính, nó chỉ cập nhật nó. Khi một khóa không có sẵn trong phần có thể bảo trì, nó sẽ thêm khóa đó vào phần có thể đo được.

Một ví dụ khác cập nhật cùng một bảng bằng cách sử dụng hàm rawset được hiển thị bên dưới.Bản thử trực tiếp

mytable = setmetatable({key1 = "value1"}, {     __newindex = function(mytable, key, value)       rawset(mytable, key, "\""..value.."\"")    end })  mytable.key1 = "new value" mytable.key2 = 4  print(mytable.key1,mytable.key2)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

new value	"4" 

rawset đặt giá trị mà không sử dụng __newindex có thể đo được. Tương tự, có rawget nhận giá trị mà không cần sử dụng __index.

Thêm Hành vi của Người vận hành vào Bảng

Dưới đây là một ví dụ đơn giản để kết hợp hai bảng bằng cách sử dụng + toán tử:Bản thử trực tiếp

mytable = setmetatable({ 1, 2, 3 }, {    __add = function(mytable, newtable) 	       for i = 1, table.maxn(newtable) do          table.insert(mytable, table.maxn(mytable)+1,newtable[i])       end       return mytable    end })  secondtable = {4,5,6}  mytable = mytable + secondtable  for k,v in ipairs(mytable) do    print(k,v) end

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

1	1 2	2 3	3 4	4 5	5 6	6 

Khóa __add được bao gồm trong biến thể để thêm hành vi của toán tử +. Bảng các phím và toán tử tương ứng được hiển thị bên dưới.

Sr.No.Chế độ & Mô tả
1__cộngThay đổi hành vi của toán tử ‘+’.
2__subThay đổi hành vi của toán tử ‘-‘.
3__mulThay đổi hành vi của toán tử ‘*’.
4__divThay đổi hành vi của toán tử ‘/’.
5__modThay đổi hành vi của toán tử ‘%’.
6__unmThay đổi hành vi của toán tử ‘-‘.
7__concatThay đổi hành vi của toán tử ‘..’.
số 8__eqThay đổi hành vi của toán tử ‘==’.
9__ltThay đổi hành vi của toán tử ‘<‘.
10__leThay đổi hành vi của toán tử ‘<=’.

__gọi

Việc thêm hành vi của cuộc gọi phương thức được thực hiện bằng cách sử dụng câu lệnh __call. Một ví dụ đơn giản trả về tổng các giá trị trong bảng chính với bảng đã truyền.Bản thử trực tiếp

mytable = setmetatable({10}, {    __call = function(mytable, newtable)    sum = 0 	       for i = 1, table.maxn(mytable) do          sum = sum + mytable[i]       end 	       for i = 1, table.maxn(newtable) do          sum = sum + newtable[i]       end 	       return sum    end })  newtable = {10,20,30} print(mytable(newtable))

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

70 

__tostring

Để thay đổi hành vi của câu lệnh print, chúng ta có thể sử dụng metamethod __tostring. Một ví dụ đơn giản được hiển thị bên dưới.Bản thử trực tiếp

mytable = setmetatable({ 10, 20, 30 }, {    __tostring = function(mytable)    sum = 0 	       for k, v in pairs(mytable) do          sum = sum + v       end 		       return "The sum of values in the table is " .. sum    end }) print(mytable)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

The sum of values in the table is 60 

Nếu bạn biết đầy đủ các khả năng của bảng meta, bạn thực sự có thể thực hiện nhiều thao tác sẽ rất phức tạp mà không cần sử dụng đến nó. Vì vậy, hãy cố gắng làm việc nhiều hơn với việc sử dụng các bảng đo lường với các tùy chọn khác nhau có sẵn trong bảng meta như được giải thích trong các mẫu và cũng tạo mẫu của riêng bạn.

Lua – Coroutines

Giới thiệu

Coroutines về bản chất là hợp tác, cho phép hai hoặc nhiều phương pháp thực thi một cách có kiểm soát. Với coroutines, tại bất kỳ thời điểm nào, chỉ một quy trình đăng ký chạy và quy trình đăng ký đang chạy này chỉ tạm ngừng thực thi khi nó yêu cầu tạm dừng một cách rõ ràng.

Định nghĩa trên có thể trông mơ hồ. Giả sử chúng ta có hai phương thức, một phương thức chương trình chính và một phương thức đăng quang. Khi chúng ta gọi một trình điều chỉnh bằng cách sử dụng hàm tiếp tục, nó sẽ bắt đầu thực thi và khi chúng ta gọi hàm kết quả, nó sẽ tạm ngừng thực thi. Một lần nữa, cùng một quy trình đăng ký có thể tiếp tục thực thi với một lệnh gọi hàm tiếp tục khác từ nơi nó bị tạm dừng. Quá trình này có thể tiếp tục cho đến khi kết thúc quá trình điều tra.

Các chức năng có sẵn trong Coroutines

Bảng sau đây liệt kê tất cả các hàm có sẵn cho coroutines trong Lua và cách sử dụng tương ứng của chúng.

Sr.No.Phương pháp & Mục đích
1coroutine.create (f)Tạo một chương trình đăng quang mới với một hàm f và trả về một đối tượng kiểu “thread”.
2coroutine.resume (co [, val1, …])Tiếp tục đồng hành trình đăng quang và chuyển các tham số nếu có. Nó trả về trạng thái hoạt động và các giá trị trả về tùy chọn khác.
3coroutine.running ()Trả về quy trình đăng quang hoặc nil đang chạy nếu được gọi trong luồng chính.
4coroutine.status (đồng)Trả về một trong các giá trị đang chạy, bình thường, bị treo hoặc chết dựa trên trạng thái của quy trình đăng ký.
5coroutine.wrap (f)Giống như coroutine.create, hàm coroutine.wrap cũng tạo ra một coroutine, nhưng thay vì trả về chính hàm coroutine, nó trả về một hàm mà khi được gọi, sẽ tiếp tục lại hàm coroutine.
6coroutine.yield (…)Tạm dừng quy trình đăng ký đang chạy. Tham số được truyền cho phương thức này hoạt động như các giá trị trả về bổ sung cho hàm tiếp tục.

Thí dụ

Hãy xem một ví dụ để hiểu khái niệm về coroutines.Bản thử trực tiếp

co = coroutine.create(function (value1,value2)    local tempvar3 = 10    print("coroutine section 1", value1, value2, tempvar3) 	    local tempvar1 = coroutine.yield(value1+1,value2+1)    tempvar3 = tempvar3 + value1    print("coroutine section 2",tempvar1 ,tempvar2, tempvar3) 	    local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2)    tempvar3 = tempvar3 + value1    print("coroutine section 3",tempvar1,tempvar2, tempvar3)    return value2, "end" 	 end)  print("main", coroutine.resume(co, 3, 2)) print("main", coroutine.resume(co, 12,14)) print("main", coroutine.resume(co, 5, 6)) print("main", coroutine.resume(co, 10, 20))

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

coroutine section 1	3	2	10 main	true	4	3 coroutine section 2	12	nil	13 main	true	5	1 coroutine section 3	5	6	16 main	true	2	end main	false	cannot resume dead coroutine 

Ví dụ trên làm gì?

Như đã đề cập trước đây, chúng tôi sử dụng chức năng tiếp tục để bắt đầu hoạt động và chức năng lợi nhuận để dừng hoạt động. Ngoài ra, bạn có thể thấy rằng có nhiều giá trị trả về nhận được bởi hàm tiếp tục của coroutine.

  • Đầu tiên, chúng ta tạo một chương trình đăng quang và gán nó cho một tên biến và chương trình đăng quang nhận hai biến làm tham số của nó.
  • Khi chúng ta gọi hàm tiếp tục đầu tiên, các giá trị 3 và 2 được giữ lại trong các biến tạm thời value1 và value2 cho đến cuối chương trình đăng quang.
  • Để bạn hiểu điều này, chúng tôi đã sử dụng tempvar3, ban đầu là 10 và nó được cập nhật lên 13 và 16 bởi các lệnh gọi tiếp theo của coroutines vì ​​value1 được giữ nguyên là 3 trong suốt quá trình thực thi coroutine.
  • Coroutine.yield đầu tiên trả về hai giá trị 4 và 3 cho hàm tiếp tục, chúng tôi nhận được giá trị này bằng cách cập nhật các tham số đầu vào 3 và 2 trong câu lệnh lợi nhuận. Nó cũng nhận được trạng thái đúng / sai của việc thực thi chương trình đăng quang.
  • Một điều khác về coroutines là cách xử lý các thông số tiếp theo của cuộc gọi sơ yếu lý lịch, trong ví dụ trên; bạn có thể thấy rằng biến coroutine.yield nhận các tham số cuộc gọi tiếp theo, cung cấp một cách mạnh mẽ để thực hiện hoạt động mới với quyền kiểm tra các giá trị tham số hiện có.
  • Cuối cùng, một khi tất cả các câu lệnh trong coroutines được thực thi, các lệnh gọi tiếp theo sẽ trả về false và câu lệnh “không thể tiếp tục coroutine đã chết” dưới dạng phản hồi.

Một ví dụ về thói quen khác

Chúng ta hãy xem xét một quy trình đăng quang đơn giản trả về một số từ 1 đến 5 với sự trợ giúp của hàm lợi nhuận và hàm tiếp tục. Nó tạo ra quy trình đăng ký nếu không có sẵn hoặc nếu không sẽ tiếp tục quy trình đăng ký hiện có.Bản thử trực tiếp

function getNumber()    local function getNumberHelper()       co = coroutine.create(function ()       coroutine.yield(1)       coroutine.yield(2)       coroutine.yield(3)       coroutine.yield(4)       coroutine.yield(5)       end)       return co    end 	    if(numberHelper) then       status, number = coroutine.resume(numberHelper); 		       if coroutine.status(numberHelper) == "dead" then          numberHelper = getNumberHelper()          status, number = coroutine.resume(numberHelper);       end 		       return number    else       numberHelper = getNumberHelper()       status, number = coroutine.resume(numberHelper);       return number    end 	 end  for index = 1, 10 do    print(index, getNumber()) end

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

1	1 2	2 3	3 4	4 5	5 6	1 7	2 8	3 9	4 10	5 

Thường có sự so sánh các coroutines với các thread của ngôn ngữ đa chương trình, nhưng chúng ta cần hiểu rằng coroutines có các tính năng tương tự của thread nhưng chúng chỉ thực thi một lần và không bao giờ thực thi đồng thời.

Chúng tôi kiểm soát trình tự thực hiện chương trình để đáp ứng nhu cầu với việc cung cấp tạm thời giữ lại một số thông tin nhất định. Sử dụng các biến toàn cục với coroutines cung cấp tính linh hoạt hơn cho coroutines.

Lua – Tệp I / O

Thư viện I / O được sử dụng để đọc và thao tác các tệp trong Lua. Có hai loại hoạt động tệp trong Lua cụ thể là bộ mô tả tệp ngầm định và bộ mô tả tệp rõ ràng.

Đối với các ví dụ sau, chúng tôi sẽ sử dụng tệp mẫu test.lua như hình dưới đây.

-- sample test.lua -- sample2 test.lua 

Một thao tác mở tệp đơn giản sử dụng câu lệnh sau.

file = io.open (filename [, mode]) 

Các chế độ tệp khác nhau được liệt kê trong bảng sau.

Sr.No.Chế độ & Mô tả
1“NS”Chế độ chỉ đọc và là chế độ mặc định nơi tệp hiện có được mở.
2“w”Chế độ đã bật ghi ghi đè lên tệp hiện có hoặc tạo tệp mới.
3“Một”Chế độ nối sẽ mở một tệp hiện có hoặc tạo một tệp mới để nối thêm.
4“r +”Chế độ đọc và ghi cho một tệp hiện có.
5“w +”Tất cả dữ liệu hiện có sẽ bị xóa nếu tệp tồn tại hoặc tệp mới được tạo với quyền đọc ghi.
6“a +”Chế độ nối với chế độ đọc được bật để mở tệp hiện có hoặc tạo tệp mới.

Trình mô tả tệp ngầm định

Các bộ mô tả tệp ngầm định sử dụng các chế độ đầu vào / đầu ra tiêu chuẩn hoặc sử dụng một tệp đầu vào và đầu ra duy nhất. Dưới đây là một ví dụ về cách sử dụng bộ mô tả tệp ngầm định.

-- Opens a file in read file = io.open("test.lua", "r")  -- sets the default input file as test.lua io.input(file)  -- prints the first line of the file print(io.read())  -- closes the open file io.close(file)  -- Opens a file in append mode file = io.open("test.lua", "a")  -- sets the default output file as test.lua io.output(file)  -- appends a word test to the last line of the file io.write("-- End of the test.lua file")  -- closes the open file io.close(file)

Khi bạn chạy chương trình, bạn sẽ nhận được đầu ra của dòng đầu tiên của tệp test.lua. Đối với chương trình của chúng tôi, chúng tôi nhận được kết quả sau.

-- Sample test.lua 

Đây là dòng đầu tiên của câu lệnh trong tệp test.lua cho chúng tôi. Ngoài ra, dòng “- End of the test.lua file” sẽ được thêm vào dòng cuối cùng của mã test.lua.

In the above example, you can see how the implicit descriptors work with file system using the io.”x” methods. The above example uses io.read() without the optional parameter. The optional parameter can be any of the following.

Sr.No.Mode & Description
1“*n”Reads from the current file position and returns a number if exists at the file position or returns nil.
2“*a”Returns all the contents of file from the current file position.
3“*l”Reads the line from the current file position, and moves file position to next line.
4numberReads number of bytes specified in the function.

Other common I/O methods includes,

  • io.tmpfile() − Returns a temporary file for reading and writing that will be removed once the program quits.
  • io.type(file) − Returns whether file, closed file or nil based on the input file.
  • io.flush() − Clears the default output buffer.
  • io.lines(optional file name) − Provides a generic for loop iterator that loops through the file and closes the file in the end, in case the file name is provided or the default file is used and not closed in the end of the loop.

Explicit File Descriptors

We often use explicit file descriptor which allows us to manipulate multiple files at a time. These functions are quite similar to implicit file descriptors. Here, we use file:function_name instead of io.function_name. The following example of the file version of the same implicit file descriptors example is shown below.

-- Opens a file in read mode file = io.open("test.lua", "r")  -- prints the first line of the file print(file:read())  -- closes the opened file file:close()  -- Opens a file in append mode file = io.open("test.lua", "a")  -- appends a word test to the last line of the file file:write("--test")  -- closes the open file file:close()

Khi bạn chạy chương trình, bạn sẽ nhận được một kết quả tương tự như ví dụ về bộ mô tả ngầm định.

-- Sample test.lua 

Tất cả các chế độ mở tệp và tham số để đọc cho các bộ mô tả bên ngoài đều giống như các bộ mô tả tệp ngầm định.

Các phương pháp tệp phổ biến khác bao gồm,

  • file: seek (thời điểm tùy chọn, độ lệch tùy chọn) – Tham số thời điểm là “set”, “cur” hoặc “end”. Đặt con trỏ tệp mới với vị trí tệp được cập nhật từ đầu tệp. Các hiệu số được dựa trên 0 trong chức năng này. Độ lệch được đo từ đầu tệp nếu đối số đầu tiên là “set”; từ vị trí hiện tại trong tệp nếu nó là “cur”; hoặc từ cuối tệp nếu nó là “kết thúc”. Các giá trị đối số mặc định là “cur” và 0, do đó, vị trí tệp hiện tại có thể nhận được bằng cách gọi hàm này mà không có đối số.
  • file: flush () – Xóa bộ đệm đầu ra mặc định.
  • io.lines (tên tệp tùy chọn) – Cung cấp trình lặp vòng lặp chung cho vòng lặp lặp qua tệp và đóng tệp cuối cùng, trong trường hợp tên tệp được cung cấp hoặc tệp mặc định được sử dụng và không được đóng ở cuối vòng lặp .

Dưới đây là một ví dụ để sử dụng phương pháp tìm kiếm. Nó đặt con trỏ khỏi 25 vị trí trước khi kết thúc tệp. Chức năng đọc in phần còn lại của tệp từ vị trí tìm kiếm.

-- Opens a file in read file = io.open("test.lua", "r")  file:seek("end",-25) print(file:read("*a"))  -- closes the opened file file:close()

Bạn sẽ nhận được một số đầu ra tương tự như sau.

sample2 test.lua --test 

Bạn có thể chơi xung quanh tất cả các chế độ và thông số khác nhau để biết toàn bộ khả năng hoạt động của tệp Lua.

Lua – Xử lý lỗi

Cần xử lý lỗi

Việc xử lý lỗi là khá quan trọng vì các hoạt động trong thế giới thực thường yêu cầu sử dụng các hoạt động phức tạp, bao gồm hoạt động tệp, giao dịch cơ sở dữ liệu và lệnh gọi dịch vụ web.

Trong bất kỳ lập trình nào, luôn có yêu cầu về xử lý lỗi. Lỗi có thể có hai loại bao gồm,

  • Lỗi cú pháp
  • Lỗi thời gian chạy

Lỗi cú pháp

Lỗi cú pháp xảy ra do việc sử dụng không đúng các thành phần chương trình khác nhau như toán tử và biểu thức. Dưới đây là một ví dụ đơn giản cho lỗi cú pháp.

a == 2 

Như bạn đã biết, có sự khác biệt giữa việc sử dụng đơn “bằng với” và kép “bằng với”. Sử dụng cái này thay vì cái kia có thể dẫn đến lỗi. Một “bằng với” đề cập đến phép gán trong khi một “bằng với” gấp đôi dùng để so sánh. Tương tự, chúng ta có các biểu thức và hàm có các cách triển khai được xác định trước.

Một ví dụ khác cho lỗi cú pháp được hiển thị bên dưới:Bản thử trực tiếp

for a= 1,10    print(a) end

Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được kết quả sau:

lua: test2.lua:2: 'do' expected near 'print' 

Lỗi cú pháp dễ xử lý hơn nhiều so với lỗi thời gian chạy vì trình thông dịch Lua định vị lỗi rõ ràng hơn so với trường hợp lỗi thời gian chạy. Từ lỗi trên, chúng ta có thể biết một cách dễ dàng rằng việc thêm một việc phải làm tuyên bố trước khi tuyên bố in được yêu cầu theo cấu trúc Lua.

Lỗi thời gian chạy

Trong trường hợp lỗi thời gian chạy, chương trình sẽ thực thi thành công, nhưng nó có thể dẫn đến lỗi thời gian chạy do sai sót trong đầu vào hoặc các hàm xử lý sai. Dưới đây là một ví dụ đơn giản để hiển thị lỗi thời gian chạy.Bản thử trực tiếp

function add(a,b)    return a+b end  add(10)

Khi chúng tôi xây dựng chương trình, nó sẽ xây dựng thành công và chạy. Khi nó chạy, hiển thị lỗi thời gian chạy.

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value) stack traceback: 	test2.lua:2: in function 'add' 	test2.lua:5: in main chunk 	[C]: ? 

Đây là lỗi thời gian chạy, đã xảy ra do không chuyển hai biến. Các b tham số được mong đợi và ở đây nó là con số không và tạo ra một lỗi.

Chức năng Khẳng định và Lỗi

Để xử lý lỗi, chúng ta thường sử dụng hai hàm – khẳng định và báo lỗi . Một ví dụ đơn giản được hiển thị bên dưới.Bản thử trực tiếp

local function add(a,b)    assert(type(a) == "number", "a is not a number")    assert(type(b) == "number", "b is not a number")    return a+b end  add(10)

Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được đầu ra lỗi sau.

lua: test2.lua:3: b is not a number stack traceback: 	[C]: in function 'assert' 	test2.lua:3: in function 'add' 	test2.lua:6: in main chunk 	[C]: ? 

Các lỗi (thông báo [, mức]) chấm dứt chức năng bảo vệ cuối cùng gọi và nhắn tin lợi nhuận như các thông báo lỗi. Lỗi hàm này không bao giờ trả về. Thông thường, lỗi thêm một số thông tin về vị trí lỗi ở đầu thư. Đối số mức chỉ định cách lấy vị trí lỗi. Với mức 1 (mặc định), vị trí lỗi là nơi hàm lỗi được gọi. Mức 2 chỉ lỗi đến nơi mà hàm được gọi là lỗi đã được gọi; và như thế. Vượt qua mức 0 sẽ tránh được việc bổ sung thông tin vị trí lỗi vào thông báo.

pcall và xpcall

Trong lập trình Lua, để tránh ném ra các lỗi này và xử lý các lỗi, chúng ta cần sử dụng các hàm pcall hoặc xpcall.

Hàm pcall (f, arg1, …) gọi hàm được yêu cầu ở chế độ được bảo vệ. Nếu một số lỗi xảy ra trong hàm f, nó không tạo ra lỗi. Nó chỉ trả về trạng thái lỗi. Dưới đây là một ví dụ đơn giản sử dụng pcall.Bản thử trực tiếp

function myfunction ()    n = n/nil end  if pcall(myfunction) then    print("Success") else 	print("Failure") end

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

Failure 

Hàm xpcall (f, err) gọi hàm được yêu cầu và cũng đặt trình xử lý lỗi. Bất kỳ lỗi nào bên trong f không được lan truyền; thay vào đó, xpcall bắt lỗi, gọi hàm err với đối tượng lỗi ban đầu và trả về mã trạng thái.

Một ví dụ đơn giản cho xpcall được hiển thị bên dưới.Bản thử trực tiếp

function myfunction ()    n = n/nil end  function myerrorhandler( err )    print( "ERROR:", err ) end  status = xpcall( myfunction, myerrorhandler ) print( status)

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

ERROR:	test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value) false 

Là một lập trình viên, điều quan trọng nhất là đảm bảo rằng bạn quan tâm đến việc xử lý lỗi thích hợp trong các chương trình bạn viết. Sử dụng xử lý lỗi có thể đảm bảo rằng các điều kiện bất ngờ ngoài điều kiện biên được xử lý mà không làm phiền người dùng chương trình.

Lua – Gỡ lỗi

Lua cung cấp một thư viện gỡ lỗi, cung cấp tất cả các chức năng nguyên thủy để chúng ta tạo trình gỡ lỗi của riêng mình. Mặc dù không có trình gỡ lỗi Lua tích hợp sẵn, chúng tôi có nhiều trình gỡ lỗi dành cho Lua, được tạo bởi nhiều nhà phát triển khác nhau với nhiều người là mã nguồn mở.

Các hàm có sẵn trong thư viện gỡ lỗi Lua được liệt kê trong bảng sau cùng với cách sử dụng của nó.

Sr.No.Phương pháp & Mục đích
1gỡ lỗi ()Vào chế độ tương tác để gỡ lỗi, chế độ này vẫn hoạt động cho đến khi chúng ta nhập chỉ cont trong một dòng và nhấn enter. Người dùng có thể kiểm tra các biến trong chế độ này bằng các chức năng khác.
2getfenv (đối tượng)Trả về môi trường của đối tượng.
3gethook (chủ đề tùy chọn)Trả về cài đặt móc hiện tại của luồng, dưới dạng ba giá trị – chức năng móc hiện tại, mặt nạ móc hiện tại và số móc hiện tại.
4getinfo (luồng tùy chọn, chức năng hoặc mức ngăn xếp, cờ tùy chọn)Trả về một bảng với thông tin về một hàm. Bạn có thể cung cấp hàm trực tiếp hoặc bạn có thể cung cấp một số làm giá trị của hàm, có nghĩa là hàm đang chạy ở hàm cấp của ngăn xếp cuộc gọi của luồng đã cho – cấp 0 là hàm hiện tại (chính là getinfo); mức 1 là chức năng được gọi là getinfo; và như thế. Nếu hàm là một số lớn hơn số hàm đang hoạt động, thì getinfo trả về nil.
5getlocal (luồng tùy chọn, mức ngăn xếp, chỉ mục cục bộ)Trả về tên và giá trị của biến cục bộ có chỉ mục cục bộ của hàm ở cấp độ ngăn xếp. Trả về giá trị nil nếu không có biến cục bộ nào với chỉ mục đã cho và phát sinh lỗi khi được gọi với cấp độ nằm ngoài phạm vi.
6có được (giá trị)Trả về khả năng gặp của đối tượng hoặc nil đã cho nếu đối tượng đó không có đối tượng có thể đo được.
7getregistry ()Trả về bảng đăng ký, một bảng được xác định trước có thể được sử dụng bởi bất kỳ mã C nào để lưu trữ bất kỳ giá trị Lua nào mà nó cần để lưu trữ.
số 8getupvalue (hàm, chỉ mục upvalue)Hàm này trả về tên và giá trị của giá trị tăng với chỉ mục của hàm func. Hàm trả về nil nếu không có giá trị tăng với chỉ số đã cho.
9setfenv (hàm hoặc luồng hoặc dữ liệu người dùng, bảng môi trường)Đặt môi trường của đối tượng đã cho vào bảng nhất định. Trả về đối tượng.
10sethook(optional thread, hook function, hook mask string with “c” and/or “r” and/or “l”, optional instruction count)Sets the given function as a hook. The string mask and the number count describes when the hook will be called. Here, c, r and l are called every time Lua calls, returns, and enters every line of code in a function respectively.
11setlocal(optional thread, stack level, local index, value)Assigns the value to the local variable with index local of the function at level of the stack. The function returns nil if there is no local variable with the given index, and raises an error when called with a level out of range. Otherwise, it returns the name of the local variable.
12setmetatable(value, metatable)Sets the metatable for the given object to the given table (which can be nil).
13setupvalue(function, upvalue index, value)This function assigns the value to the upvalue with index up of the function func. The function returns nil if there is no upvalue with the given index. Otherwise, it returns the name of the upvalue.
14traceback(optional thread, optional message string, optional level argument)Builds an extended error message with a traceback.

The above list is the complete list of debug functions in Lua and we often use a library that uses the above functions and provides easier debugging. Using these functions and creating our own debugger is quite complicated and is not preferable. Anyway, we will see an example of simple use of debugging functions.Live Demo

function myfunction ()    print(debug.traceback("Stack trace"))    print(debug.getinfo(1))    print("Stack trace end")     return 10 end  myfunction () print(debug.getinfo(1))

When we run the above program, we will get the stack trace as shown below.

Stack trace stack traceback: 	test2.lua:2: in function 'myfunction' 	test2.lua:8: in main chunk 	[C]: ? table: 0054C6C8 Stack trace end 

Trong chương trình mẫu trên, dấu vết ngăn xếp được in bằng cách sử dụng hàm debug.trace có sẵn trong thư viện gỡ lỗi. Debug.getinfo lấy bảng hiện tại của hàm.

Gỡ lỗi – Ví dụ

Chúng ta thường cần biết các biến cục bộ của một hàm để gỡ lỗi. Với mục đích đó, chúng ta có thể sử dụng getupvalue và để đặt các biến cục bộ này, chúng ta sử dụng setupvalue. Một ví dụ đơn giản cho điều này được hiển thị bên dưới.Bản thử trực tiếp

function newCounter ()    local n = 0    local k = 0 	    return function ()       k = n       n = n + 1       return n    end 	 end  counter = newCounter ()  print(counter()) print(counter())  local i = 1  repeat    name, val = debug.getupvalue(counter, i) 	    if name then       print ("index", i, name, "=", val) 		       if(name == "n") then          debug.setupvalue (counter,2,10)       end 		       i = i + 1    end -- if 	 until not name  print(counter())

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

1 2 index	1	k	=	1 index	2	n	=	2 11 

Trong ví dụ này, bộ đếm cập nhật từng cái một khi nó được gọi. Chúng ta có thể thấy trạng thái hiện tại của biến cục bộ bằng cách sử dụng hàm getupvalue. Sau đó, chúng tôi đặt biến cục bộ thành một giá trị mới. Ở đây, n là 2 trước khi hoạt động tập hợp được gọi. Sử dụng hàm setupvalue, nó được cập nhật lên 10. Bây giờ khi chúng ta gọi hàm counter, nó sẽ trả về 11 thay vì 3.

Các loại gỡ lỗi

  • Gỡ lỗi dòng lệnh
  • Gỡ lỗi đồ họa

Gỡ lỗi dòng lệnh

Gỡ lỗi dòng lệnh là loại gỡ lỗi sử dụng dòng lệnh để gỡ lỗi với sự trợ giúp của các lệnh và câu lệnh in. Có rất nhiều trình gỡ lỗi dòng lệnh có sẵn cho Lua, trong đó có một số trình gỡ rối được liệt kê bên dưới.

  • RemDebug – RemDebug là một trình gỡ lỗi từ xa cho Lua 5.0 và 5.1. Nó cho phép bạn kiểm soát việc thực thi một chương trình Lua khác từ xa, thiết lập các điểm ngắt và kiểm tra trạng thái hiện tại của chương trình. RemDebug cũng có thể gỡ lỗi các tập lệnh CGILua.
  • clidebugger – Trình gỡ lỗi giao diện dòng lệnh đơn giản cho Lua 5.1 được viết bằng Lua thuần túy. Nó không phụ thuộc vào bất kỳ thứ gì khác ngoài các thư viện Lua 5.1 tiêu chuẩn. Nó được lấy cảm hứng từ RemDebug nhưng không có cơ sở vật chất từ ​​xa.
  • ctrace – Một công cụ để theo dõi các lệnh gọi Lua API.
  • xdbLua – Trình gỡ lỗi dòng lệnh Lua đơn giản cho nền tảng Windows.
  • LuaInterface – Trình gỡ lỗi – Dự án này là một phần mở rộng trình gỡ lỗi cho LuaInterface. Nó nâng giao diện gỡ lỗi Lua được tích hợp sẵn lên một cấp độ cao hơn. Tương tác với trình gỡ lỗi được thực hiện bởi các sự kiện và các cuộc gọi phương thức.
  • Rldb – Đây là trình gỡ lỗi Lua từ xa thông qua socket, khả dụng trên cả Windows và Linux. Nó có thể cung cấp cho bạn nhiều tính năng hơn bất kỳ tính năng nào hiện có.
  • ModDebug – Điều này cho phép kiểm soát việc thực thi một chương trình Lua khác từ xa, thiết lập các điểm ngắt và kiểm tra trạng thái hiện tại của chương trình.

Gỡ lỗi đồ họa

Graphical debugging is available with the help of IDE where you are provided with visual debugging of various states like variable values, stack trace and other related information. There is a visual representation and step by step control of execution with the help of breakpoints, step into, step over and other buttons in the IDE.

There are number of graphical debuggers for Lua and it includes the following.

  • SciTE − The default windows IDE for Lua provides multiple debugging facilities like breakpoints, step, step into, step over, watch variables and so on.
  • Decoda − This is a graphical debugger with remote debugging support.
  • ZeroBrane Studio − Lua IDE with integrated remote debugger, stack view, watch view, remote console, static analyzer, and more. Works with LuaJIT, Love2d, Moai, and other Lua engines; Windows, OSX, and Linux. Open source.
  • akdebugger − Debugger and editor Lua plugin for Eclipse.
  • luaedit − This features remote debugging, local debugging, syntax highlighting, completion proposal list, parameter proposition engine, advance breakpoint management (including condition system on breakpoints and hit count), function listing, global and local variables listing, watches, solution oriented management.

Lua – Garbage Collection

Lua uses automatic memory management that uses garbage collection based on certain algorithms that is in-built in Lua. As a result of automatic memory management, as a developer −

  • No need to worry about allocating memory for objects.
  • No need to free them when no longer needed except for setting it to nil.

Lua uses a garbage collector that runs from time to time to collect dead objects when they are no longer accessible from the Lua program.

All objects including tables, userdata, functions, thread, string and so on are subject to automatic memory management. Lua uses incremental mark and sweep collector that uses two numbers to control its garbage collection cycles namely garbage collector pause and garbage collector step multiplier. These values are in percentage and value of 100 is often equal to 1 internally.

Garbage Collector Pause

Garbage collector pause is used for controlling how long the garbage collector needs to wait, before; it is called again by the Lua’s automatic memory management. Values less than 100 would mean that Lua will not wait for the next cycle. Similarly, higher values of this value would result in the garbage collector being slow and less aggressive in nature. A value of 200, means that the collector waits for the total memory in use to double before starting a new cycle. Hence, depending on the nature and speed of application, there may be a requirement to alter this value to get best performance in Lua applications.

Garbage Collector Step Multiplier

This step multiplier controls the relative speed of garbage collector to that of memory allocation in Lua program. Larger step values will lead to garbage collector to be more aggressive and it also increases the step size of each incremental step of garbage collection. Values less than 100 could often lead to avoid the garbage collector not to complete its cycle and its not generally preferred. The default value is 200, which means the garbage collector runs twice as the speed of memory allocation.

Garbage Collector Functions

As developers, we do have some control over the automatic memory management in Lua. For this, we have the following methods.

  • collectgarbage(“collect”) − Runs one complete cycle of garbage collection.
  • collectgarbage(“count”) − Returns the amount of memory currently used by the program in Kilobytes.
  • collectgarbage(“restart”) − If the garbage collector has been stopped, it restarts it.
  • collectgarbage(“setpause”) − Sets the value given as second parameter divided by 100 to the garbage collector pause variable. Its uses are as discussed a little above.
  • collectgarbage(“setstepmul”) − Sets the value given as second parameter divided by 100 to the garbage step multiplier variable. Its uses are as discussed a little above.
  • Collectgarbage (“bước”) – Chạy một bước thu gom rác. Đối số thứ hai càng lớn thì bước này sẽ càng lớn. Thu gom rác sẽ trả về true nếu bước được kích hoạt là bước cuối cùng của chu trình thu gom rác.
  • Collectgarbage (“dừng”) – Dừng bộ thu gom rác nếu nó đang chạy.

Dưới đây là một ví dụ đơn giản sử dụng ví dụ về bộ thu gom rác.Bản thử trực tiếp

mytable = {"apple", "orange", "banana"}  print(collectgarbage("count"))  mytable = nil  print(collectgarbage("count"))  print(collectgarbage("collect"))  print(collectgarbage("count"))

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau. Xin lưu ý rằng kết quả này sẽ thay đổi do sự khác biệt về loại hệ điều hành và cũng như tính năng quản lý bộ nhớ tự động của Lua.

23.1455078125   149 23.2880859375   295 0 22.37109375     380 

Bạn có thể thấy trong chương trình trên, khi việc thu dọn rác được thực hiện xong, nó sẽ làm giảm bộ nhớ được sử dụng. Nhưng, nó không bắt buộc phải gọi này. Ngay cả khi chúng tôi không gọi chúng, nó sẽ được trình thông dịch Lua thực thi tự động ở giai đoạn sau sau khoảng thời gian được xác định trước.

Rõ ràng, chúng ta có thể thay đổi hành vi của bộ thu gom rác bằng cách sử dụng các chức năng này nếu được yêu cầu. Các chức năng này cung cấp một chút khả năng bổ sung cho nhà phát triển để xử lý các tình huống phức tạp. Tùy thuộc vào loại bộ nhớ cần cho chương trình, bạn có thể sử dụng hoặc không sử dụng tính năng này. Nhưng sẽ rất hữu ích khi biết mức sử dụng bộ nhớ trong các ứng dụng và kiểm tra nó trong quá trình lập trình để tránh kết quả không mong muốn sau khi triển khai.

Lua – Hướng đối tượng

Giới thiệu về OOP

Lập trình hướng đối tượng (OOP), là một trong những kỹ thuật lập trình được sử dụng nhiều nhất trong thời đại lập trình hiện đại. Có một số ngôn ngữ lập trình hỗ trợ OOP, bao gồm,

  • C ++
  • Java
  • Objective-C
  • Smalltalk
  • NS#
  • Ruby

Đặc điểm của OOP

  • Lớp – Lớp là một khuôn mẫu có thể mở rộng để tạo các đối tượng, cung cấp các giá trị ban đầu cho trạng thái (các biến thành viên) và triển khai hành vi.
  • Đối tượng – Nó là một thể hiện của lớp và có bộ nhớ riêng được cấp phát cho chính nó.
  • Kế thừa – Là một khái niệm mà các biến và hàm của một lớp này được kế thừa bởi một lớp khác.
  • Đóng gói – Đây là quá trình kết hợp dữ liệu và các chức năng bên trong một lớp. Dữ liệu có thể được truy cập bên ngoài lớp với sự trợ giúp của các hàm. Nó còn được gọi là trừu tượng hóa dữ liệu.

OOP trong Lua

Bạn có thể triển khai hướng đối tượng trong Lua với sự trợ giúp của bảng và các hàm lớp đầu tiên của Lua. Bằng cách đặt các chức năng và dữ liệu liên quan vào một bảng, một đối tượng được hình thành. Kế thừa có thể được thực hiện với sự trợ giúp của các bảng đo lường, cung cấp cơ chế tra cứu các hàm (phương thức) và trường không tồn tại trong (các) đối tượng mẹ.

Các bảng trong Lua có các tính năng của đối tượng như trạng thái và danh tính độc lập với các giá trị của nó. Hai đối tượng (bảng) có cùng giá trị là các đối tượng khác nhau, ngược lại một đối tượng có thể có giá trị khác nhau tại các thời điểm khác nhau, nhưng nó luôn là cùng một đối tượng. Giống như các đối tượng, các bảng có một vòng đời độc lập với việc ai đã tạo ra chúng hoặc nơi chúng được tạo ra.

Một ví dụ về thế giới thực

Khái niệm hướng đối tượng được sử dụng rộng rãi nhưng bạn cần hiểu rõ về nó để có lợi ích tối đa và phù hợp.

Chúng ta hãy xem xét một ví dụ toán học đơn giản. Chúng tôi thường gặp những tình huống khi chúng tôi làm việc trên các hình dạng khác nhau như hình tròn, hình chữ nhật và hình vuông.

The shapes can have a common property Area. So, we can extend other shapes from the base object shape with the common property area. Each of the shapes can have its own properties and functions like a rectangle can have properties length, breadth, area as its properties and printArea and calculateArea as its functions.

Creating a Simple Class

A simple class implementation for a rectangle with three properties area, length, and breadth is shown below. It also has a printArea function to print the area calculated.

-- Meta class Rectangle = {area = 0, length = 0, breadth = 0}  -- Derived class method new  function Rectangle:new (o,length,breadth)    o = o or {}    setmetatable(o, self)    self.__index = self    self.length = length or 0    self.breadth = breadth or 0    self.area = length*breadth;    return o end  -- Derived class method printArea  function Rectangle:printArea ()    print("The area of Rectangle is ",self.area) end

Creating an Object

Creating an object is the process of allocating memory for the class instance. Each of the objects has its own memory and share the common class data.

r = Rectangle:new(nil,10,20) 

Accessing Properties

We can access the properties in the class using the dot operator as shown below −

print(r.length) 

Accessing Member Function

You can access a member function using the colon operator with the object as shown below −

r:printArea() 

The memory gets allocated and the initial values are set. The initialization process can be compared to constructors in other object oriented languages. It is nothing but a function that enables setting values as shown above.

Complete Example

Lets look at a complete example using object orientation in Lua.Live Demo

-- Meta class Shape = {area = 0}  -- Base class method new  function Shape:new (o,side)    o = o or {}    setmetatable(o, self)    self.__index = self    side = side or 0    self.area = side*side;    return o end  -- Base class method printArea  function Shape:printArea ()    print("The area is ",self.area) end  -- Creating an object myshape = Shape:new(nil,10)  myshape:printArea()

When you run the above program, you will get the following output.

The area is 	100 

Inheritance in Lua

Inheritance is the process of extending simple base objects like shape to rectangles, squares and so on. It is often used in the real world to share and extend the basic properties and functions.

Let us see a simple class extension. We have a class as shown below.

-- Meta class Shape = {area = 0}  -- Base class method new  function Shape:new (o,side)    o = o or {}    setmetatable(o, self)    self.__index = self    side = side or 0    self.area = side*side;    return o end  -- Base class method printArea  function Shape:printArea ()    print("The area is ",self.area) end

We can extend the shape to a square class as shown below.

Square = Shape:new()  -- Derived class method new  function Square:new (o,side)    o = o or Shape:new(o,side)    setmetatable(o, self)    self.__index = self    return o end

Over-riding Base Functions

Chúng ta có thể ghi đè các hàm của lớp cơ sở thay vì sử dụng hàm trong lớp cơ sở, lớp dẫn xuất có thể có triển khai riêng của nó như được hiển thị bên dưới:

-- Derived class method printArea  function Square:printArea ()    print("The area of square is ",self.area) end

Ví dụ hoàn chỉnh về thừa kế

Chúng ta có thể mở rộng việc triển khai lớp đơn giản trong Lua như được hiển thị ở trên với sự trợ giúp của một phương thức mới khác với sự trợ giúp của các bảng đo lường. Tất cả các biến thành viên và hàm của lớp cơ sở được giữ lại trong lớp dẫn xuất.Bản thử trực tiếp

-- Meta class Shape = {area = 0}  -- Base class method new  function Shape:new (o,side)    o = o or {}    setmetatable(o, self)    self.__index = self    side = side or 0    self.area = side*side;    return o end  -- Base class method printArea  function Shape:printArea ()    print("The area is ",self.area) end  -- Creating an object myshape = Shape:new(nil,10) myshape:printArea()  Square = Shape:new()  -- Derived class method new  function Square:new (o,side)    o = o or Shape:new(o,side)    setmetatable(o, self)    self.__index = self    return o end  -- Derived class method printArea  function Square:printArea ()    print("The area of square is ",self.area) end  -- Creating an object mysquare = Square:new(nil,10) mysquare:printArea()  Rectangle = Shape:new()  -- Derived class method new  function Rectangle:new (o,length,breadth)    o = o or Shape:new(o)    setmetatable(o, self)    self.__index = self    self.area = length * breadth    return o end  -- Derived class method printArea  function Rectangle:printArea ()     print("The area of Rectangle is ",self.area) end  -- Creating an object  myrectangle = Rectangle:new(nil,10,20) myrectangle:printArea()

Khi chúng tôi chạy chương trình trên, chúng tôi sẽ nhận được kết quả sau:

The area is 	100 The area of square is 	100 The area of Rectangle is 	200 

Trong ví dụ trên, chúng ta đã tạo hai lớp dẫn xuất – Hình chữ nhật và Hình vuông từ Lớp cơ sở Square. Có thể ghi đè các chức năng của lớp cơ sở trong lớp dẫn xuất. Trong ví dụ này, lớp dẫn xuất sẽ ghi đè hàm printArea.

Lua – Lập trình Web

Lua là một ngôn ngữ có tính linh hoạt cao và nó thường được sử dụng trên nhiều nền tảng bao gồm các ứng dụng web. Cộng đồng Kepler được thành lập vào năm 2004 để cung cấp các thành phần web mã nguồn mở trong Lua.

Mặc dù có những web framework khác sử dụng Lua đã được phát triển, chúng tôi sẽ chủ yếu tập trung vào các thành phần do cộng đồng Kepler cung cấp.

Ứng dụng và Khung công tác

  • Orbit là một khung công tác web MVC cho Lua, dựa trên WSAPI.
  • WSAPI là API tóm tắt máy chủ lưu trữ web từ các ứng dụng web Lua và là cơ sở cho nhiều dự án.
  • Xavante là một máy chủ Lua Web cung cấp giao diện WSAPI.
  • Sputnik là một wiki / CMS được phát triển qua WSAPI trên Dự án Kepler được sử dụng để hài hước và giải trí.
  • CGILua cung cấp tính năng tạo trang web LuaPages và LuaScripts, dựa trên WSAPI nhưng không còn được hỗ trợ. Thay vào đó, hãy sử dụng Orbit, Sputnik hoặc WSAPI.

Trong hướng dẫn này, chúng tôi sẽ cố gắng làm cho bạn hiểu những gì Lua có thể làm và để biết thêm về cách cài đặt và sử dụng nó, hãy tham khảo trang web của kepler

Quỹ đạo

Orbit là một khung công tác web MVC cho Lua. Nó hoàn toàn từ bỏ mô hình “tập lệnh” CGILua để ủng hộ các ứng dụng, trong đó mỗi ứng dụng Orbit có thể nằm gọn trong một tệp duy nhất, nhưng bạn có thể chia nó thành nhiều tệp nếu bạn muốn.

Tất cả các ứng dụng Orbit đều tuân theo giao thức WSAPI, vì vậy chúng hiện đang hoạt động với Xavante, CGI và Fastcgi. Nó bao gồm một trình khởi chạy giúp bạn dễ dàng khởi chạy phiên bản Xavante để phát triển.

Cách dễ nhất để cài đặt Orbit là sử dụng LuaRocks. Luarocks install quỹ đạo là lệnh cài đặt. Đối với điều này, bạn cần cài đặt LuaRocks trước.

Nếu bạn chưa cài đặt tất cả các phụ thuộc, đây là các bước cần làm để thiết lập Orbit trong môi trường Unix / Linux.

Cài đặt Apache

Kết nối với máy chủ của bạn. Cài đặt Apache2, các mô-đun hỗ trợ của nó và kích hoạt các mô-đun Apache2 bắt buộc bằng cách sử dụng –

$ sudo apt-get install apache2 libapache2-mod-fcgid libfcgi-dev build-essential $ sudo a2enmod rewrite $ sudo a2enmod fcgid $ sudo /etc/init.d/apache2 force-reload 

Cài đặt LuaRocks

$ sudo apt-get install luarocks 

Cài đặt WSAPI, FCGI, Orbit và Xavante

$ sudo luarocks install orbit $ sudo luarocks install wsapi-xavante $ sudo luarocks install wsapi-fcgi 

Thiết lập Apache2

$ sudo raj /etc/apache2/sites-available/default 

Thêm phần sau này bên dưới phần <Thư mục / var / www /> của tệp cấu hình. Nếu phần này có ‘AllowOverride None’ thì bạn cần thay đổi ‘None’ thành ‘All’ để tệp .htaccess có thể ghi đè cấu hình cục bộ.

<IfModule mod_fcgid.c>     AddHandler fcgid-script .lua    AddHandler fcgid-script .ws    AddHandler fcgid-script .op 	    FCGIWrapper "/usr/local/bin/wsapi.fcgi" .ws    FCGIWrapper "/usr/local/bin/wsapi.fcgi" .lua    FCGIWrapper "/usr/local/bin/op.fcgi" .op 	    #FCGIServer "/usr/local/bin/wsapi.fcgi" -idle-timeout 60 -processes 1    #IdleTimeout 60    #ProcessLifeTime 60 	 </IfModule>

Khởi động lại máy chủ để đảm bảo các thay đổi được thực hiện có hiệu lực.

Để kích hoạt ứng dụng của mình, bạn cần thêm + ExecCGI vào tệp .htaccess trong thư mục gốc của ứng dụng Orbit – trong trường hợp này là / var / www.

Options +ExecCGI DirectoryIndex index.ws 

Ví dụ đơn giản – Quỹ đạo

#!/usr/bin/env index.lua  -- index.lua require"orbit"  -- declaration module("myorbit", package.seeall, orbit.new)  -- handler  function index(web)    return my_home_page() end  -- dispatch myorbit:dispatch_get(index, "/", "/index")  -- Sample page  function my_home_page()     return [[       <head></head>       <html>          <h2>First Page</h2>       </html>    ]] 	 end

Bây giờ, bạn sẽ có thể khởi chạy trình duyệt web của mình. Truy cập http: // localhost: 8080 / và bạn sẽ thấy kết quả sau:

First Page 

Orbit cung cấp một tùy chọn khác, tức là mã Lua có thể tạo html.

#!/usr/bin/env index.lua  -- index.lua require"orbit"  function generate()    return html {       head{title "HTML Example"}, 		       body{          h2{"Here we go again!"}       }    } end  orbit.htmlify(generate)  print(generate())

Tạo biểu mẫu

Dưới đây là một ví dụ về biểu mẫu đơn giản –

#!/usr/bin/env index.lua require"orbit"  function wrap (inner)    return html{ head(), body(inner) } end  function test ()    return wrap(form (H'table' {       tr{td"First name",td( input{type = 'text', name='first'})},       tr{td"Second name",td(input{type = 'text', name='second'})},       tr{ td(input{type = 'submit', value = 'Submit!'}),          td(input{type = 'submit',value = 'Cancel'})       },    })) end  orbit.htmlify(wrap,test)  print(test())

WSAPI

Như đã đề cập trước đó, WSAPI hoạt động như cơ sở cho nhiều dự án và có nhiều tính năng được nhúng trong đó. Bạn có thể sử dụng WSAPI và hỗ trợ các nền tảng sau,

  • các cửa sổ
  • Hệ thống dựa trên UNIX

Các máy chủ và giao diện được hỗ trợ bởi WSAPI bao gồm,

  • CGI
  • FastCGI
  • Xavante

WSAPI cung cấp một số thư viện, giúp chúng tôi lập trình web dễ dàng hơn bằng Lua. Một số tính năng được hỗ trợ trong Lua bao gồm,

  • Yêu cầu xử lý
  • Bộ đệm đầu ra
  • Xác thực
  • Tải lên tệp
  • Yêu cầu cách ly
  • Ghép kênh

Dưới đây là một ví dụ đơn giản về WSAPI:

#!/usr/bin/env wsapi.cgi  module(..., package.seeall) function run(wsapi_env)    local headers = { ["Content-type"] = "text/html" }        local function hello_text()       coroutine.yield("<html><body>")       coroutine.yield("<p>Hello Wsapi!</p>")       coroutine.yield("<p>PATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")       coroutine.yield("<p>SCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>")       coroutine.yield("</body></html>")    end     return 200, headers, coroutine.wrap(hello_text) end

Bạn có thể thấy trong đoạn mã trên, một trang html đơn giản được hình thành và trả về. Bạn có thể thấy việc sử dụng các coroutines để có thể trả về câu lệnh theo câu lệnh cho hàm gọi. Cuối cùng, mã trạng thái html (200), tiêu đề và trang html được trả về.

Xavante

Xavante là một máy chủ Web Lua HTTP 1.1 sử dụng kiến ​​trúc mô-đun dựa trên các trình xử lý được ánh xạ URI. Xavante hiện đang cung cấp,

  • Trình xử lý tệp
  • Trình xử lý chuyển hướng
  • Trình xử lý WSAPI

Trình xử lý tệp được sử dụng cho các tệp chung. Trình xử lý chuyển hướng cho phép ánh xạ lại URI và trình xử lý WSAPI để xử lý với các ứng dụng WSAPI.

Một ví dụ đơn giản được hiển thị bên dưới.

require "xavante.filehandler" require "xavante.cgiluahandler" require "xavante.redirecthandler"  -- Define here where Xavante HTTP documents scripts are located local webDir = XAVANTE_WEB  local simplerules = {     { -- URI remapping example       match = "^[^%./]*/$",       with = xavante.redirecthandler,       params = {"index.lp"}    },      { -- cgiluahandler example       match = {"%.lp$", "%.lp/.*$", "%.lua$", "%.lua/.*$" },       with = xavante.cgiluahandler.makeHandler (webDir)    },         { -- filehandler example       match = ".",       with = xavante.filehandler,       params = {baseDir = webDir}    }, }   xavante.HTTP{    server = {host = "*", port = 8080},         defaultHost = {       rules = simplerules    }, }

Để sử dụng máy chủ ảo với Xavante, lệnh gọi đến xavante.HTTP sẽ được thay đổi thành một cái gì đó như sau:

xavante.HTTP{    server = {host = "*", port = 8080},         defaultHost = {},         virtualhosts = {       ["www.sitename.com"] = simplerules    } }

Các thành phần web Lua

  • Copas, a dispatcher based on coroutines that can be used by TCP/IP servers.
  • Cosmo, a “safe templates” engine that protects your application from arbitrary code in the templates.
  • Coxpcall encapsulates Lua native pcall and xpcall with coroutine compatible ones.
  • LuaFileSystem, a portable way to access the underlying directory structure and file attributes.
  • Rings, a library which provides a way to create new Lua states from within Lua.

Ending Note

There are so many Lua based web frameworks and components available for us and based on the need, it can be chosen. There are other web frameworks available which include the following −

  • Moonstalk enables efficient development and hosting of dynamically generated web-based projects built with the Lua language; from basic pages to complex applications.
  • Lapis, a framework for building web applications using MoonScript (or Lua) that runs inside of a customized version of Nginx called OpenResty.
  • Lua Server Pages, a Lua scripting engine plug-in that blows away any other approach to embedded web development, offers a dramatic short cut to traditional C server pages.

These web frameworks can leverage your web applications and help you in doing powerful operations.

Lua – Database Access

For simple data operations, we may use files, but, sometimes, these file operations may not be efficient, scalable, and powerful. For this purpose, we may often switch to using databases. LuaSQL is a simple interface from Lua to a number of database management systems. LuaSQL is the library, which provides support for different types of SQL. This include,

  • SQLite
  • Mysql
  • ODBC

In this tutorial, we will be covering database handling of MySQL an SQLite in Lua. This uses a generic interface for both and should be possible to port this implementation to other types of databases as well. First let see how you can do the operations in MySQL.

MySQL db Setup

In order to use the following examples to work as expected, we need the initial db setup. The assumptions are listed below.

  • You have installed and setup MySQL with default user as root and password as ‘123456’.
  • You have created a database test.
  • You have gone through MySQL tutorial to understand MySQL Basics.

Importing MySQL

We can use a simple require statement to import the sqlite library assuming that your Lua implementation was done correctly.

mysql = require "luasql.mysql" 

The variable mysql will provide access to the functions by referring to the main mysql table.

Setting up Connection

We can set up the connection by initiating a MySQL environment and then creating a connection for the environment. It is shown below.

local env  = mysql.mysql() local conn = env:connect('test','root','123456') 

The above connection will connect to an existing MySQL file and establishes the connection with the newly created file.

Execute Function

There is a simple execute function available with the connection that will help us to do all the db operations from create, insert, delete, update and so on. The syntax is shown below −

conn:execute([[ 'MySQLSTATEMENT' ]]) 

In the above syntax, we need to ensure that conn is open and existing MySQL connection and replace the ‘MySQLSTATEMENT’ with the correct statement.

Create Table Example

A simple create table example is shown below. It creates a table with two parameters id of type integer and name of type varchar.

mysql = require "luasql.mysql"  local env  = mysql.mysql() local conn = env:connect('test','root','123456')  print(env,conn)  status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]]) print(status,errorString )

When you run the above program, a table named sample will be created with two columns namely, id and name.

MySQL environment (004BB178)	MySQL connection (004BE3C8) 0	nil 

In case there is any error, you would be returned an error statement instead of nil. A simple error statement is shown below.

LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1 

Insert Statement Example

An insert statement for MySQL is shown below.

conn:execute([[INSERT INTO sample values('11','Raj')]]) 

Update Statement Example

An update statement for MySQL is shown below.

conn:execute([[UPDATE sample3 SET name='John' where id ='12']]) 

Ví dụ về Xóa câu lệnh

Một câu lệnh xóa cho MySQL được hiển thị bên dưới.

conn:execute([[DELETE from sample3 where id ='12']]) 

Chọn ví dụ về câu lệnh

Liên quan đến câu lệnh select, chúng ta cần lặp qua từng hàng và trích xuất dữ liệu cần thiết. Một câu lệnh chọn đơn giản được hiển thị bên dưới.

cursor,errorString = conn:execute([[select * from sample]]) row = cursor:fetch ({}, "a")  while row do    print(string.format("Id: %s, Name: %s", row.id, row.name))    -- reusing the table of results    row = cursor:fetch (row, "a") end

Trong đoạn mã trên, conn là một kết nối MySQL mở. Với sự trợ giúp của con trỏ được trả về bởi câu lệnh thực thi, bạn có thể lặp qua phản hồi bảng và tìm nạp dữ liệu chọn được yêu cầu.

Một ví dụ hoàn chỉnh

Dưới đây là một ví dụ hoàn chỉnh bao gồm tất cả các câu trên.

mysql = require "luasql.mysql"  local env  = mysql.mysql() local conn = env:connect('test','root','123456') print(env,conn)  status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]]) print(status,errorString )  status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]]) print(status,errorString )  cursor,errorString = conn:execute([[select * from sample3]]) print(cursor,errorString)  row = cursor:fetch ({}, "a")  while row do    print(string.format("Id: %s, Name: %s", row.id, row.name))    row = cursor:fetch (row, "a") end  -- close everything cursor:close() conn:close() env:close()

Khi bạn chạy chương trình trên, bạn sẽ nhận được kết quả sau.

MySQL environment (0037B178)	MySQL connection (0037EBA8) 0	nil 1	nil MySQL cursor (003778A8)	nil Id: 12, Name: Raj 

Thực hiện các giao dịch

Giao dịch là một cơ chế đảm bảo tính nhất quán của dữ liệu. Các giao dịch phải có bốn thuộc tính sau:

  • Tính nguyên tử – Giao dịch hoàn tất hoặc không có gì xảy ra cả.
  • Tính nhất quán – Một giao dịch phải bắt đầu ở trạng thái nhất quán và để hệ thống ở trạng thái nhất quán.
  • Cô lập – Kết quả trung gian của một giao dịch không được hiển thị bên ngoài giao dịch hiện tại.
  • Độ bền – Sau khi giao dịch được cam kết, các tác động sẽ tồn tại dai dẳng, ngay cả sau khi hệ thống bị lỗi.

Giao dịch bắt đầu bằng BẮT ĐẦU GIAO DỊCH; và kết thúc bằng câu lệnh commit hoặc rollback.

Bắt đầu giao dịch

Để bắt đầu một giao dịch, chúng ta cần thực hiện câu lệnh sau trong Lua, giả sử conn là một kết nối MySQL mở.

conn:execute([[START TRANSACTION;]]) 

Giao dịch hồi phục

Chúng ta cần thực hiện câu lệnh sau để khôi phục các thay đổi được thực hiện sau khi bắt đầu giao dịch được thực hiện.

conn:execute([[ROLLBACK;]]) 

Giao dịch cam kết

Chúng ta cần thực hiện câu lệnh sau để cam kết các thay đổi được thực hiện sau khi bắt đầu giao dịch được thực hiện.

conn:execute([[COMMIT;]]) 

Chúng ta đã biết về MySQL trong phần trên và phần sau giải thích về các phép toán SQL cơ bản. Hãy nhớ các giao dịch, mặc dù không được giải thích lại cho SQLite3 nhưng các câu lệnh tương tự cũng sẽ hoạt động cho SQLite3.

Nhập SQLite

Chúng ta có thể sử dụng một câu lệnh request đơn giản để nhập thư viện SQLite với giả định rằng việc triển khai Lua của bạn đã được thực hiện chính xác. Trong khi cài đặt, một thư mục libsql có chứa các tệp liên quan đến cơ sở dữ liệu.

sqlite3 = require "luasql.sqlite3" 

Biến sqlite3 sẽ cung cấp quyền truy cập vào các hàm bằng cách tham chiếu đến bảng sqlite3 chính.

Thiết lập kết nối

Chúng ta có thể thiết lập kết nối bằng cách khởi tạo môi trường SQLite và sau đó tạo kết nối cho môi trường. Nó được hiển thị bên dưới.

local env  = sqlite3.sqlite3() local conn = env:connect('mydb.sqlite') 

Kết nối trên sẽ kết nối với tệp SQLite hiện có hoặc tạo tệp SQLite mới và thiết lập kết nối với tệp mới được tạo.

Thực thi chức năng

Có một chức năng thực thi đơn giản có sẵn với kết nối sẽ giúp chúng ta thực hiện tất cả các thao tác db từ tạo, chèn, xóa, cập nhật, v.v. Cú pháp được hiển thị bên dưới –

conn:execute([[ 'SQLite3STATEMENT' ]]) 

Trong cú pháp trên, chúng ta cần đảm bảo rằng conn đang mở và kết nối sqlite3 hiện có và thay thế ‘SQLite3STATEMENT’ bằng câu lệnh chính xác.

Ví dụ về Tạo bảng

Dưới đây là một ví dụ tạo bảng đơn giản. Nó tạo một bảng với hai tham số id kiểu số nguyên và tên kiểu varchar.

sqlite3 = require "luasql.sqlite3"  local env  = sqlite3.sqlite3() local conn = env:connect('mydb.sqlite') print(env,conn)  status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]]) print(status,errorString )

Khi bạn chạy chương trình trên, một bảng có tên sample sẽ được tạo với hai cột là id và name.

SQLite3 environment (003EC918)	SQLite3 connection (00421F08) 0	nil 

Trong trường hợp có lỗi, bạn sẽ được trả về một câu lệnh lỗi thay vì nil. Một báo cáo lỗi đơn giản được hiển thị bên dưới.

LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)" 

Chèn ví dụ câu lệnh

Một câu lệnh chèn cho SQLite được hiển thị bên dưới.

 conn:execute([[INSERT INTO sample values('11','Raj')]]) 

Chọn ví dụ về câu lệnh

As far as select statement is concerned, we need to loop through each of the rows and extract the required data. A simple select statement is shown below.

cursor,errorString = conn:execute([[select * from sample]]) row = cursor:fetch ({}, "a")  while row do    print(string.format("Id: %s, Name: %s", row.id, row.name))    -- reusing the table of results    row = cursor:fetch (row, "a") end

In the above code, conn is an open sqlite3 connection. With the help of the cursor returned by the execute statement, you can loop through the table response and fetch the required select data.

A Complete Example

A complete example including all the above statements is given below.

sqlite3 = require "luasql.sqlite3"  local env  = sqlite3.sqlite3() local conn = env:connect('mydb.sqlite') print(env,conn)  status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]]) print(status,errorString )  status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]]) print(status,errorString )  cursor,errorString = conn:execute([[select * from sample]]) print(cursor,errorString)  row = cursor:fetch ({}, "a")  while row do    print(string.format("Id: %s, Name: %s", row.id, row.name))    row = cursor:fetch (row, "a") end  -- close everything cursor:close() conn:close() env:close()

When you run the above program, you will get the following output.

SQLite3 environment (005EC918)	SQLite3 connection (005E77B0) 0	nil 1	nil SQLite3 cursor (005E9200)	nil Id: 1, Name: Raj 

We can execute all the available queries with the help of this libsql library. So, please don’t stop with these examples. Experiment various query statement available in respective MySQL, SQLite3 and other supported db in Lua.

Lua – Game Programing

Lua is used in a lot of game engines due to its simple language structure and syntax. The garbage collection feature is often quite useful in games which consume a lot of memory due to rich graphics that is used. Some game engines that use Lua includes −

  • Corona SDK
  • Gideros Mobile
  • ShiVa3D
  • Moai SDK
  • LOVE
  • CryEngine

Each of these game engines are based on Lua and there is a rich set of API available in each of these engines. We will look at the capabilities of each in brief.

Corona SDK

Corona SDK is a cross platform mobile game engine that supports iPhone, iPad, and Android platforms. There is a free version of Corona SDK that can be used for small games with limited features. You can upgrade to other versions when needed.

Corona SDK provides a number of features which includes the following −

  • Physics and Collision handling APIs
  • Web and Network APIs
  • Game Network API
  • Ads API
  • Analytics API
  • Database and File System APIs
  • Crypto and Math APIs
  • Audio and Media APIs

It is easier and faster to develop an application using the above APIs rather than using the native APIs separately for iOS and Android.

Gideros Mobile

Gideros provides the cross-platform SDK to create games for iOS and Android. It is free to use with a made with Gideros splash. Some of the striking advantages in Gideoros includes, the following −

  • Development IDE − It provides its own IDE which makes it easier to develop Gideros apps.
  • Instant testing − While developing your game, it can be tested on a real device through Wifi in only 1 second. You don’t need to waste your time with an export or deploy process.
  • Plugin – Bạn có thể dễ dàng mở rộng lõi bằng các plugin. Nhập mã (C, C ++, Java hoặc Obj-C) hiện có của bạn, liên kết với Lua và diễn giải chúng trực tiếp. Hàng chục plugin mã nguồn mở đã được phát triển và sẵn sàng sử dụng.
  • Phương pháp OOP sạch – Gideros cung cấp hệ thống lớp của riêng mình với tất cả các tiêu chuẩn OOP cơ bản, cho phép bạn viết mã sạch và có thể sử dụng lại cho bất kỳ trò chơi nào trong tương lai của bạn.
  • Tốc độ gốc – Được phát triển dựa trên C / C ++ và OpenGL, trò chơi của bạn chạy ở tốc độ gốc và sử dụng đầy đủ sức mạnh của CPU và GPU bên dưới.

ShiVa3D

ShiVa3D là một trong những công cụ trò chơi 3D cung cấp trình chỉnh sửa đồ họa được thiết kế để tạo các ứng dụng và trò chơi điện tử cho Web, Bảng điều khiển và thiết bị Di động. Nó hỗ trợ nhiều nền tảng bao gồm Windows, Mac, Linux, iOS, Android, BlackBerry, Palm OS, Wii và WebOS.

Một số tính năng chính bao gồm

  • Các plugin tiêu chuẩn
  • API sửa đổi lưới
  • IDE
  • Trình chỉnh sửa địa hình, đại dương và hình ảnh động được tích hợp sẵn
  • Hỗ trợ công cụ vật lý ODE
  • Kiểm soát bản đồ ánh sáng đầy đủ
  • Xem trước trực tiếp cho vật liệu, hạt, đường mòn và HUD
  • Hỗ trợ định dạng trao đổi Collada

Phiên bản web của Shiva3d hoàn toàn miễn phí và các phiên bản khác mà bạn đăng ký.

SDK Moai

Moai SDK là một công cụ trò chơi di động đa nền tảng hỗ trợ các nền tảng iPhone, iPad và Android. Nền tảng Moai ban đầu bao gồm Moai SDK, một công cụ trò chơi mã nguồn mở và Moai Cloud, một nền tảng đám mây làm dịch vụ lưu trữ và triển khai các dịch vụ trò chơi. Hiện Moai Cloud đã ngừng hoạt động và chỉ có công cụ trò chơi.

Moai SDK chạy trên nhiều nền tảng bao gồm iOS, Android, Chrome, Windows, Mac và Linux.

YÊU QUÝ

LOVE là một khuôn khổ mà bạn có thể sử dụng để tạo các trò chơi 2D. Nó là miễn phí và mã nguồn mở. Nó hỗ trợ các nền tảng Windows, Mac OS X và Linux.

Nó cung cấp nhiều tính năng bao gồm,

  • API âm thanh
  • API hệ thống tệp
  • API bàn phím và cần điều khiển
  • API toán học
  • API cửa sổ và chuột
  • API Vật lý
  • API hệ thống và bộ hẹn giờ

CryEngine

CryEngine là một công cụ trò chơi được phát triển bởi nhà phát triển trò chơi người Đức Crytek. Nó đã phát triển từ thế hệ 1 đến thế hệ 4 và là một giải pháp phát triển tiên tiến. Nó hỗ trợ các trò chơi PC, Xbox 360, PlayStation3 và WiiU.

Nó cung cấp nhiều tính năng bao gồm,

  • Các hiệu ứng hình ảnh như Ánh sáng tự nhiên & Bóng mềm động, Chiếu sáng toàn cầu động trong thời gian thực, Khối lượng lan truyền ánh sáng, Đổ bóng hạt, Tessellation, v.v.
  • Hệ thống Hoạt hình Nhân vật và Hệ thống Cá nhân hóa Nhân vật.
  • Hình ảnh động bộ xương tham số và Trình chỉnh sửa hoạt ảnh khuôn mặt chuyên dụng độc đáo
  • Hệ thống AI như Lưới điều hướng nhiều lớp và Hệ thống điểm chiến thuật. Đồng thời cung cấp Hệ thống chỉnh sửa AI thân thiện với nhà thiết kế.
  • Trong Game Mixing & Profiling, Hệ thống âm thanh theo hướng dữ liệu Âm thanh động & Âm nhạc tương tác, v.v.
  • Các tính năng vật lý như Biến dạng thủ tục và Vật lý dây nâng cao.

Một ghi chú kết thúc

Mỗi SDK / khuôn khổ trò chơi này đều có ưu và nhược điểm riêng. Một sự lựa chọn thích hợp giữa chúng sẽ làm cho nhiệm vụ của bạn trở nên dễ dàng hơn và bạn có thể có thời gian tốt hơn với nó. Vì vậy, trước khi sử dụng nó, bạn cần phải biết các yêu cầu cho trò chơi của bạn và sau đó phân tích xem cái nào đáp ứng được tất cả các nhu cầu của bạn rồi mới nên sử dụng chúng.

Lua – Thư viện tiêu chuẩn

Thư viện tiêu chuẩn Lua cung cấp một bộ hàm phong phú được triển khai trực tiếp với API C và được tích hợp sẵn với ngôn ngữ lập trình Lua. Các thư viện này cung cấp các dịch vụ bên trong ngôn ngữ lập trình Lua và cả các dịch vụ bên ngoài như hoạt động tệp và db.

Các thư viện tiêu chuẩn này được xây dựng trong API C chính thức được cung cấp dưới dạng các mô-đun C riêng biệt. Nó bao gồm những điều sau:

  • Thư viện cơ bản, bao gồm thư viện con của coroutine
  • Thư viện mô-đun
  • Thao tác với chuỗi
  • Thao tác bảng
  • Thư viện toán học
  • Đầu vào và đầu ra tệp
  • Hệ điều hành cơ sở vật chất
  • Cơ sở gỡ lỗi

Thư viện cơ bản

Chúng tôi đã sử dụng thư viện cơ bản trong suốt hướng dẫn theo các chủ đề khác nhau. Bảng sau cung cấp liên kết của các trang liên quan và liệt kê các chức năng được đề cập trong các phần khác nhau của hướng dẫn Lua này.

Sr.No.Thư viện / Phương pháp & Mục đích
1Xử lý lỗiBao gồm các chức năng xử lý lỗi như khẳng định, lỗi như được giải thích trong Lua – Xử lý lỗi .
2Quản lý bộ nhớBao gồm các chức năng quản lý bộ nhớ tự động liên quan đến thu gom rác như được giải thích trong Lua – Garbage Collection .
3dofile ([tên tệp])Nó mở tệp và thực thi nội dung của tệp dưới dạng một đoạn. Nếu không có tham số nào được truyền, thì hàm này thực thi nội dung của đầu vào chuẩn. Các lỗi sẽ được thông báo cho người gọi.
4_NSDo đó, biến toàn cục nắm giữ môi trường toàn cục (nghĩa là, _G._G = _G). Bản thân Lua không sử dụng biến này.
5getfenv ([f])Trả về môi trường hiện tại được sử dụng bởi hàm. f có thể là một hàm Lua hoặc một số chỉ định hàm ở mức ngăn xếp đó – Mức 1 là hàm gọi getfenv. Nếu hàm đã cho không phải là hàm Lua hoặc nếu f bằng 0, getfenv trả về môi trường toàn cục. Giá trị mặc định cho f là 1.
6getmetatable (đối tượng)Nếu đối tượng không có đối tượng, trả về nil. Ngược lại, nếu đối tượng có thể đo được có trường “__metatable”, sẽ trả về giá trị được liên kết. Nếu không, trả về khả năng đáp ứng của đối tượng đã cho.
7ipairs (t)Hàm này tìm nạp các chỉ số và giá trị của bảng.
số 8tải (func [, chunkname])Tải một đoạn bằng cách sử dụng hàm func để lấy các mảnh của nó. Mỗi lệnh gọi đến func phải trả về một chuỗi nối với các kết quả trước đó.
9loadfile ([tên tệp]))Tương tự như tải, nhưng lấy đoạn từ tên tệp hoặc từ đầu vào chuẩn, nếu không có tên tệp nào được cung cấp.
10chuỗi tải (string [, chunkname])Tương tự như tải, nhưng lấy đoạn từ chuỗi đã cho.
11tiếp theo (bảng [, chỉ mục])Cho phép chương trình duyệt qua tất cả các trường của bảng. Đối số đầu tiên của nó là một bảng và đối số thứ hai của nó là một chỉ mục trong bảng này. next trả về chỉ mục tiếp theo của bảng và giá trị liên quan của nó.
12cặp (t)Tạm dừng quy trình đăng ký đang chạy. Tham số được truyền cho phương thức này hoạt động như các giá trị trả về bổ sung cho hàm tiếp tục.
13in (…)Tạm dừng quy trình đăng ký đang chạy. Tham số được truyền cho phương thức này hoạt động như các giá trị trả về bổ sung cho hàm tiếp tục.
14rawequal (v1, v2)Kiểm tra xem v1 có bằng v2 hay không mà không cần gọi bất kỳ metamethod nào. Trả về một boolean.
15rawget (bảng, chỉ mục)Nhận giá trị thực của bảng [index], mà không cần gọi bất kỳ metamethod nào. table phải là một cái bàn; chỉ mục có thể là bất kỳ giá trị nào.
16rawset (bảng, chỉ mục, giá trị)Đặt giá trị thực của bảng [index] thành giá trị, mà không cần gọi bất kỳ phương thức siêu tốc nào. bảng phải là một bảng, lập chỉ mục bất kỳ giá trị nào khác với nil và đánh giá bất kỳ giá trị Lua nào. Hàm này trả về bảng.
17chọn (chỉ mục, …)Nếu chỉ mục là một số, trả về tất cả các đối số sau chỉ mục số đối số. Nếu không, chỉ mục phải là chuỗi “#” và select trả về tổng số đối số bổ sung mà nó nhận được.
18setfenv (f, bảng)Đặt môi trường sẽ được sử dụng bởi hàm đã cho. f có thể là một hàm Lua hoặc một số chỉ định hàm ở mức ngăn xếp đó – Mức 1 là hàm gọi setfenv. setfenv trả về hàm đã cho. Là một trường hợp đặc biệt, khi f bằng 0 setfenv thay đổi môi trường của luồng đang chạy. Trong trường hợp này, setfenv không trả về giá trị nào.
19thiết lập được (bảng, có thể đo được)Đặt khả năng đáp ứng cho bảng đã cho. (Bạn không thể thay đổi phép đo đếm được của các loại khác từ Lua, chỉ từ C.) Nếu độ đo được bằng không, hãy loại bỏ độ đo được của bảng đã cho. Nếu hệ thống đo lường ban đầu có trường “__metatable”, thì sẽ xảy ra lỗi. Hàm này trả về bảng.
20tonumber (e [, base])Cố gắng chuyển đối số của nó thành một số. Nếu đối số đã là một số hoặc một chuỗi có thể chuyển đổi thành số, thì tonumber trả về số này; nếu không, nó trả về nil.
21dây (e)Nhận một đối số thuộc bất kỳ loại nào và chuyển đổi nó thành một chuỗi ở một định dạng hợp lý. Để kiểm soát hoàn toàn cách các số được chuyển đổi, hãy sử dụng string.format.
22loại (v)Trả về kiểu đối số duy nhất của nó, được mã hóa dưới dạng chuỗi. Các kết quả có thể có của hàm này là “nil” (một chuỗi, không phải giá trị nil), “number”, “string”, “boolean”, “table”, “function”, “thread” và “userdata”.
23giải nén (danh sách [, i [, j]])Trả về các phần tử từ bảng đã cho.
24_PHIÊN BẢNMột biến toàn cục (không phải một hàm) chứa một chuỗi chứa phiên bản thông dịch hiện tại. Nội dung hiện tại của biến này là “Lua 5.1”.
25CoroutinesBao gồm các chức năng thao tác trên quy trình như được giải thích trong Lua – Coroutines .

Thư viện mô-đun

Thư viện mô-đun cung cấp các chức năng cơ bản để tải mô-đun trong Lua. Nó xuất trực tiếp một hàm trong môi trường toàn cầu: request. Mọi thứ khác được xuất trong một gói bảng. Chi tiết về thư viện mô-đun được giải thích trong chương trước Lua – Hướng dẫn về mô-đun .

Thao tác với chuỗi

Lua cung cấp một tập hợp các hàm thao tác chuỗi phong phú. Hướng dẫn Lua – Strings trước đó sẽ trình bày chi tiết về vấn đề này.

Thao tác bảng

Lua phụ thuộc vào các bảng trong hầu hết các hoạt động của nó. Hướng dẫn Lua – Tables trước đó sẽ trình bày chi tiết về vấn đề này.

Đầu vào và đầu ra tệp

Chúng ta thường cần cơ sở lưu trữ dữ liệu trong lập trình và điều này được cung cấp bởi các hàm thư viện tiêu chuẩn cho I / O tệp trong Lua. Nó được thảo luận trong hướng dẫn Lua – File I / O trước đó .

Cơ sở gỡ lỗi

Lua cung cấp một thư viện gỡ lỗi cung cấp tất cả các chức năng nguyên thủy để chúng tôi tạo trình gỡ lỗi của riêng mình. Nó được thảo luận trong Lua – hướng dẫn gỡ lỗi trước đó .

Lua – Thư viện toán học

Chúng ta thường cần các phép toán trong tính toán khoa học và kỹ thuật và chúng ta có thể tận dụng điều này bằng cách sử dụng toán học thư viện Lua tiêu chuẩn. Danh sách các hàm có sẵn trong thư viện toán học được hiển thị trong bảng sau.

Sr.No.Thư viện / Phương pháp & Mục đích
1math.abs (x)Trả về giá trị tuyệt đối của x.
2math.acos (x)Trả về cosin cung của x (tính bằng radian).
3math.asin (x)Trả về sin cung của x (tính bằng radian).
4math.atan (x)Trả về tiếp tuyến cung của x (tính bằng radian).
5math.atan2 (y, x)Trả về tiếp tuyến cung của y / x (tính bằng radian), nhưng sử dụng dấu hiệu của cả hai tham số để tìm góc phần tư của kết quả. (Nó cũng xử lý chính xác trường hợp x bằng không.)
6math.ceil (x)Trả về số nguyên nhỏ nhất lớn hơn hoặc bằng x.
7toán học.cos (x)Trả về cosine của x (giả sử là radian).
số 8math.cosh (x)Trả về cosin hyperbol của x.
9math.deg (x)Trả về góc x (tính bằng radian) theo độ.
10math.exp (x)Trả về giá trị e lũy thừa x.
11math.floor (x)Trả về số nguyên lớn nhất nhỏ hơn hoặc bằng x.
12math.fmod (x, y)Trả về phần còn lại của phép chia x cho y làm tròn thương số về 0.
13math.frexp (x)Trả về m và e sao cho x = m2e, e là số nguyên và giá trị tuyệt đối của m nằm trong khoảng [0,5, 1) (hoặc 0 khi x bằng 0).
14math.hugeGiá trị HUGE_VAL, một giá trị lớn hơn hoặc bằng bất kỳ giá trị số nào khác.
15math.ldexp (m, e)Trả về m2e (e phải là một số nguyên).
16math.log (x)Trả về lôgarit tự nhiên của x.
17math.log10 (x)Trả về logarit cơ số 10 của x.
18math.max (x, …)Trả về giá trị lớn nhất trong số các đối số của nó.
19math.min (x, …)Trả về giá trị nhỏ nhất trong số các đối số của nó.
20math.modf (x)Trả về hai số, phần nguyên của x và phần thập phân của x.
21math.piGiá trị của số pi.
22math.pow (x, y)Trả về xy. (Bạn cũng có thể sử dụng biểu thức x ^ y để tính giá trị này.)
23math.rad (x)Trả về góc x (tính bằng độ) tính bằng radian.
24math.random ([m [, n]])Hàm này là một giao diện với hàm tạo ngẫu nhiên giả đơn giản do ANSI C. cung cấp. Khi được gọi mà không có đối số, trả về một số thực giả ngẫu nhiên thống nhất trong phạm vi [0,1). Khi được gọi với một số nguyên m, math.random trả về một số nguyên giả ngẫu nhiên thống nhất trong phạm vi [1, m]. Khi được gọi với hai số nguyên m và n, math.random trả về một số nguyên giả ngẫu nhiên thống nhất trong phạm vi [m, n].
25math.randomseed (x)Đặt x làm “hạt giống” cho trình tạo giả ngẫu nhiên: các hạt giống nhau tạo ra các chuỗi số bằng nhau.
26math.sin (x)Trả về sin của x (giả sử là radian).
27math.sinh (x)Trả về sin hyperbol của x.
28math.sqrt (x)Trả về căn bậc hai của x. (Bạn cũng có thể sử dụng biểu thức x ^ 0,5 để tính giá trị này.)
29toán.tan (x)Trả về tang của x (giả sử là radian).
30math.tanh (x)Trả về tiếp tuyến hypebol của x.

Hàm lượng giác

Dưới đây là một ví dụ đơn giản sử dụng hàm lượng giác.Bản thử trực tiếp

radianVal = math.rad(math.pi / 2)  io.write(radianVal,"\n")  -- Sin value of 90(math.pi / 2) degrees io.write(string.format("%.1f ", math.sin(radianVal)),"\n")  -- Cos value of 90(math.pi / 2) degrees io.write(string.format("%.1f ", math.cos(radianVal)),"\n")  -- Tan value of 90(math.pi / 2) degrees io.write(string.format("%.1f ", math.tan(radianVal)),"\n")  -- Cosh value of 90(math.pi / 2) degrees io.write(string.format("%.1f ", math.cosh(radianVal)),"\n")  -- Pi Value in degrees io.write(math.deg(math.pi),"\n")

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

0.027415567780804 0.0  1.0  0.0  1.0  180 

Các hàm toán học thông thường khác

Dưới đây là một ví dụ đơn giản sử dụng các hàm toán học phổ biến.Bản thử trực tiếp

-- Floor io.write("Floor of 10.5055 is ", math.floor(10.5055),"\n")  -- Ceil io.write("Ceil of 10.5055 is ", math.ceil(10.5055),"\n")  -- Square root io.write("Square root of 16 is ",math.sqrt(16),"\n")  -- Power io.write("10 power 2 is ",math.pow(10,2),"\n") io.write("100 power 0.5 is ",math.pow(100,0.5),"\n")  -- Absolute io.write("Absolute value of -10 is ",math.abs(-10),"\n")  --Random math.randomseed(os.time()) io.write("Random number between 1 and 100 is ",math.random(),"\n")  --Random between 1 to 100 io.write("Random number between 1 and 100 is ",math.random(1,100),"\n")  --Max io.write("Maximum in the input array is ",math.max(1,100,101,99,999),"\n")  --Min io.write("Minimum in the input array is ",math.min(1,100,101,99,999),"\n")

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

Floor of 10.5055 is 10 Ceil of 10.5055 is 11 Square root of 16 is 4 10 power 2 is 100 100 power 0.5 is 10 Absolute value of -10 is 10 Random number between 1 and 100 is 0.22876674703207 Random number between 1 and 100 is 7 Maximum in the input array is 999 Minimum in the input array is 1 

Các ví dụ trên chỉ là một số ví dụ phổ biến, chúng ta có thể sử dụng thư viện toán học dựa trên nhu cầu của mình, vì vậy hãy thử sử dụng tất cả các hàm để quen thuộc hơn.

Lua – Cơ sở hệ điều hành

Trong bất kỳ ứng dụng nào, nó thường được yêu cầu truy cập các chức năng cấp Hệ điều hành và nó được cung cấp sẵn với thư viện Hệ điều hành. Danh sách các chức năng có sẵn được liệt kê trong bảng sau.

Sr.No.Thư viện / Phương pháp & Mục đích
1os.clock ()Trả về giá trị gần đúng tính bằng giây thời gian CPU được chương trình sử dụng.
2os.date ([định dạng [, thời gian]])Trả về một chuỗi hoặc một bảng chứa ngày và giờ, được định dạng theo định dạng chuỗi đã cho.
3os.difftime (t2, t1)Trả về số giây từ thời điểm t1 đến thời điểm t2. Trong POSIX, Windows và một số hệ thống khác, giá trị này chính xác là t2-t1.
4os.execute ([lệnh])Chức năng này tương đương với hệ thống chức năng ANSI C. Nó chuyển lệnh để được thực thi bởi một trình bao hệ điều hành. Kết quả đầu tiên của nó là true nếu lệnh kết thúc thành công, hoặc bằng không.
5os.exit ([mã [, đóng])Gọi lối ra hàm ANSI C để chấm dứt chương trình máy chủ. Nếu mã là đúng, trạng thái trả về là EXIT_SUCCESS; nếu mã sai, trạng thái trả về là EXIT_FAILURE; nếu mã là một số, trạng thái trả về là số này.
6os.getenv (varname)Trả về giá trị của biến môi trường tiến trình varname hoặc nil nếu biến không được xác định.
7os.remove (tên tệp)Xóa tệp (hoặc thư mục trống, trên hệ thống POSIX) với tên đã cho. Nếu hàm này không thành công, nó sẽ trả về nil, cộng với một chuỗi mô tả lỗi và mã lỗi.
số 8os.rename (tên cũ, tên mới)Đổi tên tệp hoặc thư mục có tên cũ thành tên mới. Nếu hàm này không thành công, nó sẽ trả về nil, cộng với một chuỗi mô tả lỗi và mã lỗi.
9os.setlocale (locale [, category])Đặt ngôn ngữ hiện tại của chương trình. locale là một chuỗi phụ thuộc vào hệ thống chỉ định một ngôn ngữ; danh mục là một chuỗi tùy chọn mô tả danh mục cần thay đổi: “tất cả”, “đối chiếu”, “ctype”, “tiền tệ”, “số” hoặc “thời gian”; danh mục mặc định là “tất cả”. Hàm trả về tên của ngôn ngữ mới hoặc nil nếu yêu cầu không thể được thực hiện.
10os.time ([bảng])Trả về thời gian hiện tại khi được gọi mà không có đối số hoặc thời gian biểu thị ngày và giờ được chỉ định bởi bảng đã cho. Bảng này phải có các trường năm, tháng và ngày và có thể có các trường giờ (mặc định là 12), min (mặc định là 0), giây (mặc định là 0) và isdst (mặc định là nil). Để biết mô tả về các trường này, hãy xem hàm os.date.
11os.tmpname ()Trả về một chuỗi có tên tệp có thể được sử dụng cho tệp tạm thời. Tệp phải được mở rõ ràng trước khi sử dụng và xóa rõ ràng khi không cần nữa.

Các chức năng hệ điều hành phổ biến

Dưới đây là một ví dụ đơn giản sử dụng các hàm toán học phổ biến.Bản thử trực tiếp

-- Date with format io.write("The date is ", os.date("%m/%d/%Y"),"\n")  -- Date and time io.write("The date and time is ", os.date(),"\n")  -- Time io.write("The OS time is ", os.time(),"\n")  -- Wait for some time for i=1,1000000 do end  -- Time since Lua started io.write("Lua started before ", os.clock(),"\n")

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả tương tự như sau.

The date is 01/25/2014 The date and time is 01/25/14 07:38:40 The OS time is 1390615720 Lua started before 0.013 

Các ví dụ trên chỉ là một số ví dụ phổ biến, chúng ta có thể sử dụng thư viện OS tùy theo nhu cầu của mình, vì vậy hãy thử sử dụng tất cả các hàm để quen thuộc hơn. Có các chức năng như remove giúp xóa tệp, thực thi giúp chúng ta thực hiện các lệnh hệ điều hành như đã giải thích ở trên.


Lượt xem : 258

Integrations
Users

Share Profile

Anyone at KeenThemes can view
Anyone with link can edit

Give Award

Anyone at KeenThemes can view
Anyone with link can edit

Report User

Let us know why you’re reporing this person
Don't worry, your report is completely anonymous; the person you're
reporting will not be informed that you've submitted it