ZeroBrane Studio で LuaAppMaker のスクリプトをデバッグする方法をメモしておく(Mac版)
まず、ZeroBrane Studio アプリを右クリックして「パッケージの内容を表示」し、Contents/ZeroBraneStudio/interpreters
フォルダを開く。このフォルダの中に、下のスクリプトを luaappmaker.lua
として保存する。
-- LuaAppMaker interpreter settings
-- Based on love2d.lua
-- Copyright 2011-16 Paul Kulchenko, ZeroBrane LLC
-- Copyright 2019 Toshi Nagata
local pathcache
local win = ide.osname == "Windows"
local mac = ide.osname == "Macintosh"
return {
name = "LuaAppMaker",
description = "wxLua application",
api = {"baselib", "wxwidgets"},
frun = function(self,wfilename,rundebug)
local luaappmaker = ide.config.path.luaappmaker or pathcache -- check if the path is configured
local projdir = self:fworkdir(wfilename)
if not luaappmaker then
local sep = win and ';' or ':'
local default =
win and (GenerateProgramFilesPath('LuaAppMaker', sep)..sep)
or mac and ('/Applications/LuaAppMaker.app/Contents/MacOS'..sep)
or ''
local home = wx.wxGetHomeDir()
local pathsep = wx.wxFileName.GetPathSeparators():sub(1, 1)
local path = default
..(os.getenv('PATH') or '')..sep
..(GetPathWithSep(projdir))..sep
..home..sep
..(home .. pathsep ..'bin')
local paths = {}
for p in path:gmatch("[^"..sep.."]+") do
if win then p = p .. pathsep .. 'LuaAppMaker' end
luaappmaker = luaappmaker or GetFullPathIfExists(p, win and 'LuaAppMaker.exe' or 'LuaAppMaker')
table.insert(paths, p)
end
if not luaappmaker then
ide:Print("Can't find LuaAppMaker executable in any of the following folders: "
..table.concat(paths, ", "))
return
end
pathcache = luaappmaker
end
if not GetFullPathIfExists(projdir, 'wxmain.lua') then
local altpath = wfilename:GetPath(wx.wxPATH_GET_VOLUME)
local altname = GetFullPathIfExists(altpath, 'wxmain.lua')
if altname and wx.wxMessageBox(
("Can't find 'wxmain.lua' file in the current project folder.\n"
.."Would you like to switch the project directory to '%s'?"):format(altpath),
"LuaAppMaker interpreter",
wx.wxYES_NO + wx.wxCENTRE, ide:GetMainFrame()) == wx.wxYES then
ide:SetProject(altpath)
projdir = altpath
else
ide:Print(("Can't find 'wxmain.lua' file in the current project folder: '%s'.")
:format(projdir))
return
end
end
if rundebug then
ide:GetDebugger():SetOptions({runstart = ide.config.debugger.runonstart ~= false})
end
-- suppress hiding ConsoleWindowClass as this is used by Love console
local uhw = ide.config.unhidewindow
local cwc = uhw and uhw.ConsoleWindowClass
if uhw then uhw.ConsoleWindowClass = 0 end
local params = self:GetCommandLineArg()
local cmd = ('"%s" "%s"%s%s'):format(luaappmaker, projdir,
params and " "..params or "", rundebug and ' -debug --' or '')
-- CommandLineRun(cmd,wdir,tooutput,nohide,stringcallback,uid,endcallback)
return CommandLineRun(cmd,projdir,true,true,nil,nil,
function() if uhw then uhw.ConsoleWindowClass = cwc end end)
end,
hasdebugger = true,
scratchextloop = true,
takeparameters = true,
}
LuaAppMaker のメインスクリプトである wxmain.lua
の最初に、下の1行を入れる。
if LuaApp.debug then LuaApp.debug.start() end
実行すると、上の1行を実行した直後に一旦停止する。これは、意図的にそのような仕様にしてある。必ずしも必要ない仕様かも知れないけど、「デバッガの管理下で動作している」ことを確認できる、という意図でこうしてある。
実行を続けて、ブレークポイントに到達すると、このようにスタックトレースが表示される。
変数の値はスタックトレースでもわかるが、Remote Console で式を入力すると、その結果が表示される。最初に @2
と入れると、2番目のスタック上での値が表示される。
ブレークポイントでない場所で止まった時は、ランタイムエラーが発生している。エラーメッセージは LuaApp.debug.errorMessage
で表示できる。これを ZeroBrane Studio のコンソールに自動表示したいんだけど、やり方がどうしてもわからなかった。ちなみに、このランタイムエラーの原因は、self.text:SetValue(...)
のコロンをピリオドと間違えたこと。けっこうやっちゃうんだよね。
スクリプト言語でアプリを作る時は、ランタイムエラーに悩まされることが大変多い。エラーで止まった時の変数の値やスタックトレースを確認できるのは、非常にありがたい。ZeroBrane Studio と Lua の組み合わせはなかなか素晴らしいと思うんだけど、全然流行りませんねえ。