Showing posts with label tech. Show all posts
Showing posts with label tech. Show all posts

11 March, 2018

... thinking in circles

programrun as it flows through the data executing commands based on
decisionpoints mandated in its execution logic. many loops are terminated
based on a length and they pick through data until some known point, maybe the
length of the data.

in the begininning of my programming days, i was only able to envision fixed
ends. loop `for` and only `for` this long, but that could be inefficient as there
may be a reson to terminate before the end, so `breaks` were used but the syntax
was ugly because the intent of the `for` appears as if it is to run all the way
through. yet, `while` hidden in its logic is a `break` whose condition needs a code
__comment__.

all the `while` a cleaner loop existed with its intent clearly
expressed and the code became more readable with less reliance on
soon-to-be-stale comments. constructs such as `each` took the `for`'s place,
spelling that actions were to happen all along the length of this line of
data.

the loops were all spelled out.

then, came the method that called itself. it didn't look anything like a loop,
just passing along what's left of the data to be handled by the next time this
method was to be called, which was right now because i'm that method and i'm
calling it, which is to say me and... was it to be an endless loop that couldn't
be because of finite resources like a python swallowing its tail?

relax...

although it may not work for everything, the terse--yet powerful--form of
recursion is somewhat poetic. the sleek and postmodern feel to code in which a
method keeps calling itself until some point at which it exits, the depth to
which is not known to the developer. instead, if the data given are still
open to processing, then we let the

(originally a guest post circa 2014 on the now-dark opinionateddeveloper.com)

14 March, 2017

The People

I spent my day doing the human thing. No, not humane... human. I work in tech. People tend to think tech is keyboards, screens, and code.

However, today, I talked some, and I listened a lot. I work in a satellite office, but I'm on a visit to HQ. There has been a lot of turnover in leadership through the last year, and I spent time with Directors, VPs, a C-level person, and others. All but one of these people were new since my last visit.

I'm not really a press-the-flesh kind of person. I feel like I can connect, remotely, via technology, but you have to be very deliberate. After today, I realized that being here, in their office, with a limited amount of time, was a different way of being deliberate. Being present, makes you a person, not an appointment. It's easy to skip an appointment.

If I had to come out here to be a human, so be it. I need to accept that certain people need that. Meeting people on their terms, especially for the first time, just reduces friction.

03 December, 2014

Do you currently work in the Dev Ops environment?

I was recently asked:

"Do you currently work in the Dev Ops environment?"

Here's my answer:

No, the devops is not really a thing. The devops is the intersection of development and operations skills. In reality a devops culture is still built around product. A dev team takes control over its ops concerns to ensure they deliver the best product the can. When someone "specializes" in the devops, they are no longer focused on product and are no longer dev, they are ops. They may be ops for developers--helping build their development environments and playing an extremely important role--but they are no longer devs (for the product team).

Now... ops people who approach things from a software engineering perspective (automate all the things!) are extremely valuable. They probably are the best fit for your search for people to fill the devops role.

30 November, 2014

Empathy and the Product Era

Just tried out Medium as a social posting platform with the topic Empathy and the Product Era. Check it out: https://medium.com/@bikeonastick/empathy-and-the-product-era-ff1304af82e

24 May, 2013

tmux clear backscroll...

I've recently started using tmux on my OSX work box. I had avoided it because I've developed a strong attachment to clearing my screen before running commands that are going to kick out a lot of output, which in a regular terminal or iterm2 on a mac is Command+k. Well, if you do that during a tmux session, it clears the tmux screen elements and things are really fubar-ed until you resize the screen. Anyway... I added the following to my .tmux.conf

# clear scrollback
bind-key C-k send-keys -R \; clear-history \; send-keys "Enter"


Which is nice, so I perform a control+b control+k and it clears the screen. However... there's a really nice side effect that I stumbled on completely by accident. If I already have a command queued up and ready to go when I use that keystroke combination, the send-keys "Enter" causes the command to execute.

That way, I get the command to execute and the only output I'll ever be able to scroll to is the entire output of the command! I had added the send-keys "Enter" to this because the rest of the command was leaving me with a blank screen and I had to hit enter to get my prompt back. Now... I have a new workflow I like.

23 February, 2013

