Dies ist eine alte Version des Dokuments!
Programming in Lua (5.0) Tutorial — Reference Manual — Short Reference — IBM intro: Embeddable scripting with Lua — Linux Journal intro: A Look at Lua
#!/usr/bin/lua
Use global table arg
local inp= io.stdin:read() -- Read a line from stdion print() -- Print a line to stdout io.stdout:write() -- Print a string to stdout io.stderr:write() -- Print a string to stderr
for i = 0,24,4 do -- start, end (including), step print(i) end
Use #
operator
-- Iterate over array part: for i,v in ipairs(now) do print(i,v) end -- Iterate over complete table: for k,v in pairs(now) do print(k,v) end
pairs()
#!/usr/bin/lua -- Numbers: a=3 -- a contains 3 b=a -- b contains 3 a=4 -- a contains 4, b still contains 3 print(a,b) -- 4 3 -- Booleans: a=true; b=a; a=false print(a,b) -- false true -- Strings: a="World" -- a points to the string "World" b=a -- b points to the same string a="Hello" -- a points to "World", b still points to "Hello" print(a,b) --> Hello World -- Functions: a= function() print("World") end b=a -- a and b point to the same function: print(a,b) --> function: 0x80500e8 function: 0x80500e8 a= function() print("Hello") end -- a points to a new function and b still points to the old function: print(a,b) --> function: 0x8050a48 function: 0x80500e8 a() -- Hello b() -- World
#!/usr/bin/lua -- Tables: a={3} b=a; -- a and b point to the same table: print(a,b) -- table: 0x80509e0 table: 0x80509e0 print(a[1],b[1]) -- 3 3 a[1]=4; print(a[1],b[1]) -- 4 4 b[1]=5 print(a[1],b[1]) -- 5 5 a={6} -- a points to a new table and b still points to the old table: print(a,b) -- table: 0x8050a30 table: 0x80509e0 print(a[1],b[1]) -- 6 5 b[1]=7 print(a[1],b[1]) -- 6 7
This is simliar to Go
A throw/catch mechanism is possible with error() / pcall(). More
-- rectangle prototype: rectangle_proto= {species="rectangle"} function rectangle_proto:area() return self.width * self.height end -- rectangle constructor: function new_rectangle(width, height) local rectangle= {width= width, height= height} setmetatable(rectangle, {__index=rectangle_proto}) return rectangle end -- rectangle usage: rectangle= new_rectangle(3,4) print(rectangle:area()) --> 12 print(rectangle.species) --> rectangle -- circle prototype: circle_proto= {species="circle"} function circle_proto:area() return self.radius^2 * math.pi end -- circle constructor: function new_circle(radius) local circle= {radius= radius} setmetatable(circle, {__index=circle_proto}) return circle end circle= new_circle(1) print(circle:area()) --> 3.14 print(circle.species) --> circle
Classic single inheritance chain:
-- Inheritance: shape prototype: shape_proto= {family="shape"} function shape_proto:get_species() return self.species end function shape_proto:get_family() return self.family end setmetatable(rectangle_proto, {__index=shape_proto}) setmetatable(circle_proto, {__index=shape_proto}) print(circle:get_family().."/"..circle:get_species()) --> shape/circle print(rectangle:get_family().."/"..rectangle:get_species()) --> shape/rectangle
Lua print()
does not look for a tostring()
method directly in the table, instead it looks for a method called __tostring()
in its metatable. Thus, to enable both print(myobject:tostring())
(explicit call) and print(myobject)
(implicit call), provide the tostring() method in the prototype table of the object and set __tostring
attribute of the metatable to that method:
-- rectangle prototype: rectangle_proto= {} function rectangle_proto:tostring() return "["..self.width.."|"..self.height.."]" end -- rectangle constructor: function new_rectangle(width, height) rectangle= {width= width, height= height} setmetatable(rectangle, { __index=rectangle_proto, __tostring=rectangle_proto.tostring }) return rectangle end -- rectangle usage: rectangle= new_rectangle(3,4) print(rectangle:tostring()) --> [3|4] print(rectangle) --> [3|4]
This works also if tostring()
is defined in the base clase:
-- shape as base class: shape_proto= {} function shape_proto:tostring() return "["..self.width.."|"..self.height.."]" end -- rectangle prototype inherits from shape: rectangle_proto= {} setmetatable(rectangle_proto, { __index=shape_proto }) -- rectangle constructor: function new_rectangle(width, height) rectangle= {width= width, height= height} setmetatable(rectangle, { __index=rectangle_proto, __tostring=rectangle_proto.tostring }) return rectangle end -- rectangle usage: rectangle= new_rectangle(3,4) print(rectangle:tostring()) --> [3|4] print(rectangle) --> [3|4]
local M= {} local private= {} -- holds private data of all objecs in subtables -- Class Point: -- local Point_proto= {} -- Class prototype function Point_proto:set(x,y) local priv= private[self] priv.x= x priv.y= y end function Point_proto:get() local priv= private[self] return priv.x, priv.y end function Point_proto:tostring() local priv= private[self] return "["..priv.x.."|"..priv.y.."]" end Point_proto.__index = Point_proto Point_proto.__newindex= function() assert(false,"object is write-protected") end setmetatable(Point_proto, { -- ensure read protection for Point and all childs __index= function() assert(false, "object is read-protected") end }) function M.new_Point(x,y) -- constructor local instance= {} setmetatable(instance, Point_proto) private[instance]= {} -- create private part of object instance:set(x,y) return instance end return M
#!/usr/bin/lua local point= require "point" local print_r= function(table) for key,value in pairs(table) do io.write("[", key, "] = ", tostring(value), "\n") end end local p= point.new_Point(3,4) --p.x= 8 --> Write access throws an error --print(p.y) --> Read access throws an error print(p:tostring()) --> [3|4] print_r(p) --> prints nothing
local M= {} local private= {} -- holds private data of all objecs in subtables -- Class Point: -- -- ... -- CLASS MovablePoint: -- local MovablePoint_proto= {} -- Class prototype function MovablePoint_proto:move(dx, dy) local priv= private[self] priv.x= priv.x+dx priv.y= priv.y+dy end MovablePoint_proto.__index = MovablePoint_proto MovablePoint_proto.__newindex= Point_proto.__newindex setmetatable(MovablePoint_proto, Point_proto) -- Inherit from Point function M.new_MovablePoint(x,y) -- constructor local instance= M.new_Point(x,y) -- call parent constructor setmetatable(instance, MovablePoint_proto) return instance end return M
#!/usr/bin/lua local point= require "point" -- ... local mp= point.new_MovablePoint(5,6) mp.x= 9 --> Write access throws an error print(mp.y) --> Read access throws an error print(mp:tostring()) --> [5|6] mp:move(2,1) print(mp:tostring()) --> [7|7] print_r(mp) --> prints nothing
To run some code sitting in a different file, use dofile()
To load global variables of an external (config) file into a table locally, you have to pass the table as environment:
a="Harry" b="Hirsch"
#!/usr/bin/lua local extenv={} local chunk= loadfile("config.lua", "t" , extenv) chunk() for key,value in pairs(extenv) do io.write("[", key, "] = ", value, "\n") end
[a] = Harry [b] = Hirsch
See ModuleDefinition and LuaStyleGuide → Modules
module()
is deprecated!
now= os.time()
-- Return a table containing hour, min, wday, day, ... of current time: now = os.date("*t") -- Return a table containing hour, min, wday, day, ... of a certain time: atime = os.date("*t", timestamp) -- Return a formated string of current time: now = os.date("Today is %A") -- Today is Thursday
Example:
-- global.lua a=0 b=0 for i=1, 10000000 do a= b+1 b= a end
$time global.lua real 0m1.178s user 0m1.176s sys 0m0.001s
-- local.lua local a=0 local b=0 for i=1, 10000000 do a= b+1 b= a end
$time local.lua real 0m0.161s user 0m0.157s sys 0m0.003s
table.concat()
See also:
#!/usr/bin/lua co= coroutine.create(function() while true do io.stderr:write('co: waking up\n') local inp= io.stdin:read() io.stderr:write('co: read "'..inp..'", going to sleep\n') coroutine.yield(inp) end end) while true do io.stderr:write('main: going to sleep\n') local state, oup= coroutine.resume(co) io.stderr:write('main: waking up\n') print('> '..oup) end