2014-03-28 32 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不起作用。我試過了。
相關問題