2014-03-28 30 views
1

我是tcl的新手。有没有办法可以处理脚本中调用的不存在的proc。我给你的例子有没有办法处理Tcl中不存在的proc?

想这是我们的代码

package require 65ABC 
package provide package1 
65ABC::callingFunction param1 param2 (# this does not exist in 65ABC) 

It will throw an error saying undefined command 65ABC::callingFunction 

如果我没有记错不知道TCL但在其他语言中,在这些情况下,有一个universal proc。这意味着在上述情况下,调用函数不存在时,它将转到一些通用处理程序,并执行通用处理程序中写入的内容。假设我们可以打印一条消息,说明“这个过程不存在”,或者我们可以做一些其他操作。

更新:加入catch命令不是一个选项。因为我大约有200个这样的特效。我想通过一个superproc来处理这些场景

回答

1

您可以使用catch

package require 65ABC 
package provide package1 
if {[catch {65ABC::callingFunction param1 param2} err]} { 
    puts "Error: $err" 
} 

或许try ... on error

package require 65ABC 
package provide package1 

try { 
    65ABC::callingFunction param1 param2 
} on error {result options} { 
    puts "Something's not so right..." 
    return -options $options $result 
} 
+0

我相信有一些像通用程序。 – Nitesh

+0

@Nitesh你是什么意思? – Jerry

+0

问题是我有大约200个这样的特效。我不能把每个过程捕获。如果我得到像通用过程一样的东西,那么我需要只添加一次消息 – Nitesh

7

你要找的是unknown和/或namespace unknown命令。这些命令记录在这里:

这里是unknown一个简单的例子:

% rename unknown _unknown ;# save reference to the original 
% proc unknown {args} { 
    puts stderr "Hey, I don't know this command: $args" 
    uplevel 1 [list _unknown {*}$args] 
} 
% hello world 
Hey, I don't know this command: hello world 
invalid command name "hello" 

你可以,当然,你要这个proc中什么 - 您可以记录信息,动态创建丢失的特效,引发错误等等。

+0

我们需要编写未知的过程。我们可以在包装中写入65ABC吗? 65ABC是我们正在寻找proc的软件包,比如说65ABC :: testProc – Nitesh

+0

我可以在包含名为65ABC :: unknown的命名空间的包中编写它,而不是编写未知的脚本。我需要那种解决方案 – Nitesh

+2

是的,你可以使用'namespace unknown'命令。 –

0

这只是布莱恩奥克利的答案的扩展。你可以使用tcl的内省来查看调用者并采取适当的行动。任何不是源于B ::命名空间的调用将照常进行处理。

rename unknown _unknown 
proc unknown {args} { 
    array set i [info frame 1] 
    # if the uknown command is in the B:: namespace, use our own 
    # handler, otherwise, run the default. 
    if { [regexp {^B::} $i(cmd)] } { 
    puts "unk: $args" 
    } else { 
    uplevel 1 [list _unknown {*}$args] 
    } 
} 

namespace eval B { 
    proc x {} { 
    puts "B::x" 
    } 
} 

B::x 
B::y 
xyzzy 
1

看来楼主(OP)有兴趣在名字空间65ABC只处理未知程序。如果是这种情况,则proc unknown必须更具选择性:它必须找出未知proc属于哪个名称空间。如果是65ABC,那么我们会自己处理。否则,我们将让系统处理它。以下是我心目中:

rename unknown original_unknown; # Save the original unknown 
proc getns {name {defaultNS "::"}} { 
    set lastSeparatorPosition [string last "::" $name] 
    if {$lastSeparatorPosition == -1} { 
     return $defaultNS 
    } else { 
     incr lastSeparatorPosition -1 
     return [string range $name 0 $lastSeparatorPosition] 
    } 
} 
proc unknown {args} { 
    set procName [lindex $args 0] 
    set ns [getns $procName] 
    puts "$args, happens in name space -- $ns" 

    if {$ns == "::65ABC" || $ns == "65ABC"} { 
     puts " We will handle this ourselves" 
    } else { 
     uplevel 1 [list original_unknown {*}$args] 
    } 
} 

# Test it out 
namespace eval ::65ABC { 
    proc foo {args} { puts "::65ABC::foo $args" } 

    # This will never get called 
    proc unknown {args} { 
     puts "::65ABC::unknown -- $args" 
    } 
} 

::65ABC::bar hello there; # We will handle this case 
65ABC::foobar 1 2 3;  # Also handle this case 
foo bar;     # The system will handle this case 

输出

::65ABC::bar hello there, happens in name space -- ::65ABC 
    We will handle this ourselves 
65ABC::foobar 1 2 3, happens in name space -- 65ABC 
    We will handle this ourselves 
foo bar, happens in name space -- :: 
invalid command name "foo" 
    while executing 
"original_unknown foo bar" 
    ("uplevel" body line 1) 
    invoked from within 
"uplevel 1 [list original_unknown {*}$args]" 
    (procedure "::unknown" line 12) 
    invoked from within 
"foo bar" 
    (file "/Users/haiv/Dropbox/src/tcl/unknown_proc.tcl" line 47) 

讨论

  • proc unknown我已经是基本相同布莱恩Oakley的,但也有一些额外的代码,以确定哪些未知proc所属的名称空间。
  • 要确定未知的proc的名称空间,我创建了proc gents,它返回最后一个"::"之前的文本。如果proc名称不包含"::",则gents将为全局名称空间返回"::"
  • 在命名空间65ABC中写入unknown proc不起作用。我试过了。
相关问题