เรียนรู้การใช้ภาษา Lua
บทความนี้กล่าวถึง ภาษา Lua ซึ่งเป็นภาษาคอมพิวเตอร์ และเรียนรู้การเขียนโค้ดในภาษานี้
โดยอาศัยโค้ดตัวอย่าง
ผู้อ่านควรมีพื้นฐานการเขียนโปรแกรมมาบ้างเพื่อทำความเข้าใจเนื้อหาในบทความนี้ คำสำคัญ / Keywords: Lua programming language |
ภาษา Lua
(pronounced 'LOO-ah' หรือออกเสียงว่า 'ลัว' หรือ 'ลูอ่า' ในภาษาโปรตุเกส)
อาจไม่เป็นที่รู้จักสำหรับโปรแกรมเมอร์ทั่วไปในวงกว้าง แต่ก็เป็นภาษาคอมพิวเตอร์ที่น่าสนใจ
และสามารถนำมาใช้งานได้ ลองมาทำความรู้จักกับภาษานี้ โดยเขียนสรุปเป็นข้อๆ ดังนี้
|
โปรแกรมสำหรับการเขียนโค้ดในภาษา Luaโปรแกรมที่ใช้ในการเขียนโค้ดภาษา Lua ได้แก่ 1) ตัวแปลคำสั่ง หรือ 'อินเทอร์พรีเตอร์' สำหรับภาษา Lua (Lua Interpreter) และ 2) โปรแกรมที่ใช้ในการเขียนโค้ดหรือ Code Editor ซึ่งมีให้เลือกใช้หลายตัวและเป็นซอฟต์แวร์ประเภท Opensource หรือติดตั้งใช้งานได้ฟรีสำหรับโปรแกรม Lua Interpreter (binaries) สามารถหาดาวน์โหลดได้จาก sourceforge.net และผู้ใช้ระบบปฏิบัติการ Windows ให้เลือกไฟล์ lua-5.3.2_Win32_bin.zip หรือ lua-5.3.2_Win64_bin.zip (เวอร์ชันปัจจุบันคือ 5.3.2 ในขณะที่เขียนเอกสารนี้) ขึ้นอยู่กับว่าใช้ระบบปฏิบัติการแบบ 32 บิต หรือ 64 บิต ส่วนการติดตั้งใช้งาน ก็เพียงแตกไฟล์ (Unzip) แล้วนำไปใส่ในไดเรคทรอรี่ที่ต้องการ สำหรับโปรแกรมที่ใช้ในการเขียนโค้ด ได้เลือกใช้โปรแกรม Sublime Text 2 และใช้ระบบปฏิบัติการ Windows เป็นตัวอย่าง โปรแกรมนี้รองรับการทำ Syntax Highlighting สำหรับภาษา Lua และอีกหลายภาษา รูปหน้าต่างหลักของโปรแกรม Sublime Text 2 ที่นำมาใช้เขียนโค้ด Lua สามารถแสดงสีไฮไลท์ (color highlighting) ของคำตามไวยากรณ์ภาษา Lua สามารถ Build เพื่อทำคำสั่งโดยใช้ตัวแปลคำสั่งภาษา Lua ได้ การเรียนรู้ Lua จากตัวอย่าง / Learning Lua by Examplesการเรียนรู้การเขียนโปรแกรมคอมพิวเตอร์ด้วยภาษาใดๆ โดยทั่วไปก็มักอาศัยโค้ดตัวอย่าง เริ่มจากที่มีความซับซ้อนจากน้อยไปหามาก และถ้าผู้อ่านมีความรู้ภาษาคอมพิวเตอร์อื่นมาบ้าง ก็ควรศึกษาเชิงเปรียบเทียบ คือเปรียบเทียบกับภาษาเดิมที่เคยรู้จักในขณะที่กำลังศึกษาภาษา Luaหัวข้อในการเรียนรู้ภาษา Lua ขั้นพื้นฐานได้แก่
รูปแบบการเขียนโค้ดภาษา Luaโดยทั่วไป บรรทัดแรกของไฟล์ชุดคำสั่งหรือสคริปต์ (script) ในภาษา Lua จะมีการระบุว่า จะใช้โปรแกรมใดที่ทำหน้าที่เป็น Lua Interpreter เช่น #!/usr/bin/env lua เพื่อใช้ทำตามประโยคคำสั่งต่างๆ ในสคริปต์ และมักใช้กับระบบปฏิบัติการอย่างเช่น Linux และเรียกใช้สคริปต์ผ่านหน้าต่างคอนโซล (console) ประโยคคำสั่งอาจมีความยาวหนึ่งบรรทัดหรือมากกว่าหนึ่งบรรทัดได้ ถ้าในบรรทัดเดียวกันมีประโยคคำสั่งมากกว่าหนึ่ง จำเป็นต้องมีสัญลักษณ์ semicolon (;) ปิดท้ายประโยคแต่ละประโยคคำอธิบายโค้ด (code comment)ในภาษา Lua การเขียนคำอธิบายในโค้ด (code comment) หรือโค้ดคอมเมนต์ ถ้าเขียนแบบบรรทัดเดียว (single-Line comment) จะเริ่มต้นด้วยสัญลักษณ์ -- (double-dash หรือ double hyphen) และข้อความที่ตามมาในบรรทัดนั้นให้ถือว่าเป็นโค้ดคอมเมนต์ แต่ถ้าจะเขียนมากกว่าหนึ่งบรรทัด (multiple-line comment) ให้เขียนอยู่ระหว่าง --[[ และ --]]การแสดงข้อความออกทางช่องเอาต์พุตของโปรแกรมคำสั่งที่ใช้ในการแสดงข้อความ (string) หรือข้อมูลชนิดอื่นๆ ให้เป็นข้อความทางช่อง เอาต์พุตของโปรแกรม คือ print() หรือใช้คำสั่ง io.write() โดยระบุอาร์กิวเมนต์ (arguments) ป้อนให้คำสั่งเหล่านี้ ถ้ามีข้อความหรือตัวแปรมากกว่าหนึ่ง ก็เขียนอาร์กิวเมนต์แยกด้วยเครื่องหมาย comma (,) คำสั่ง print() เมื่อแสดงข้อความแล้วจะขึ้นบรรทัดใหม่ (newline) โดยอัตโนมัติซึ่งแตกต่างจากคำสั่ง io.write()ชนิดข้อมูลที่เป็นข้อความ (String Data Type)ในภาษา Lua ข้อความ (string) จะเริ่มต้นและจบท้ายด้วย ' ... ' (single qoutes) หรือ " ... " (double quotes) ถ้าจะนำข้อความมาต่อกัน (string concatenation) ก็ใช้โอเปเรเตอร์ .. (double dots) จะได้เป็นข้อความใหม่ (new string object) ข้อความเมื่อถูกสร้างขึ้นมาแล้วและถูกอ้างอิงด้วยตัวแปร จะไม่สามารถเปลี่ยนแปลงข้อมูลภายในได้ (immutable string) ข้อความอาจมีตัวอักขระที่เรียกว่า Escape Character ซึ่งเริ่มต้นด้วยสัญลักษณ์ Backslash (\)ตัวอย่าง Escape Characters
การใช้งานตัวแปร (Variables)ถ้าต้องการใช้งานตัวแปร เพื่ออ้างอิงข้อมูลตามชนิดของข้อมูลใดๆ ในภาษา Lua ก็ทำได้โดยการประกาศและกำหนดค่าเริ่มต้นให้ตัวแปรนั้น ซึ่งจะเป็นข้อมูลชนิดใดก็ได้ แต่ถ้าไม่กำหนดค่าให้หรืออ้างอิงข้อมูลใดๆ ก็ให้กำหนดค่าให้เป็น nil และเป็นการยกเลิกการใช้ตัวแปรนั้นๆ ประโยคคำสั่งในการกำหนดค่าให้ตัวแปรจะมีชื่อตัวแปรอยู่ด้านซ้ายของโอเปเรเตอร์ = (assignment operator) และทางขวามือเป็นนิพจน์ (expression) ซึ่งให้ค่าได้ การตั้งชื่อตัวแปร ก็เหมือนในภาษา C ยกเว้นคำที่สงวนไว้ (reserved words)คำสงวนในภาษา Lua (Reserved Words)คำที่ห้ามนำไปตั้งชื่อ identifier สำหรับชื่อตัวแปรหรือฟังก์ชันในภาษา Lua มีดังต่อไปนี้and break do else elseif end false for function if in local nil not or repeat return then true until whileและที่ควรรู้อีกประการหนึ่งคือ ภาษา Lua เป็นภาษาที่จำแนกความแตกต่างระหว่างตัวพิมพ์ใหญ่และเล็ก (case-sensitive) โค้ดตัวอย่าง: ex-1.lua #!/usr/bin/env lua -- Learning Lua: Code Example 1 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 -- This is a one-line comment. --[[ This is a multiple-line comment. --]] s1 = 'hello ' -- immutable string (with single quote) s2 = "world" -- immutable string (with double quote) s3 = '!' s4 = [[ This is Line 1. This is Line 2. This is Line 3. ]] print(s1,s2,s3) -- output: hello world ! io.write(s1,s2,s3,'\n') -- output: hello world! print(s1..s2..s3) -- output: hello world! io.write(s4) -- output: -- This is Line 1. -- This is Line 2. -- This is Line 3. print ('\\,\',\"') -- output: \,'," -- show a string with four characters, each specified in hex format (ASCII code) print ('\x61\x62\x63\x64') -- output: abcd -------------------------------------------------------------------------- ชนิดข้อมูลพื้นฐานในภาษา Luaตัวแปรสามารถอ้างอิงข้อมูลที่เป็นตัวเลข (number) ค่าลอจิกหรือบูลีน (boolean) และข้อความ (string) ซึ่งเป็นชนิดข้อมูลพื้นฐานในภาษา Lua ข้อมูลแบบตัวเลขมีสองชนิดคือ ค่าที่เป็นเลขจำนวนเต็ม (integer number) และค่าที่เป็นเลขทศนิยม (floating-point number) ถ้าต้องการทราบชนิดข้อมูลของตัวแปรใดๆ ให้ใช้คำสั่ง type() ซึ่งจะให้ค่ากลับคืนเป็นข้อความที่ระบุชนิดของข้อมูลที่ตัวแปรนั้นอ้างอิง เช่น 'number', 'boolean' และ 'string' เป็นต้นถ้าต้องการแปลงชนิดข้อมูลของตัวแปร ก็มีคำสั่งอย่างเช่น tonumber() ที่แปลงข้อความให้เป็นตัวเลข และ tostring() และแปลงตัวเลขให้เป็นข้อความ การใช้ฟังก์ชันทางคณิตศาสตร์ ก็มีไลบรารี่ math ของภาษา Lua ให้ใช้งาน เช่น คำสั่ง math.floor(), math.ceil(), math.sin(), math.cos(), math.exp() และ math.pow() เป็นต้น โค้ดตัวอย่าง: ex-2.lua #!/usr/bin/env lua -- Learning Lua: Code Example 2 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 x = 0 -- define a variable x / assign a number (int) to x print ('x =', x) -- output: x = 0 io.write('x = ', x, '\n') -- output: x = 0 x = nil -- undefine a variable x / assign nil to x print ('x = ', x) -- output: x = nil print ('----------') f = 1.2345e+2 -- define a variable x / assign a number (double) to x print (type(f)) -- output: number io.write ('f = ', f, '\n') print ('----------') y = math.floor(f) -- compute the largest integer less than f io.write ('y = ', y, '\n') -- output: y = 123 y = math.ceil(f) -- compute the smallest integer greater than f io.write ('y = ', y, '\n') -- output: y = 124 y = math.sin( math.pi/2 ) -- compute sin(PI/2) io.write ('y = ', y, '\n') -- output: y = 1 y = math.cos( math.pi ) -- compute cos(PI) io.write ('y = ', y, '\n') -- output: y = -1 y = math.exp( 0 ) -- compute e^0 io.write ('y = ', y, '\n') -- output: y = 1 y = math.pow( 2, 0.5 ) -- compute the square root of 2 io.write ('y = ', y, '\n') -- output: y = 1.4142135623731 print ('----------') z = tonumber("1.5")+1 -- convert a string to a number print (type(z)) -- output: number io.write ('z = ', z, '\n') -- output: z = 2.5 t = tonumber('0x' .. tostring(10)) print ('t = ' .. t) -- output: t = 16 -------------------------------------------------------------------------- ประโยคที่ทำขั้นตอนตามเงื่อนไขและการทำซ้ำการทำกลุ่มคำสั่งที่ขึ้นอยู่กับเงื่อนไข จะอาศัยประโยคแบบ if-else เพื่อตรวจสอบเงื่อนไขจากนิพจน์ที่ให้ค่าเป็น true หรือ false และทำคำสั่งตามแต่ละเงื่อนไขที่กำหนดไว้ และการใช้ประโยคคำสั่งแบบ for-do เพื่อทำคำสั่งซ้ำตามจำนวนครั้งที่ต้องการ (looping) หรือตามเงื่อนไขที่กำหนดและอาจจะไม่ทราบจำนวนครั้งที่ต้องทำการเขียนนิพจน์สำหรับใช้เป็นเงื่อนไข จะต้องเป็นนิพจน์ที่ให้ค่าแบบ boolean หรืออาจได้จากการใช้โอเปเรเตอร์เปรียบเทียบค่า (relational operators) อย่างเช่น > (มากกว่า) < (น้อยกว่า) >= (มากกว่าหรือเท่ากับ) <= (น้อยกว่าหรือเท่ากับ) == (เท่ากับ) และ ~= (ไม่เท่ากับ) เพื่อให้ได้ค่าเป็น true หรือ false และยังใช้โอเปเรเตอร์เชิงลอจิก (logical operators) อย่างเช่น and, or และ not กับนิพจน์ที่ให้ค่าทางลอจิกได้อีกด้วย คำสั่ง io.write() ใช้สำหรับแสดงข้อความออกทางเอาต์พุต แต่ถ้าต้องการจะรับค่าที่เป็นข้อความจากอินพุตของระบบ ให้ใช้คำสั่ง io.read() และเป็นการรับข้อความหนึ่งบรรทัด ถ้าต้องการสร้างตัวเลขสุ่ม ก็สามารถใช้คำสั่งจากไลบรารี่ math ได้เช่น math.randomseed() เพื่อกำหนดค่าเริ่มต้น (seed) ให้กับตัวสร้างเลขสุ่ม (random generator) และ math.random() เพื่อสร้างเลขสุ่มที่เป็นเลขจำนวนเต็ม โค้ดตัวอย่าง: ex-3.lua #!/usr/bin/env lua -- Learning Lua: Code Example 3 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 io.write('Please enter a number: ') -- read string from standard input and convert to a number x = tonumber( io.read() ) print ('x = '..x) -- if-elseif-else statement if x < 0 then print ('x is a negative number.') elseif x > 0 then print ('x is a positive number.') else print ('x is zero.') end print ('current time = '..os.time()) -- read system time in seconds math.randomseed( os.time() ) -- set the seed for the random number generator x = math.random(-10,10) -- create a random integer number between [-10,10] print ('x='..x) if (x > 0) then t = true; else t = false; end print ('t = '..tostring(t)) print ('----------') for i=1,10 do -- repeat for 10 times local x = math.random() -- create a random real number between [0,1) print (tostring(i)..') '..x) end c = math.random(0,2); -- create a random value [0,2] and assign to c if (c) then -- Warning: always true print('c = '..c); end -------------------------------------------------------------------------- ความแตกต่างระหว่างตัวแปรภายนอกและภายในการประกาศใช้ตัวแปรแบ่งได้เป็น 2 รูปแบบคือ ตัวแปรภายนอก (global variables) ที่มีขอบเขตการใช้งานครอบคลุมทั้งโปรแกรม และตัวแปรภายใน (local variables) ซึ่งมีขอบเขตและอายุการใช้จำกัดอยู่ตามประเภทของประโยคคำสั่ง หรือโครงสร้างที่ใช้งาน ถ้าไม่ระบุ ตัวแปรเมื่อกำหนดค่าให้จะเป็นตัวแปรภายนอก แต่ถ้าต้องการใช้งานแบบตัวแปรภายใน ให้เขียนกำกับด้วยคำว่า local ตามตัวอย่าง ให้สังเกตผลการทำงานของโค้ด ex-4.luaโค้ดตัวอย่าง: ex-4.lua #!/usr/bin/env lua -- Learning Lua: Code Example 4 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 x,y = nil,nil; -- undefine variables x and y if (x==nil) then -- if x is 'equal to' nil. x = 1 -- assign a number to x (global variable) end if (x ~= nil) then -- if x is 'not equal to' nil. io.write('x = ',x,'\n') -- show the value of the variable x else io.write('x is nil.','\n') end -- output: x = 1 print ('----------') if (y == nil) then -- if y is 'equal to' nil. local y = 1 -- assign a number to y (local variable) end if (y ~= nil) then -- if y is 'not equal to' nil. io.write('y = ',y,'\n') -- show the value of the variable y else io.write('y is nil.','\n') end -- output: y is nil. print ('----------') -- note: variable 'i' is a local variable within the following for statement. for i=1,5 do -- for i=1,2,..,5 local z=i*i; io.write('z = ',tostring(z),'\n'); end if (z ~= nil) then -- if z is 'not equal to' nil. io.write('z = ',z,'\n') -- show the value of the variable z else io.write('z is nil.','\n') end -- output: z is nil. if (i ~= nil) then -- if i is 'not equal to' nil. io.write('i = ',i,'\n') -- show the value of the variable i else io.write('i is nil.','\n') end -- output: i is nil. -------------------------------------------------------------------------- การใช้ประโยคคำสั่งเพื่อทำซ้ำ (Looping)ประโยคคำสั่งสำหรับการทำซ้ำหรือวนลูป ซึ่งอาจจะมีการซ้อนกันได้มากกว่าชั้น (nested loop) มีอยู่สามรูปแบบในภาษา Lua ได้แก่ ประโยคคำสั่งแบบ for-do, while-do และ repeat-until โดยทั่วไปแล้ว ประโยค for-do จะอาศัยตัวแปรภายในหนึ่งตัวเป็นตัวนับ (count variable) และนำไปกำหนดนิพจน์เงื่อนไขการทำซ้ำ มีทั้งการนับขึ้นและนับลงของตัวนับ และมีการทำซ้ำที่ ทราบจำนวนครั้งแน่นอน อย่างไรก็ตาม การทำซ้ำแบบไม่ทราบจำนวนครั้งล่วงหน้า หรือขึ้นอยู่กับเงื่อนไขในขณะที่โปรแกรมทำงาน ก็สามารถใช้ประโยคทั้งสามแบบได้ได้เช่นกัน นอกจากนั้นประโยคคำสั่ง break จะใช้สำหรับการหยุดการทำงานของลูปได้ทันทีโค้ดตัวอย่าง: ex-5.lua #!/usr/bin/env lua -- Learning Lua: Code Example 5 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 -- for-do loop n = 4 for i=0,n do -- for i=0,1,2,...,n print( 'i='..i ) end print ('---------') -- while-do loop i=0; while i < n do -- for i=0,1,2,..,(n-1) print( 'i='..i ) i = i+1 end print ('---------') -- repeat-until loop i = 0 repeat -- for i=0,1,2,..,(n-1) print( 'i='..i ) i=i+1 until i==n print ('---------') -- for loop, count-up for i=1,n do -- for i=1,2,...,n io.write('i=',i,'\n') end print ('---------') -- for loop, count-down for i=n,1,-1 do -- for i=n,n-1,...,2,1 io.write('i=',i,'\n') end while true do io.write('Please enter a number: ') local x = io.read() if (x == '0') then -- stop the loop if x is '0' break end end -------------------------------------------------------------------------- การสร้างฟังก์ชันฟังก์ชัน (functions) คือกลุ่มของประโยคคำสั่งที่ใช้สำหรับทำงานใดงานหนึ่งภายในโปรแรกม ถ้าต้องการสร้างฟังก์ชันเพื่อใช้งาน ก็ทำได้โดยใช้โครงสร้าง function ซึ่งมีส่วนประกอบคือ function name, function arguments และ function body ตามตัวอย่างในโค้ด ex-6.lua ฟังก์ชันสามารถมีรายการของอาร์กิวเมนต์ (function arguments) หรือไม่มีก็ได้ ภายในอาจมีคำสั่ง return เพื่อหยุดการทำงานต่อไปของฟังก์ชัน ฟังก์ชันสามารถให้ค่ากลับคืนได้ (return value) ไม่มีก็ได้ หรือให้ค่ากลับคืนเป็นข้อมูลได้มากกว่าหนึ่งตัวก็ได้เมื่อสร้างฟังก์ชันใหม่แล้วสามารถนำไปใช้กับตัวแปรได้ หรือกล่าวได้ว่า ตัวแปรสามารถอ้างอิงฟังก์ชันได้ และฟังก์ชันสามารถเป็นได้ทั้งฟังก์ชันภายนอก (global function) และฟังก์ชันภายใน (local function) ขึ้นอยู่ว่าจะประกาศเป็นแบบใด (มีคำว่า local นำหน้าหรือไม่) ถ้าต้องการสร้างฟังก์ชันที่มีรายการหรือจำนวนของอาร์กิวเมนต์ ไม่ระบุชัดเจนหรือไม่แน่นอน (function with variable argument) ก็มีวิธีสร้างในภาษา Lua ได้ตามโค้ดตัวอย่าง ข้อสังเกต: คำสั่ง ipairs() ซึ่งใช้กับอาร์เรย์หรือตารางในภาษา Lua คือ สิ่งที่เรียกว่า "generic for iterator" ทำหน้าที่เข้าถึงข้อมูลในตาราง หรืออาร์เรย์ทีละตำแหน่ง และจะใช้กับประโยค for-in-do ในขณะที่มีการวนลูปนั้นจะได้ครั้งละสองค่า ตัวแรกเป็นเลขลำดับของข้อมูล (เริ่มนับตั้งแต่ 1) และตัวที่สองเป็นข้อมูลตามที่อยู่ดังกล่าวในอาร์เรย์ โค้ดตัวอย่าง: ex-6.lua #!/usr/bin/env lua -- Learning Lua: Code Example 6 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 f = function (x) -- define a new function and assign it to a variable return (x ^ 2) -- return the square of x as a floating-point number end print (type(f)) -- output: function for i=1,5 do print (f(i)) -- call function 'f' end print ('---------') -- fibonacci, n=0,1,2,... function fib(n) -- define a function that computes the Fibonacci number if n < 2 then return 1 end return fib( n-2 ) + fib( n-1 ) -- recursive calls end for i=0,5 do -- for i=0,1,..,5 print ( fib(i) ) end print ('---------') f = nil -- undefine the variable f function f(...) -- define a function with dynamic argument list local args = {...} -- access the argument list of the function for i,v in ipairs(args) do -- for each argument with its integer index print (i, v) -- show the index (i) and the argument (v) end end f('a', 5, true) -- call function 'f' print ('---------') function show_numbers(count,start,step) local num = count or 0 -- if count is nil then num is set to 0. local value = start or 0 -- if start is nil then value is set to 0. local delta = step or 1 -- if step is nil then delta is set to 1. for i=1,num do io.write( value, ' ') value = value + delta; end io.write('\n') end show_numbers() -- output: show_numbers(5) -- output: 0 1 2 3 4 show_numbers(5,-2) -- output: -2 -1 0 1 2 show_numbers(5,2,-1) -- output: 2 1 0 -1 -2 -------------------------------------------------------------------------- การใช้งานโครงสร้างข้อมูลแบบอาร์เรย์อาร์เรย์ หรือที่เรียกว่า ตาราง (table) ในภาษา Lua เป็นโครงสร้างข้อมูลประเภทหนึ่ง โดยทั่วไปจะใช้งานได้สองแบบคือ เก็บข้อมูลที่เหมือนหรือต่างชนิดกันก็ได้ (และรวมถึงฟังก์ชันด้วย) สามารถเข้าถึงได้โดยใช้หมายเลขที่อยู่ซึ่งเป็นเลขจำนวนเต็มไปตามลำดับที่จัดเก็บ (เหมือนในภาษาอื่นๆ) และใช้โอเปเรเตอร์ [ ] กับตัวแปรแบบอาร์เรย์เพื่อการเข้าถึงข้อมูลข้างใน ถ้าต้องการทราบจำนวนข้อมูลในอาร์เรย์หรือตาราง ก็ใช้โอเปเรเตอร์ # เขียนนำหน้าตัวแปรแบบอาร์เรย์ ส่วนการเพิ่มข้อมูลลงในตารางหรือลบออก ก็สามารถใช้คำสั่ง table.insert() และ table.remove() ได้ตามลำดับอาร์เรย์แบบที่สองเป็นการใช้งานแบบ associative array เป็นข้อมูลเป็นคู่ ตัวแรกคือ key ซึ่งเป็น string และตัวที่สองคือ value ที่เป็นข้อมูลชนิดใดก็ได้ และจะกล่าวถึงในตัวอย่างถัดไป โค้ดตัวอย่าง: ex-7.lua #!/usr/bin/env lua -- Learning Lua: Code Example 7 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 function sum( a ) -- a function that sums up values in the table local sum=0 if type(a) == "table" then -- if the variable 'a' is a table. for i=1,#a do sum = sum + a[i] end return sum else return nil end end t = {1,2,3,4} -- create a table with four elements and assign it to variable t print (type(t)) -- output: table print ('number of elements in the table : '..#t) print ('sum of all elements in the table : '..sum(t)) for i=1,#t do -- for i=1,2,...,#t print( tostring(i) .. ') ' .. t[i] ) -- show each element in the table end print ('----------') print('#t = '..#t) -- number of elements in t -- append a table to another table z = {5,6,7} for i=1,#z do t[#t+i]= z[i] -- insert each element from table 'z' to table 't' end print('#t = '..#t) -- number of elements in t for i,v in pairs(t) do print (tostring(i) .. ') ' .. v) -- show the element t[i] = nil -- undefine / delete element at position i end print('#t = '..#t) -- output: #t = 0 print ('----------') x = {'a','b'} y = {'c','d','e'} t = {} for i,e in ipairs(x) do -- for each element in table x t[#t+1] = e -- append an element to table t (method 1) end for i,e in ipairs(y) do -- for each element in table y table.insert(t, e) -- append an element to table t (method 2) end for i,e in ipairs(t) do -- show elements in t print (i, e) end print ('------------') local compare = function (a,b) return a > b end -- use the function 'compare' to sort elements in the table table.sort( t, compare ) for i,e in ipairs(t) do -- show elements in t after sorting print (i, e) end print ('------------') n = #t for i=1,n do -- show elements in t after sorting table.remove(t,1) -- remove the first element from the table end print ('#t = '..#t) -- output: #t = 0 t = nil -- remove reference to table object print ('-----------') -- a table of the names of months days = { [1] = "Sunday", [2] = "Monday", [3] = "Tuesday", [4] = "Wednesday", [5] = "Thursday", [6] = "Friday", [7] = "Saturday" } for i=1,7 do print( days[i] ) end print ('-----------') -- the same as above days = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" } for _,day in ipairs(days) do print( day ) end -- create a 3x3 matrix (two-dimensional array) m = {} for i=1,3 do m[i] = {} for j=1,3 do m[i][j] = i*j -- assign a number to the cell at (i,j) end end -------------------------------------------------------------------------- การใช้งานโครงสร้างข้อมูลแบบ Associative Arraysโค้ด ex-8.lua สาธิตการใช้งานอาร์เรย์ที่เก็บข้อมูลเป็นคู่ระหว่างสองสิ่งที่เรียกว่า กุญแจ (key) และข้อมูล (value) ถ้าจะเข้าถึงข้อมูล value ต้องอาศัยข้อความ key สำหรับการค้นหาในตาราง รวมถึงการเพิ่มหรือลบข้อมูลออกจากอาร์เรย์ และการเข้าถึงข้อมูลในอาร์เรย์ข้อสังเกต: คำสั่งทั้ง ipairs() และ pairs() เป็น generic for iterator ใช้สำหรับการเข้าถึงข้อมูลในตารางหรืออาร์เรย์ทีละตำแหน่ง มีรูปแบบการทำงานแตกต่างกันคือ ipairs() ไม่สามารถใช้ได้กับตารางแบบ associative array โค้ดตัวอย่าง: ex-8.lua #!/usr/bin/env lua -- Learning Lua: Code Example 8 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 -- create two dictionaries (associative arrays) x = { ['one'] = 1, ['two'] = 2, } y = { ['three'] = 3, ['four'] = 4 } -- create an empty table t = {} for k,v in pairs(x) do t[k] = v -- insert (k,v) from table x into table t end for k,v in pairs(y) do t[k] = v -- insert (k,v) from table y into table t end -- add more elements into table t t["five"] = 5 t["six"] = 6 print ('#t = '..#t) for k,v in pairs(t) do print (k,v) t[k] = nil -- remove an element that matches the key end print ('#t = '..#t) print ('-----------') -- note: Since Lua 5.2, table.foreach is deprecated. if not table.foreach then table.foreach = function(t, f) -- define function table.foreach for k, v in pairs(t) do f(k, v) end end end t = { th='Thailand', de='Deutschland', ['jp']='Japan', ['fr']='France' } -- show all key-value pairs in the table table.foreach( t, function(k,v) print (k,v) end ) -------------------------------------------------------------------------- การใช้งานตัวแปรที่เก็บข้อมูลแบบ Stringโค้ด ex-9.lua สาธิตการใช้ตัวแปรแบบสตริง (string) จากตัวอย่างเห็นได้ว่า ตัวแปรแบบสตริงมีฟังก์ชันให้เรียกใช้งานได้ โดยเขียนสัญลักษณ์ : ต่อท้ายชื่อตัวแปรที่เป็นสตริง (เช่น s) แล้วตามด้วยชื่อฟังก์ชัน อย่างเช่น s:len() จะได้ความยาวของสตริง, s:upper() ให้สตริงใหม่ที่ถูกแปลงเป็นตัวพิมพ์ใหญ่, s:lower() ให้สตริงใหม่ที่ถูกแปลงเป็นตัวพิมพ์เล็ก, s:byte() ให้ค่าของไบต์ในตำแหน่งที่ระบุในสตริง, s:sub() ให้สตริงใหม่โดยนำข้อมูลมาจากช่วงตำแหน่งที่ระบุโค้ดตัวอย่าง: ex-9.lua #!/usr/bin/env lua -- Learning Lua: Code Example 9 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 s = "abcd\x21" -- assign a string of length = 5 to a variable print (type(s)) -- output: string len = #s -- get the string length print ('#s = '..len) -- output: #s = 5 print ('#s = '..s:len()) -- output: #s = 5 for i=1,len do local b = s:byte(i) -- get the i-th byte in the string print ( b ) -- output: 97 98 99 100 33 end print ('---------') for i=1,len do local p = s:sub(1,i) -- get a substring, starting from index 0 to i print ( p ) end print ('---------') t = {'a','b','c','d'} s = table.concat(t, '') -- convert a table into string print ('s = '..s) -- output: s = abcd print ('---------') s = table.concat(t, ',') -- convert a table into string print ('s = '..s) -- output: s = a,b,c,d print ('---------') u = s:upper() -- get a copy of string s, but with uppercase chars print (u) u = u:lower() -- get a copy of string u, but with lowercase chars print (u) -------------------------------------------------------------------------- การใช้ฟังก์ชันจากไลบรารี่ String ของ Luaนอกเหนือจากการเรียกใช้ฟังก์ชันผ่านตัวแปรแบบสตริงแล้ว ยังมีอีกวิธีสำหรับการจัดการกับสตริง ซึ่งก็คือการใช้ฟังก์ชันจากไลบรารี่ string ของ Lua เช่น string.len(), string.format(), string.char(), string.byte(), string.upper(), string.lower(), string.rep(), string.find(), string.gsub, string.match() และ string.gmatch() เป็นต้น (ศึกษาเพิ่มเติมได้จาก http://www.lua.org/pil/20.html)ข้อสังเกต: รูปแบบการเขียนคำสั่ง string.len(s) ให้ผลเหมือน s:len() ถ้าให้ s เป็นตัวแปรที่อ้างอิงข้อความ ดังนั้นแบบหลังนั้นเป็นรูปแบบที่ช่วยเขียนคำสั่งได้สั้นกว่าแบบแรก โค้ดตัวอย่าง: ex-10.lua #!/usr/bin/env lua -- Learning Lua: Code Example 10 -- Author: RSP @ Embedded Systems Lab (ESL), KMUTNB, BKK/Thailand -- Last Modified: 2015-04-11 s = 'Hello!' print ( string.format("%s %q",s,s) ) -- output: Hello! "Hello!" x = 10 print ( string.format("0x%02x %d",x,x) ) -- output: 0x0a 10 y = 123.456 print ( string.format("%e %.2f",y,y) ) -- output: 1.234560e+002 123.46 print ('---------') s = string.char(97) -- create a string from a single number (byte) print ('s = '..s) -- output: s = a s = string.char(97,98,99,100) -- create a string from 4 numbers print ('s = '..s) -- output: s = abcd -- get the length of string s print (#s,string.len(s),s:len()) -- output: 4 4 4 for i=1,#s do b = string.byte(s,i) -- get the value of a ASCII char at index=i in the string io.write(b, ' ') -- show the value end io.write('\n') -- output: 97 98 99 100 print ('---------') print ( string.rep('*',10) ) -- output: ********** print( ('*'):rep(10) ) -- output: ********** s = "abcdefghijk" -- declare a variable that refers to a string -- get a substring from s print (string.sub(s,1,4)) -- output: abcd -- get a new string from s with uppercase characters print ( string.upper(s) ) -- output: ABCDEFGHIJK print ('---------') s = 'My favorite color is ${color}. I have a pair of ${color} shoes.' s = string.gsub(s,'${color}','red') -- substitute the substring ${color} with a string print(s) -- output: My favorite color is red. I have a pair of red shoes. print ('---------') s = 'The temperature is -8.5 Celsius.' pattern = "[-]?%d+.%d" -- define a 'regex' pattern that matches a floating-point number temp = string.match(s, pattern) -- find the first match print( 'Temp='..temp) -- output: Temp=-8.5 print ('---------') s = 'data: 3,-4,-13,0,193' -- define a string that contains integer numbers pattern = "([-]?%d+)" -- define a 'regex' pattern that matches integers for number in string.gmatch (s, pattern) do print( number ) -- show the next integer end -------------------------------------------------------------------------- แหล่งข้อมูลอ้างอิงและศึกษาเพิ่มเติม
|
เผยแพร่ภายใต้ลิขสิทธิ์ / This work is licensed under: Creative Commons Attribution-NonCommercial 3.0 Unported
ไม่มีความคิดเห็น:
แสดงความคิดเห็น