tdd-bdd goodness

wow, ok, so here's another huge plus for TDD and BDD. it gives you the confidence to not immediately blame your own code when something goes wrong when you deploy and take part in a large SOA project. when you know that, given the right inputs, you'll produce the right results (because you built the system using TDD based on the other system's messages), you know to look to things outside your system when it's going pear shaped.

turns out, this was a human error thing that was the result of some less-than-stellar design on my part. also, the QA test plan was not using our intended behavior for the software, so... suffice it to say, there were a lot of cognitive leaps to be made to get this validated. buuuuuut... the greatest thing i got out of it was i was an effective troubleshooter because i didn't waste time (or stress) digging in my code for answers.

it turned out to be an education thing. once the dust settled, code was verified.

01 January, 2013

vim commands/functions to run cukes within vim

OK, I'm doing more rails work in vim, these days, so I'll be tossing more stupid vim tricks up here as I run into them.

The other day, I was moaning about cucumber and locations of step files, as it encourages (but doesn't depend upon) a file-naming convention. As such, step files can be hard to find. Anyway, as I'm kicking through a way to script a solution to that problem, I decided I wanted a way to run cukes from within vim.

I came up with two solutions:

  1. one to run the whole file that's in the currently open buffer
  2. one to run the scenario that starts on the line the cursor is on
To implement these, I'm using the very cool RunShellCommand function found here, which opens the results of the command in a scratch buffer in a new window.

I just added the following command definitions to my .vimrc:

command! Cuke call s:RunShellCommand('bundle exec cucumber ' .expand('%:p'))

command! CukeL call s:RunShellCommand('bundle exec cucumber ' .expand('%:p').':'.winline())  


I haven't mapped short commands with my <leader> yet as I'm not sure if I'll use this regularly, but it seemed helpful, so I thought I'd share. The drawback is that the execution time of cucumber is long, especially if it's a UI test, so it can take over your UI for a while, which is why I added CukeL, so I cold run just the current line. The cucumber overhead is still pretty high, so I may look into creating a modified RunShellCommand that forks the process, so you can continue working while you fire off the command.

31 December, 2012

cucumber disambiguation, or... survival tip for a noob in an existing rails project

I've just jumped into an existing rails project at work. The existing team is using the hell out of BDD/TDD. While I'm super excited to get there with them, I struggled HUGE with the fact that their features and steps have been heavily optimized and DRYed out. To grok the project and the methodology, I was trying to jump from feature to step and because they've been working with this for a while, they have organized source around DRY, not around readability and discoverability. As such, I was stumbling around trying to figure out where the hell each of the step definitions were for the features I was reading.

I finally stumbled upon the right incantation of cucumber options to get what i needed:


bundle exec cucumber -o cuke.out --format stepdefs features 


If you want to do all features. However, if you just want to discover the feature-step relationships for a specific feature:


bundle exec cucumber -o cuke.out --format stepdefs features/specific_feature_file.feature


Will produce output like this:

5.1738260 /^I am logged in as a valid user$/
   # features/step_definitions/authentication_steps.rb:100
2.6341953 /^(?:|I )go to (.+)$/
   # features/step_definitions/web_steps.rb:48
2.1448050 /^I should be able to visit the admin area$/
   # features/step_definitions/admin/admin_steps.rb:5
1.2116820 /^I am logged in as an admin$/
   # features/step_definitions/authentication_steps.rb:106
0.7382180 /^I am logged in as an uber admin$/
   # features/step_definitions/authentication_steps.rb:118
0.1408770 /^I should see the Contacts\/New Contacts page$/
   # features/step_definitions/marketing/contact_list_steps.rb:1
0.0094120 /^(?:|I )should not see "([^"]*)"$/
   # features/step_definitions/web_steps.rb:123
0.0092010 /^(?:|I )should see "([^"]*)"$/
   # features/step_definitions/web_steps.rb:105


Now, you can tell where the f-uh-uh-uh-uke, fuke... er... cuke the implementation is. Odds are, a team who's been doing this for a while have shut off step output because they know the project like the back of their hand, but something like this will help a noob like you get up to speed in an existing project. Well, it helped me and it took a while to find the right search terms to give me what I needed. Oh, also, the output file was a huge help because the number of NOT MATCHED BY ANY STEPS lines in the project blew the useful stuff right out of my iTerm's scroll history.

