출처: http://people.man.ac.uk/~zzcgudf/tcl/try.tcl
아래의 코드로 Tcl에서도 try/catch/finally 구문을 사용할 수 있습니다. 이 스크립트를 사용하면 예외 처리를 쉽게 할 수 있어 스크립트의 오류를 최소한의 코드로 구조화된 방식으로 처리할 수 있습니다. Tcl 8.0 이상에서 사용 가능합니다.
namespace eval ::try {
namespace export try
variable bodyMatch { \("uplevel" body line}
proc helper {script part {eiv ei} {ecv ec} {codev code} {msgv msg}} {
global errorInfo errorCode
variable bodyMatch
upvar 1 $eiv ei $ecv ec $codev code $msgv msg
set code [catch [list uplevel 2 $script] msg]
set ec $errorCode
set lines [split $errorInfo "\n"]
if {$code == 1} {
while {![regexp $bodyMatch [lindex $lines end]]} {
set lines [lrange $lines 0 [expr {[llength $lines]-2}]]
}
regsub {"uplevel" body} [lindex $lines end] $part fixed
set lines [lrange $lines 0 [expr {[llength $lines]-2}]]
lappend lines $fixed
}
set ei [join $lines "\n"]
}
proc try {body args} {
# First, parse apart the args
set hasFinally 0
set catches {}
for {set i 0} {$i<[llength $args]} {incr i} {
set word [lindex $args $i]
if {![string compare $word catch]} {
if {$i+1 >= [llength $args]} {
return -code error "missing matcher to catch"
} elseif {$i+2 >= [llength $args]} {
return -code error "missing body to catch"
}
lappend catches [lindex $args [incr i]]
lappend catches [lindex $args [incr i]]
} elseif {![string compare $word finally]} {
if {$i+1 >= [llength $args]} {
return -code error "missing body to finally"
}
set finally [lindex $args [incr i]]
set hasFinally 1
} else {
return -code error "unknown keyword \"$word\" to try:\
should be \"try body ?catch matcher body ...?\
?finally body?\""
}
}
# Now evaluate the body
helper $body "try body"
# Handle errors
if {$code == 1} {
foreach {matcher handler} $catches {
if {[string match $matcher $ec]} {
helper $handler "catch \"$matcher\" body"
break
}
}
}
# Do the finally clause
if {$hasFinally} {
helper $finally "finally clause" a b c d
if {$c} {
set ei $a
set ec $b
set code $c
set msg $d
}
}
# Now we can return. Phew!
return -code $code -errorinfo $ei -errorcode $ec $msg
}
}
namespace import ::try::try
## EXAMPLE ##
# try {
# set f [open /non/existant/file]
# } catch {POSIX ENOENT *} {
# puts "That file doesn't exist!"
# } catch {POSIX EACCES *} {
# puts "You may not open that file!"
# } finally {
# puts "Wibble..."
# }
'Tcl & Tk > 팁 (Tip)' 카테고리의 다른 글
popen 구현 하기 (0) | 2025.03.26 |
---|---|
C로 만드는 base64 디코드 커맨드 (0) | 2025.03.26 |
특정 주기로 실행하는 every 커맨드 (0) | 2025.03.26 |
Windows의 트레이 영역에 Notification 팝업 띄우기 (0) | 2025.03.26 |
Round Frame (0) | 2025.03.26 |