programming in lua 初读19,20

初学者,有错误希望指正。

19——————————————————————————————环境变量
--声明全局变量,防止拼写错误引起的bug
--将说有全局变量保存在一个表中,使用metttables改变访问全局变量的行为
#!/usr/local/bin/lua
local declaredNames = {}
function declare (name, initval)
    rawset(_G, name, initval)
    --rawset绕过metatable
    declaredNames[name] = true
end
setmetatable(_G, {
    __newindex = function (t, n, v)
    if not declaredNames[n] then
       error("attempt to write to undeclared var. "..n, 2)
    else
       rawset(t, n, v)   
    end
end,
    __index = function (_, n)
    if not declaredNames[n] then
       error("attempt to read undeclared var. "..n, 2)
    else
       return nil
    end
end,
})
declare("a",1)
print(a)
--非全局变量
--使用setfenv在一段chunk中改变环境
--使用继承封装新的环境
a=1
local newgt={}
setmetatable(newgt,{__index=_G})
setfenv(1,newgt)
print(a)
--任何操作对新表进行

20————————————————————packages包

--像标准库,使用表来描述package
--module.lua文件
--[[
local module={}
function  module.one(...)
--body
end
function module.two(...)
--body
end
  ......
  ,....
 --私有成员(privacy)
local function three(...)
   --body
end
--优点:package中所有名字在一个独立的命名空间,每一个实体(entity)都清楚的标记为公有还是私有。
--私有实体在package外部不可访问
--缺点:公有实体加上前缀module
--修改函数状态,必须修改函数调用方式
return module
]]
--解决上方chunk的优缺点
--所有函数声明为局部
local  function one(...) end
local  function two(...) end
local  function three(...) end
local  function four(...) end
local  function five(...) end
module={
  one=one,
  two=two,
  three=three,
four=four,
}
--在module中列出所有的公有函数
return module
--基本格式:用表封装函数
--使用时 用 require "module"调用
--require命令使用文件问不是packages,不需要固定的扩展名,由路径设置决定
————————————————————————————————————————————
--使用全局变量表的metamethods实现package
--package使用独占的环境,
--改变pacjage主chunk的环境,创建的所有函数都共享这个新的环境
local p={}
module=p
setfenv(1,p)
function  one(...) 
--body
end
--这样设置后,one会自动变成module.one,内部的声明或者调用都不需要前缀
————————————————————————————————————————————————————
--主package中定义一个辅助表来记录函数存放的位置:
local location = {
    foo = "/usr/local/lua/lib/pack1_1.lua",
    goo = "/usr/local/lua/lib/pack1_1.lua",
    foo1 = "/usr/local/lua/lib/pack1_2.lua",
    goo1 = "/usr/local/lua/lib/pack1_3.lua",
}
--创建package并定义metamethod:
pack1 = {}
 
setmetatable(pack1, {__index = function (t, funcname)
local file = location[funcname]
if not file then
    error("package pack1 does not define " .. funcname)
end
assert(loadfile(file))()    
return t[funcname]          
end})
 
return pack1
--加载这个package之后,第一次程序执行pack1.foo()将触发__index metamethod,接着发现函数有一个相应的文件,并加载这个文件。微妙之处在于:加载了文件,同时返回函数作为访问的结果。
--因为整个系统都使用Lua写的,所以很容易改变系统的行为。
--例如,函数可以是用C写的,在metamethod中用loadlib加载他。
--或者我们我们可以在全局表中设定一个metamethod来自动加载整个packages.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值