Good luck...

Now, I'm thinking of writing a vim plugin that will use this output to create a ctags like file that will allow you to jump around from feature to step regardless of what your file naming conventions are. 



03 November, 2012

agile practitioners, are we waiters or doctors?

In the opening session at yesterday's Agile Day Twin Cities (url or #adtc2012 tweets), David Hussman and Jeff Patton introduced a metaphor for the sake of conversation. The metaphor was to give agile practitioners a way to describe their own role in the software development processes they use. The question was: are you more like a waiter or a doctor in your agile process? This, of course assumes that waiters take orders (specifications) and deliver food (features) while doctors participate in a discovery process to solve problems. The thing with metaphors is you can torture the heck out of them and render them meaningless, but I feel there's something to this and I want to hash it out a little, here.

I am now in my 8th month at a company who is committed to using Scrum for their development process. I was a certified scrummaster a couple of years back, but my employer at the time didn't practice, so I let certification lapse. Between that employer and my current employer, I took a short stint at a software company that had some big quality issues which they'd asked me to come in and help solve. We didn't have the same view of what might solve the problems, so put a few things in place to help, but ultimately decided to let them get back to handling things without me. I have done a number of agile-flavored things in my career, but had yet to practice a formal agile method before this.

Now, I'm in my 8th month of practicing full-on scrum with a product team. There have been ups and downs, but they're neither as high nor as low as I've experienced at other places. It feels extremely sane, but I have been feeling, lately, like I just react to "priority." Admittedly, until yesterday, I hadn't been able to put a name to it, and, while I had a sense that something was off, I wasn't sure what.

I've wanted to work in an agile process for quite some time, why didn't it feel perfect? Things are working very well, we get our product work done, we meet our deadlines, so what could be wrong? When in an afternoon openspace session about the Doctor-Waiter metaphor, Hussman asks those of us sitting around, "So, are you a Doctor or a Waiter?" It hit me, "oh wow, I'm a waiter." That's what I've been missing.

Anyway, in that openspace session, we kicked the metaphors around and while people were in the process of torturing it, it occurred to me that there are good waiters too. In fact, I had a chance to eat at a great tapas place a few weeks ago in which a waiter guided us through the experience. Could waiter and doctor not be two discrete things, could they, instead exist on a continuum of maturity from waiter to doctor? So, my contribution to the metaphor torture was, "Considering there's a continuum from waiter to doctor, are we working our way through med school by waiting tables?" It got a couple of snickers, but we didn't explore the thought.

Here's what I was trying to get at with the question, just because we're being waiters, doesn't invalidate what it is. It serves a purpose. I am gaining my experience with scrum as a participant, but now that I know there's a higher purpose, I'll be working toward doctor status. Admittedly, my mojo isn't being completely fed or this metaphor wouldn't have resonated so well with me. Some participants (including me for a few moments) in the open space session talked like they were victims of the process, which is why I wanted to kick the metaphor a little longer. Now that we know the names, now that we've identified the healthy state, let's work through it. It's kind of like the start of a 12 step program: admitting the problem.

Except, I won't go so far as saying it's a problem. It may work very well for organizations to feed bite sized chunks of product information through teams working in short iterations. This keeps teams from burning out and it does get things done (still way better than waterfall). What's missing, though, is a feeling of empowerment and engagement for the entire team.

Is being a scrum waiter an organizational thing or is it an individual choice? I will admit, that, as the new guy, I have sat back and observed. I'm working in a new language (yeah, only 8 months with grails too), the lead who hired me has left the company, and I'm experiencing a new development methodology. It didn't take me too long on Agile Day to come to the conclusion that I've chosen to be a waiter. It has served its purpose, giving me exposure to the process, time to absorb a new language and framework, and a breather to embrace the organizational change around me. I have to admit, I've probably even been a little purposefully dysfunctional about my waiter status by pushing all responsibility for prioritizing the backlog on my product manager. Rationalizing it with statements like, "he knows the business."

