You are here

try .. catch .. finally 커맨드

admin의 아바타

출처: http://people.man.ac.uk/~zzcgudf/tcl/try.tcl

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..."

# }

포럼: