调试 101:VS 代码中的第一个断点和跟踪变量
本文将讨论 Microsoft Visual Studio Code IDE中包含的所有调试工具 。
内容包括
- 断点
- 观察窗口
- 调用堆栈
让我们从了解调试要求开始!
前提条件
有两个插件(扩展)可用于调试 ObjectScript:
第一个是 InterSystems ObjectScript 扩展包的一部分 。第二个是 Serenji,它是一个独立的插件,提供编辑器、文件管理器和调试功能。这两个插件都可以从插件商店安装。要激活关键功能,Serenji 需要许可证。在本文中,我们将使用 InterSystems ObjectScript 扩展包来降低学习难度。在掌握基础知识后,您可以考虑购买 Serenji 的付费许可证。
您需要
- 最新版本的 Microsoft Visual Studio Code IDE
- 安装 InterSystems ObjectScript Extension Pack 插件(安装 Visual Studio Code 后)
- InterSystems IRIS 实例。您可以选择 Docker 版本或安装包。(您必须在 开发人员社区 生态系统中注册)
如何将 IRIS 连接到 Microsoft Visual Studio Code IDE,请 点击此处。
设置调试功能
通常,配置文件会在调试开始后自动生成。配置文件如下
{
"configurations": [
{
"type": "objectscript",
"request": "launch",
"name": "ObjectScript Run current routine",
"program": "${file}"
}
]
}
其中 type 是调试代码的语言,request 是调试启动选项(launch - 启动并执行代码,attach - 连接到已运行的代码),name 是调试标识符,program 是调试类和方法的名称(在此配置中,将拾取打开的文件)。
断点
任何程序代码都是自上而下逐行执行的。调试时,了解程序在任何特定时刻的状态非常重要,包括局部变量和全局变量的值、文件的打开和关闭、网络连接等。
断点(Breakpoint)是一种调试工具,它允许你在特定行暂停程序的执行,以确定程序状态中不必要的变化。 在 Visual Studio Code 中开始调试非常简单。 比方说,我们有如下代码:
Class Test.MyFile Extends %RegisteredObject
{
ClassMethod TestVar() As %Integer
{
set randomNum = $RANDOM(10)
return randomNum
}
ClassMethod MyMethod() As %Integer
{
set randomNum = ..TestVar()
set numVar = 2
set numDivision = randomNum / numVar
return numDivision
}
}
我们需要了解存储在 MyMethod() 方法中randomNum变量的值。它由 TestVar() 方法返回。我们在第 15 行对该变量执行算术运算之前设置一个断点,然后单击调试按钮。如果不设置断点,调试只会执行代码,不会向控制台输出任何内容。
开始调试后,我们可以立即看到给定变量的值!非常方便。接下来,我们可以按 Step into 按钮或 F11 逐行查看整个程序。
好极了!现在我们知道了代码执行过程中每一步的变量值。
我们可以用同样的方法在循环中循环变量。下面是一段代码
Class Test.MyFile Extends %RegisteredObject
{
ClassMethod LoopMethod() As %List
{
set objList = $LB("string", 1, {"name":1})
for i=1:1:$LL(objList){
set item = $LG(objList, i)
}
return objList
}
}
在方法的开头设置一个断点,开始调试。然后,使用 IDE 顶部调试面板上的 "Step into "按钮,向下移动程序并观察分配给项变量的值。我们还可以看到程序中所有其他变量的值,包括迭代器变量i,在本例中i 的值等于 2。
因此,沿着循环向前移动,就可以跟踪到循环的每一步将为 item 变量分配什么值。
观察窗口
在调试过程中,我们还可以通过将变量添加到观察模式来监控变量的状态。在观察模式下,我们可以对变量应用方法,并在每次迭代中测量其状态。例如,请看下面的代码
Class Test.MyFile Extends %RegisteredObject
{
ClassMethod WatchAVariable() As %List
{
set list = ""
set randomNum = $RANDOM(100)
for int=randomNum:randomNum:100000{
set list = list _$LB(int)
}
return list
}
}
我们将为 list 变量编写三个方法:
我们要跟踪 list 的长度 $LL(list)、最后添加的数字 $LG(list, -1) 及其平方根 $LG(list, -1) ** 0.5。我们进入循环并获取第一个值:
通过在观察窗口中定义函数,我们可以看到详细的调试信息!此外,变量窗口仍然显示 int iterator 变量的值和循环步骤。非常方便!
调用堆栈窗口
注意最下方的 "调用堆栈 "窗口。该窗口显示代码中函数调用的顺序。在当前状态下,我们有两个项目:循环以及分别为变量 WatchVariable+7 和 WatchVariable+6 赋值。但这里的一切都不言自明。让我们再添加一些逻辑:
Class Test.MyFile Extends %RegisteredObject
{
ClassMethod RandomlyChangeVar() As %Integer
{
return $RANDOM(100)
}
ClassMethod WatchAVariable() As %List
{
set list = ""
set randomNum = $RANDOM(100)
for int=randomNum:randomNum:100000{
set list = list _$LB(int)
if $LG(list, -1) ** 0.5 > 10{
set int = int + ..RandomlyChangeVar()
}
}
return list
}
}
我们添加了一个新方法 RandomlyChangeVar(),如果上一个数字的平方根大于 10,该方法将改变下一个 int 变量。我们循环运行,直到变量的状态满足逻辑条件(这是一个 GIF):_anim_preview.jpg)
请注意平方根函数的值和调用堆栈中函数调用的顺序。只要平方根超过 10,就会立即调用 RandomlyChangeVar() 函数!此外,通过测量列表的长度,我们还能跟踪到需要多少循环步骤才能达到所需的逻辑条件。这样,无论逻辑多么复杂,都能轻松跟踪调用多个函数的顺序和条件。
就是这样!
在本文中,我们详细介绍了VSCode 的调试功能。设置了首个断点,并追踪了变量的取值变化。