Now that I am cognizant of that sense of doubt--no... let's call it unease--about where I am in my maturity around scrum, I own the outcome. So, I'm going to start working my way through "med school." I'm not sure of the exact path, but I do know that I have more to contribute to the process than just writing the code. I'm starting to really internalize the product space, so I can begin to help dig into those areas, but I am, for sure, able to be more of an active participant in grooming the backlog and story planning to represent areas in which I do have significant knowledge and the ability to control, e.g., performance and architecture.

As I'm beginning to understand, a healthy scrum process probably expects me to be acting doctorly. So, choosing just to participate with a small pad of paper in my apron and a pencil behind my ear, I'll be the one breaking the rules, not the victim.

14 October, 2012

amping up the watij


I've been working on a grails webapp recently that I need to iterate on pretty quickly. Unfortunately the steps are getting more and more complex that have to be performed in each iteration. This weekend's project was an attempt to get a web-testing automation flow. No, not for deep QA or for extensive regression testing, I just want to be able to fire off some tests so I can iterate. In case you're wondering, this is on a mac.

I've looked around some and, to date, watij had the lowest bar to entry. So long as I had everything on the classpath that came with the watij webspec zip file, it seemed to work just fine. I wrote a shell script watij.sh to handle the dirty work:

export JAVA_OPTS=-d32
export CLASSPATH=$WATIJ_HOME/testlib/engine-gecko.jar:$WATIJ_HOME/

testlib/engine-ie.jar:$WATIJ_HOME/testlib/engine-webkit.jar:$WATIJ_HOME/
testlib/jniwrap-native.jar:$WATIJ_HOME/testlib/junit-4.8.2.jar:$WATIJ_HOME/
testlib/jxbrowser-2.5.jar:$WATIJ_HOME/testlib/log4j-1.2.15.jar:$WATIJ_HOME
/testlib/MozillaGlue.jar:$WATIJ_HOME/testlib/MozillaInterfaces.jar:
$WATIJ_HOME/testlib/mshtml.jar:$WATIJ_HOME/testlib/runtime.jar:
$WATIJ_HOME/testlib/slf4j-api-1.5.8.jar:$WATIJ_HOME/testlib/
slf4j-log4j12-1.5.8.jar:$WATIJ_HOME/testlib/tuxpack-0.2.jar:$WATIJ_HOME/
testlib/watij.jar:$WATIJ_HOME/testlib/webspec.jar:$WATIJ_HOME/testlib/
winpack-3.8.jar:$WATIJ_HOME/testlib/xulrunner-linux.jar:$WATIJ_HOME/
testlib/xulrunner-linux64.jar:$WATIJ_HOME/testlib/xulrunner-mac.jar:$WATIJ_HOME/
testlib/xulrunner-windows.jar:.

USAGE='
usage: watij <watijscript>.groovy [scriptargs ...]

        sets watij libs on classpath (based on WATIJ_HOME) and
        runs groovy-based watij scripts. All scriptargs passed
    on to the groovy call.

'
while [ $# -gt 0 ]
do
    case $1 in
        -h)
        echo >&2 "$USAGE"
        exit 1;;
        *)  break;;    # terminate while loop
    esac
    shift

done
if [[ $1 == *.groovy ]]
then
    groovy $@
else
    echo >&2 "$USAGE"
fi


Yes, that means you have to set an environment variable, WATIJ_HOME. Then, I also wanted to be able to write and execute my scripts from within vim as that is my primary development tool, so I added the following to my .vimrc:

command! -complete=shellcmd -nargs=* Watij call s:RunShellCommand('watij ' . expand('%:p'). ' ' . <q-args>)

function! s:RunShellCommand(cmdline)
  echo a:cmdline
  let expanded_cmdline = a:cmdline
  for part in split(a:cmdline, ' ')
     if part[0] =~ '\v[%#<]'
        let expanded_part = fnameescape(expand(part))
        let expanded_cmdline = substitute(expanded_cmdline, part, expanded_part, '')
     endif
  endfor
  botright new
  setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
  call setline(1, 'You entered:    ' . a:cmdline)
  call setline(2, 'Expanded Form:  ' .expanded_cmdline)
  call setline(3,substitute(getline(2),'.','=','g'))
  execute '$read !'. expanded_cmdline
  setlocal nomodifiable
  1
endfunction

