我最近在看一些网友写的脚本时,发现有存在一个共同的问题:
脚本有出错的可能
出错的原因不是程序设计本身的问题,而是没有考虑到用户的操作可能不会按照作者的意图去进行。一个完善的脚本是必须要考虑到各种意外情况的,毕竟如果脚本在运行的弹出错误信息,或者带界面的脚本直接崩溃,这都会带来很差的体验。
我写脚本的时候,经常考虑的一个问题是:**如果用户是一个专门捣蛋的人,我怎么能保证脚本无论什么情况下都不会出错或崩溃?**比如,如果脚本需要先画出time selection,而对方偏不画?如果脚本需要对选中的item进行处理,而对方偏不选?如果你要对方输入一个数字,而对方输入了文字?
你的脚本能不能在不满足必要条件的时候不出错?
这是写脚本的时候,除了主要功能以外,必须考虑的一个点,你必须无死角的堵住每个会导致你出错的漏洞。最常用的方法就是,如果必要条件不满足,停止运行:
if XXX then return end
例1 获取选中item的名字
local it=reaper.GetSelectedMediaItem(0, 0)
local tk=reaper.GetActiveTake(it)
local name=reaper.GetTakeName(tk)
reaper.ShowConsoleMsg(name)
正常来说,这些代码能显示出选中item的名字,但这里埋了两个坑在里面。如果没有选中item就运行,就会得到出错信息:
bad argument #1 to 'GetActiveTake' (MediaItem expected)
因为没有选中item,所以第一行获得的就是个空值,因此在第二行想要获取take的时候报错。因此得先加一个判断,如果没有选中item的话脚本提前结束
if reaper.CountSelectedMediaItems(0)==0 then return end --没有选中item的情况
local it=reaper.GetSelectedMediaItem(0, 0)
local tk=reaper.GetActiveTake(it)
local name=reaper.GetTakeName(tk)
reaper.ShowConsoleMsg(name)
第二个坑在于第三行,如果选中的是一个empty item,因为empty item没有take,因此获取到的也是一个空值,导致第四行会出错
bad argument #1 to 'GetTakeName' (MediaItem_Take expected)
所以要对获取到的take加一个判断是否空值,是的话提前结束
if reaper.CountSelectedMediaItems(0)==0 then return end --没有选中item的情况
local it=reaper.GetSelectedMediaItem(0, 0)
local tk=reaper.GetActiveTake(it)
if not tk then return end --判断是否empty item
local name=reaper.GetTakeName(tk)
reaper.ShowConsoleMsg(name)
这样下来,可以保证无论对方如何操作,都不会有出错的可能
例2 获取用户输入内容
一般用这个函数来获取
local check, text=reaper.GetUserInputs('title', 1, 'content', '')
当用到这个函数,首先应该考虑:如果用户点了取消或者关掉窗口怎么办?函数第一个返回值就是检测这个的,点取消或者关掉窗口,第一个返回值(check)会是false,因此下一步应该先做判断:
local check, text=reaper.GetUserInputs('title', 1, 'content', '')
if not check then return end --检测是否正常输入
然后如果用户给你捣蛋,输入窗口是空的,然后点了确定。这时变量check是true,输入值text将是一个空字符串’’,因此再多加一个判断:
local check, text=reaper.GetUserInputs('title', 1, 'content', '')
if not check or text=='' then return end --检测是否正常输入
这样最大程度避免了获得不正常输入而导致后面出错的可能。但这还是初步的,还要根据程序具体的设计,使用 string.match 函数来判断一下这个获取到的数值是否符合要求的格式