Stored procedures 如何处理传递给proc的不存在的变量
我想创建一个类似以下简单示例的过程:Stored procedures 如何处理传递给proc的不存在的变量,stored-procedures,tcl,args,Stored Procedures,Tcl,Args,我想创建一个类似以下简单示例的过程: proc name {args} { foreach val $args { puts $val } } 但是我希望这个过程能够处理不存在的变量,比如下面的代码: proc name {args} { foreach val $args { if [info exists $val] { puts $val } } } 问题是代码没有被执行,因为只
proc name {args} {
foreach val $args {
puts $val
}
}
但是我希望这个过程能够处理不存在的变量,比如下面的代码:
proc name {args} {
foreach val $args {
if [info exists $val] {
puts $val
}
}
}
问题是代码没有被执行,因为只要我用一个不存在的变量调用过程,它就会立即暂停,然后再进入代码,说有一个不存在的变量。是否可能是因为程序在进入正文之前检查了参数存在
我可以通过使用几个带有预定义值的可选变量来更改args
使其工作,但这限制了过程并使其看起来很糟糕
我可以制作一个能够处理不存在的变量的程序吗?您在这里犯了一个错误
if [info exists $val]
当信息存在时
被使用应根据变量名称而不是变量值进行检查。
让我们来谈谈你的实际问题
您可以将参数作为键值对传递给过程,这非常简单
proc user_info {args} {
#Converting the arguments into array
if {[catch {array set aArgs $args}]} {
puts "Please pass the arguments as key-value pair"
return 1
}
#Assume, we need to ensure these 3 arguments passed for sure.
set mandatoryArgs "-name -age -country"
foreach mArg $mandatoryArgs {
if {![info exists aArgs($mArg)]} {
puts "Missing mandatory argument '$mArg'"
return 1
}
}
}
user_info -name Dinesh
你犯了个错误
if [info exists $val]
当信息存在时
被使用应根据变量名称而不是变量值进行检查。
让我们来谈谈你的实际问题
您可以将参数作为键值对传递给过程,这非常简单
proc user_info {args} {
#Converting the arguments into array
if {[catch {array set aArgs $args}]} {
puts "Please pass the arguments as key-value pair"
return 1
}
#Assume, we need to ensure these 3 arguments passed for sure.
set mandatoryArgs "-name -age -country"
foreach mArg $mandatoryArgs {
if {![info exists aArgs($mArg)]} {
puts "Missing mandatory argument '$mArg'"
return 1
}
}
}
user_info -name Dinesh
不能将变量作为参数传递:参数必须是值。可以将变量名作为参数传递,并将其用作过程中变量的引用。例如:
proc name args {
foreach varname $args {
upvar 1 $varname var
if {[info exists var]} {
puts $var
}
}
}
(对upvar
的调用在过程外部变量varname
的值与过程内部变量var
之间创建链接。这是“将变量传递给过程”的一种方法。)
然后你可以这样做:
% set foo 1 ; set baz 3
% name foo bar baz
1
3
请注意,如果您尝试按以下方式调用该过程:
% name $bar
如果bar
未定义,解释器会在调用过程之前尝试(但失败)对其求值。这可能就是你所看到的
文件:
不能将变量作为参数传递:参数必须是值。可以将变量名作为参数传递,并将其用作过程中变量的引用。例如:
proc name args {
foreach varname $args {
upvar 1 $varname var
if {[info exists var]} {
puts $var
}
}
}
(对upvar
的调用在过程外部变量varname
的值与过程内部变量var
之间创建链接。这是“将变量传递给过程”的一种方法。)
然后你可以这样做:
% set foo 1 ; set baz 3
% name foo bar baz
1
3
请注意,如果您尝试按以下方式调用该过程:
% name $bar
如果bar
未定义,解释器会在调用过程之前尝试(但失败)对其求值。这可能就是你所看到的
文件:
如果我们看一下您调用命令的位置(过程是命令;它们实际上是一个子类),您将在代码中看到如下内容:
name$a$b$c
如果所有这些变量都存在,这很好,但如果不存在,它将在调用name
之前爆炸。在Tcl中,$a
的意思正是“读取变量a
并在此处使用其内容”,而在其他一些语言中,$
的意思是“注意语言,这里有一个变量名!”
因此,我们需要将调用约定更改为适用于以下内容的约定:
name a b c
这需要使用upvar
。像这样:
proc name{args}{
foreach varName$args{
#将调用方的命名变量映射到本地名称“v”
upvar 1$varName v
#现在我们可以用一种简单的方法来处理v
如果{[info exists v]}{
卖出$v
}
}
}
如果我们看一下您调用命令的位置(过程是命令;它们实际上是一个子类),您将在代码中看到如下内容:
name$a$b$c
如果所有这些变量都存在,这很好,但如果不存在,它将在调用name
之前爆炸。在Tcl中,$a
的意思正是“读取变量a
并在此处使用其内容”,而在其他一些语言中,$
的意思是“注意语言,这里有一个变量名!”
因此,我们需要将调用约定更改为适用于以下内容的约定:
name a b c
这需要使用upvar
。像这样:
proc name{args}{
foreach varName$args{
#将调用方的命名变量映射到本地名称“v”
upvar 1$varName v
#现在我们可以用一种简单的方法来处理v
如果{[info exists v]}{
卖出$v
}
}
}