The RunShellCommand function was straight out of the vim tips wiki. It makes it so the output of a command is displayed in an extra window. The Watij command! statement makes it so I can execute watij against the script in the currently active editor window:


Just type :Watij <followed by args>
In this case, my script will launch bing because I added that as an argument
Now... after closing the groovy window with command-q, I see any printed output from the script in the scratch window in vim:
Now, just close the scratch window with :q

In a perfect world, I would like to create a homebrew formula for installing/configuring this and configuring the .vimrc. But... I need to get back to doing some work, so I just decided to blog about it for now.


21 July, 2012

i've been using macvim as my development environment for groovy/grails at work and i'm slowly building up my toolbox of functionality. Here's one I put together based on based on a RunShellCommand method

function! s:RunShellCommand(cmdline)
  echo a:cmdline
  let expanded_cmdline = a:cmdline
  for part in split(a:cmdline, ' ')
     if part[0] =~ '\v[%#&lt;]'
        let expanded_part = fnameescape(expand(part))
        let expanded_cmdline = substitute(expanded_cmdline, part, expanded_part, '')
     endif
  endfor
  botright new
  setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
  call setline(1, 'You entered:    ' . a:cmdline)
  call setline(2, 'Expanded Form:  ' .expanded_cmdline)
  call setline(3,substitute(getline(2),'.','=','g'))
  execute '$read !'. expanded_cmdline
  setlocal nomodifiable
  1
endfunction

i found out about this here: http://vim.wikia.com/wiki/Display_output_of_shell_commands_in_new_window


then, i added some commands to my vimrc:


this one searches all my groovy files for the word under the cursor (the thing is the under-the-cursor magic):

command! Srchwg call s:RunShellCommand(
'find . -name \*.groovy -exec grep -H --regexp="' .expand("<cword>").'" {} \;')

this one, takes an argument for a filename extension and will search all files of that type for the word under the cursor:

command! -nargs=+ Srchw call s:RunShellCommand(
'find . -name \*.'' -exec grep -H --regexp="' .expand("<cword>").'" {} \;')

now, i can have my cursor on a line and type :Srchwg which will open a window with a list of files that contain the word. or, if i type :Srchw js, i'll search all js files in my project for the word under the cursor. nice.

i was thinking of writing a function to, then, open files based on the buffer opened by the RunShellCommand method, but i found that vim already has functionality to do that. all i needed to use was the handy-dandy gf functionality!

anyway, one of these days, i'll package up all of my vim tricks into either a vimball or just a vimrc that you can source into your vimrc and open source it on github.

24 March, 2012

Carboy 0.1.2 is out in the wild

After learning a bunch about Homebrew for mac, I decided to do a talk at ruby.mn on the subject. As I was working up to sharing what I'd learned about writing Homebrew formulae, I decided, "hey, there's a pattern to this that I should just wrap up in code instead of just write about it..."

Thus, carboy was born. Homebrew is in reference to home brewing of beer and a carboy is an important part of any homebrewer's toolkit. Here's a library that, if included in your rakefile, gives you some valuable build functionality for creating installs for homebrew. I have released preliminary versions of it to github and rubygems.org

https://github.com/bikeonastick/carboy
https://rubygems.org/gems/carboy



For information on how to use it, read the simple steps 1-10 in the README for carboy on github. Step 0 is assumed, but if you need it, you need it. There's also an example included within carboy called my-tools. Look at that for more info.

I'll be speaking at ruby.mn about carboy on Monday 26 March 2012. Well... I was pretty vague when I signed up to speak, which was before I made the jump from telling folks what I learned about developing for homebrew to writing carboy. Oh well...

One last thing for those of you interested in writing your own Homebrew formulae. Here were some good resources:



21 January, 2012

macvim dev env update

ok, so i've mentioned that i'm revisiting vim as a dev tool and, quite frankly, i've been impressed with some of the plugins out there. i've been using NERDTree and the grails plugin. NERDTree has been very nice and the grails one is ok.

as i've been watching grails webcasts like bobby warner's jump into grails 2.0, i've been a little jealous of textmate's ability to "find files." so i started searching for a vim plugin to do the same and found command-t. it's pretty cool. as i've mentioned before, i've been doing a few things with keymappings to make macvim act the way my fingers need it to work. i had to add a little magic to my .gvimrc to make it work for me.

