Version 16 of main script

Updated 2014-06-06 05:10:47 by pooryorick

The main script is the primary script that is executed by the interpreter, e.g. tclsh or wish.

Description

One common technique is to have a script run a self test if it detects that it is the main script. Naive approaches only compare info script with $argv0. A somewhat more robust approach that usually works with pkg_mkIndex looks only at the file tail of those two values. The most robust approach fully normalizes those two values, including the last component, which a simple file normalize does not resolve.

The most complete approach:

if {[info exists argv0] && [
    file dirname [file normalize [info script]/...]] eq [
    file dirname [file normalize $argv0/...]]} {

    #do stuff
}

AMG: I'm not sure I fully understand the purpose of the /... in this code. From the above description, I'm assuming it's a dummy component so that [file normalize] resolves all components of the true path.

A common and fairly robust approach:

if {[info exists argv0] && [file tail [info script]] eq [file tail $argv0]} {
    #do stuff
}

The negative approach, also quite common:

if {![info exists argv0] || [file tail [info script]] ne [file tail $argv0]} {
    return
}

# test/standalone code follows

The more simple and naive approach to detection method directly compares info script with $argv0:

if {[info exists argv0] && $argv0 eq [info script]} {
    #do stuff
}

or, as formulated in Methods for Justifying text output in TCL , DKF, comp.lang.tcl, 2001-06-15:

if {[string equal $::argv0 [info script]] || [array exists ::embed_args]} {
    main
} 

AMG: Which posting would that be? What is ::embed_args? It must be something specific to the script DKF was describing.

PYK: I migrated this example and the verbiage from another page (can't remember which one now), and unfortunately it was just as unclear on that other page as well. I just searched comp.lang.tcl though, found the conversation, and included it above.

AMG: Here's a new way to do it, comparing device and inode numbers:

proc mainScript {} {
    global argv0
    if {[info exists argv0]
     && [file exists [info script]] && [file exists $argv0]} {
        file stat $argv0        argv0Info
        file stat [info script] scriptInfo
        expr {$argv0Info(dev) == $scriptInfo(dev)
           && $argv0Info(ino) == $scriptInfo(ino)}
    } else {
        return 0
    }
}

And by request from PYK, here's how to make the above callable as [info main]:

namespace ensemble configure info -map [dict replace\
    [namespace ensemble configure info -map] main mainScript]

PYK: Actually, I was suggesting that since only tclsh itself really knows what is the main script, e.g. wouldn't get confused by source info script, that it should provide info main as an alternative to all the scripts on this page.

authors

dkf
CJL
AMG: I'm not sure who this is... is a full name available? According to [L1 ], it's not Cameron Laird whose middle initial is not J.
PYK
RS