MSH: Script Blocks as Data

A feature from Lisp that I really like is the ability to pass code around as data.  One of the very cool aspects of Monad is that you can now easily do this.  That is, code can be placed in storage and then later executed.  To place in storage just assign it to a variable (or function parameter or hashtable entry) e.g.:

MSH > $code = { Get-Process }
MSH > $code

Then you can later execute the code in storage with the "&" a.k.a. invoke operator as shown below: 

MSH> &$code

Handles  NPM(K)    PM(K)      WS(K) VS(M)   CPU(s)     Id ProcessName
——-  ——    —–      —– —–   ——     — ———–
     88       5     1300       6236    43     0.71    308 albd_server
    103       5     1088       3340    32     0.08   3368 alg

This came in very handy when I was writing a script to import SoftbenchCM versioned files into Microsoft Team Foundation Version Control.  I needed a way to check legacy EXE error codes in a consistent fashion but I also needed a way to run some code before exiting if the EXE returned a failure code.  Here’s the MSH function I wrote:

function CheckExitCode {
    param ([string]$failureMessage, [int[]]$successCodes = @(0), $script=$null)
    $res = $successCodes -contains $LastExitCode
    if ($res.Length -eq 0) {
        write-error "ERROR CODE ${LastExitCode}: $failureMessage"
        if ($script) {
            "Executing cleanup script: $script"
        exit 1

Having to check the length on $res is a temporary situation.  In later drops of Monad the -contains operator returns a boolean.  The second parameter lets you specify which exit codes indicate success for your context.  It defaults to just 0 but you can specify multiple success codes.  The final parameter is code that will execute in the event of an error.  You use this function like so:

$tfci = tf checkin $destFilename /noprompt /comment:"$comment" 2>&1
CheckExitCode "tf checkin of $destFilename – $tfci" @(0) {tf undo $destFilename /noprompt}

If you need to specify multiple success codes you can do this:

$tfdir = tf dir $destItem
CheckExitCode "tf dir of $destItem – $tfdir" @(0,1)

This entry was posted in Monad. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s