macmenu &File.New\ Tab key=<nop>
map <D-t> :CommandT<cr>

now, command + t enables the file finding feature of the command-t plugin.

26 December, 2011

running a simple rails app (like wagn) with ubuntu upstart






I had a hell of a time getting my upstart script to start. It kept launching, reporting that it started and even showing a pid, but it would die. This was a version of the same script I had written in a shell script and it would execute just fine. The addition of the export HOME, suddenly made things come together.

I'd been chasing the various values in the expect stanza, but nothing made sense. Once I had the HOME export in place, I was able to find the right setting for the expect stanza after a couple of tries.

Anyway, I wanted to run a very simple rails app, called wagn, as an internal tool on an internal server. In the event that our box goes down, I want wagn to restart. Furthermore, I don't have a bunch of time to muck about with all of those full-on production ways of deploying ruby, so I went looking for the best way to run this on the platform I had in front of me. I found out the new way of running services on ubuntu is through upstart.

After looking through a bunch of things on upstart:

I found a hint... well, something I hadn't tried yet. Anyway, upstart seems to need a HOME var set when you execute. So, if you've been searching, here's a good example to go on if you want to run a rails server with upstart. You can create something similar to the following in /etc/init/servicename.conf. If you are using it specifically for wagn, edit my path below to match your install location for wagn.

# example script offered with NO WARRANTY. 
# feel free to use it or just learn from it

# wagn-server - wagn-server job file
description "wagn server"
author "robert tomb"

# restart process if crashed try 10 times every 5
seconds
respawn
respawn limit 10 5
# let upstart know the process will detach
expect daemon

# When to start the service
start on runlevel [234]

# When to stop the service
stop on runlevel [016]

# don't know why but home=root is necessary
# found it here: http://kevin.vanzonneveld.net/techblog/article/run_nodejs_as_a_service_on_ubuntu_karmic/
script
   export HOME="/root"
   exec /usr/local/wiki/wagn-1.7.0/script/server -b 192.168.1.54 -e production -p 3000 -d > /var/log/wagn.log 2>&1
end script

14 December, 2011

Hate bat scripting? Me too...



Abstract
Hate BAT files? Yeah, so do I. Stuck on windows for reasons beyond your control but need to do some scripting? Sure, you can use perl, ruby, python or jruby, but all of those require the installation of an interpreter.

How do you survive if you have a bare-metal windows box and aren't allowed to dictate prerequisites? You could fall back on bat scripting and risk the integrity of your hairline or you could fall back on your JavaScripting skills and go against the WSH.

I'll show you a couple of minor examples in a JS coding idiom that makes sense to me and share as many of the references as I remember that helped me with my code. Lastly, I'll give a few suggestions as to where this can be used. Hopefully, this will be enough to spur your imagination to use JavaScript solve problems you have on the windows platform.

Windows Scripting Host
Here's your goto microsoft site for this http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx . This site is going to give you all of the conceptual stuff you need to know about this. I'll talk about some things I had to reconcile and give you a codesample walkthrough.

Executing your scripts


  1. just execute a js script from the cmd line
    jsmn_all.js
  2. execute it from the command line with cscript
    cscript /Nologo jsmn_all.js
  3. create a .wsf file to define and execute it with cscript
    cscript /Nologo jsmn.wsf
  4. or just execute your wsf file from the command line
    jsmn.wsf
wsf? WTF?
Go here for info on wsh files. Basically, they offer the ability to define a script and do imports, similar to what you do in an html file with

I'm not going to get too far ahead of my self decomposing this entire script. Suffice it to say that this allows you to connect to jsmn.js and use things in it, such as the ScriptHelper object. Objects that are part of the windws scripting host, e.g., the WScript object are going to be in your execution scope no matter what, so there's no need to root around for some WSH javascript file to "include."

You can have multiple script references, but I don't know the limitations. You can even have your script entry point in one of the referenced scripts. I can see where it might make better sense (and make your editor of choice happier) if you put all logic in a js file and only used hour WSH file like a project file.

