《Programming in Lua 3》读书笔记(二十)

阅读: 评论:0

《Programming in Lua 3》读书笔记(二十)

《Programming in Lua 3》读书笔记(二十)

日期:2014.7.29 PartⅢ The Standard Libraries 24 The Debug Library
Lua的debug库并不是提供一个调试器,而是提供一些供你写调试器的一些操作。Lua实现这些功能是以C API来实现的,因此这个库相当于提供使用Lua代码访问C API,这是从性能上考虑的。 Lua的debug库包含两类函数:introspective function和hooks(啥东西?)。前面一个函数允许我们对调试正在运行的程序(当前运行到的行数、局部变量的名字和值等);hook则允许我们回溯程序的运行过程。 Debug库一个重要的概念是:stack level。指的是一个代表当前阶段一个特定函数的活跃值:访问debug库的函数其level为1,调用该函数的函数其level为2。
24.1 Introspective Facilities debug库中主要的内省函数是info。该函数的第一个参数可以是一个函数也可以是一个stack level。当参数是一个函数的时候,该函数返回一个table包含该函数的一些信息: 当参数函数为一个C函数的时候,返回信息仅包括函数类型(Lua C)、名字、函数名的前一个字段(global local 等) 当以数值作为参数调用该函数的时候,该数值代表一个stack level。此时会得到一个满足该level的函数的信息。如当n为1的时候,会得到进行执行调用的函数,当为0的时候,得到getinfo这个函数本身,当n大于stack中活跃函数的数量的时候,返回nil。when you query an active function,info with a number,the result table has an extra field ,currentline,with the line where the function is at that moment.Moreover,func has the function that is active at that level. table中的字段name需要谨慎对待,因为lua中的函数可以没有名字,也可以有多个名字。 作者也提到,getinfo函数不怎么高效。lua以一种不损害程序运行的形式保存debug的信息,efficient retrieval is a secondary info函数接受一个第二参数用来选择需要得到的信息以提高效率,此时函数不会去收集用户不需要的信息。该参数的类型是一个字符串型,一个字母收集一类字段的信息: 'n'     收集 name 和 namewhat 'f'      收集 func 'S'     收集source,short_src,what,linedefined,和lastlinedefined 'l'      收集 currentline 'L'      收集 activeline 'u'     收集 nup 下面的例子介绍了info函数的使用:
  Accessing local variables 可以使用local 函数查看任意活跃函数中的局部变量,这个函数有两个参数:访问的函数的stack level和访问变量的index值。该函数返回两个值:访问变量的名字和值。如果参数index值大于函数中总的变量的值,那么getlocal函数返回nil。如果stack level值不符合要求,则会引起错误(此时的技巧是通过getinfo函数来先验证stack level)
函数中的局部变量依据其出现的顺序进行排序,最先出现的变量其index值最小,而且只会对当前函数有效区间内的变量进行计数,举例来看:
function foo( a,b )local xdo local c = a - b endlocal a = 1while true dolocal name,value = local(1,a)if not name then break endprint(name,value)a = a + 1endendfoo(10,29)
打印出来的值为: a     10 b     29 x     nil a     4 函数中首先出现的局部变量是a,其index为1,其次是b,index为2,接着是x,index为3,最后为函数体内部的局部变量a,其index为4.此时要注意的是,函数体内的局部变量c,有其自身的有效范围,此时已经在函数体的有效范围之外了。(局部变量只会在其初始化代码之后可见)。 自Lua5.2开始,负数作为参数会得到函数的一些额外信息:index -1代表第一个额外信息,此时这个name总是"(*vararg)".---这段内容还有待考证 也可以通过函数debug.setlocal来改变局部变量的值,该函数的前两个参数分别为:stack level 和变量的index值,第三个参数则为要设定的新的值。如果index超出了范围,则该函数会返回nil值
  Accessing non-local variables 使用一个lua函数:getupvalue 可以使我们访问非局部变量。与局部变量不同的是,非局部变量是当函数非active的时候才会存在(这也是所谓的闭包),因此该函数的第一个参数不是一个stack level ,而是一个函数(准确的说是一个闭包),第二个参数是变量的index值,其顺序和局部变量一致都是先出现的index值越小。(函数不能以同一个名字访问两个非局部变量) 使用setupvalue 可以用来改变非局部变量的值,与setlocal一样,函数也是三个参数,只不过第一个参数是一个闭包。
  Accessing other coroutines dubug库中的所有内省函数都接受一个可选参数--一个协同程序作为其第一参数,因此我们也可以从外部查看协同程序,例如:
co = ate(function ( ... )local x = 10coroutine.yield()error("some error")sume(co)aceback(co))
运行该段代码打印出: stack traceback: [C]: in function 'yield' 此时在yield函数内部
回溯不会执行resume,因为协同程序和主程序不在同一个栈中。 当协同程序引发错误的时候,不会存在与当前的这个栈中。这就意味着我们可以在其引发的错误之后查看该协同程序,继续上述的例子,假如我们此时再一次resume协同程序,这次便会引发错误:
sume(co)aceback(co))sume(co))
--打印 stack traceback: [C]: in function 'yield' false     some error
而此时再一次回溯:
sume(co)aceback(co))sume(co))aceback(co))
--打印 stack traceback: [C]: in function 'yield' false    some error stack traceback: [C]: in function 'error' 此时便会到error函数内部了
我们甚至可以再函数产生错误之后再范围协同程序内部的局部变量 local(co,1,1)) --打印 x 10           --这个是协同程序内部的局部变量x的值
24.2 Hooks Lua debug库的hook机制允许我们注册一个函数的调用,然后在程序运行的某个特定时间点调用我们注册的那个函数。这里有四个时间点(events 事件?)可以触发一个hook: call events           每次lua调用一个函数的时候就触发这个事件 return events        每次函数返回值的时候触发这个事件 line events           每当lua开始执行新的一行代码的时候触发这个事件 count events          进过给定数量的指令后触发这个事件
Lua通常以一个参数调用hooks,这个参数是字符串型,代表某个事件:"call"("tail call"),"return","line","count".当参数是line的时候,函数也接受新的一行的行数作为第二个参数。而如果需要得到更多关于hook内部的信息,则需要使用函数&#info. 使用函数debug.sethook 可以注册一个hook,参数为两个可选第三个参数:第一个参数是要注册的函数;第二个参数是一个string字符串型,代表需要触发的事件('c','r','l'); 可选的第三参数代表我们想获得count event事件的频率;call,return,line事件通过第二个参数控制,而可选的第三个参数用来控制count事件。关掉一个hook,则以无参数调用sethook。

24.3 Profiles Lua的debug库不仅可以用来做debug,还可以用来(profiling??)

本文发布于:2024-01-28 02:16:40,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063794064069.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:二十   读书笔记   Programming   Lua
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23