What can you do with this here WSH thingy?
Good question. Well, I have a progressive "hello jsmn" demo for you that might help to enlighten. You'll really have to dig through the Microsoft pages to see all that you can do. You can even use this to wrap windows commandline commands.

I see it as a great way to drop a toolkit onto a bare metal windows box and make yourself productive. Seems like something that could be very powerful for sysadmins or testing engineers especially for windows VMs.

Oh yeah, the demo
  

Running just this with no Arguments yields a dialog box with:Needs two arguments: one to specifiy the subject and another for desired action. Here's the ScriptHelper class we instantiate and call methods from:

/*
 * Class for grouping functions that are important to this script.
 */
function ScriptHelper(word1,word2) {

    this.desktopiconfolder = "";
    this.envname = "jsmn";
    this.write_script;
    this.fullFileName = WScript.ScriptFullName;

    this.wshShell = WScript.CreateObject("WScript.Shell");
    this.objFSO = WScript.CreateObject("Scripting.FileSystemObject");

    this.wordOne = word1;
    this.wordTwo = word2;

    this.speak = function() {
        WScript.echo(this.wordOne + " " + this.wordTwo);
    }

}

That's all well and good but...
I'd like to do something slightly more sophisticated than just echo some crap out

So, let's write to a file. I'll add a speakToFile function to my ScriptHelper class


this.speakToFile = function(loc) {

        this.write_script = loc;

        var filelocation = loc;
        if ( this.objFSO.fileExists(filelocation) ) {
            this.objFSO.moveFile(filelocation,filelocation + ".bak");
        }
        var ForWriting = 2;
        propFile = this.objFSO.OpenTextFile(filelocation,ForWriting,true);
        propFile.WriteLine("WScript.echo('from file:" + this.wordOne + " " + this.wordTwo + "');");
        propFile.Close();
    }

 and tell my WSF file to call that instead of speak.
  
Now, when I run

jsmn.wsf hellooooo jsmn

it writes a file to disk called jsmn_write.js. This file contains one line of javascript and if I execute jsmn_write.js, I'll see

"hellooooo jsmn"

So, I can write a file, what else?
There's all sorts of windowsey stuff you can do like write shortcuts... So, I add a call to a createShortcuts() method

And, this takes a few more methods to support it, but I add the following methods to ScriptHelper

this.createShortcuts = function() {
        this.createShortcutFolder("Shortcuts for " + this.envname);
        this.createShortcut("TestShortcutFor-" +
                this.envname,this.getScriptDir()+"\\"+this.write_script,this.env
name);

    };

this.createShortcutFolder = function(name) {
        var desktop = this.wshShell.SpecialFolders("Desktop");
        this.desktopiconfolder = desktop + "\\" + name;
        this.objFSO.CreateFolder(this.desktopiconfolder);
    };

this.getScriptDir = function() {
        var forShortening = this.fullFileName;
        var lastSlash = forShortening.lastIndexOf("\\");
        var shortened = forShortening.substring(0,lastSlash);

        return shortened;
    };
    this.createShortcut = function(linkName,tgtPath,args) {
        var myShort = this.wshShell.CreateShortcut(this.desktopiconfolder +
                        "\\"+linkName+".lnk");
        myShort.WindowStyle = 1;
        myShort.TargetPath = tgtPath;
        myShort.Arguments = args;
        myShort.Save();
    };

Now when I run

jsmn.wsf hellooooo jsmn

I get a shortcut folder on my desktop with a shortcut in it that has a link to jsmn_write.js. That's it for my demo, I hope it was simple enough to follow but sophisticated enough to give you some ideas for new ways to use your javascripting skillz.


Debugging?
cscript has an option for a debugger, but I have not successfully used it.
//X         Execute script in debugger
NOTE: I will research this further and update or write a new entry on this

Soo... What else is possible?
Unit testing is pretty cool and if you're developing some sort of a toolkit with WSH scripts, you might want to be able to build them with TDD or just have some tests to prove that your code doesn't toally suck. I have not tried either of these, but they look very promising:


The next time someone tells you that JS is a toy language and you can't do anything with it, you can tell them to kiss your asterisk.

Acknowledgements
Also, this post uses the awesome syntax highlighter from alex gorbatchev it's some pretty cool javascripting in its own right.