Powershell on Rails -- MonadRail!

Okay -- i've been going on about powershell a lot lately. And you want to hear about other things. I can accept that. Even the people on the bus seem to pull faces when i start spontaneously talking about powershell.

(An old lady on the bus this morning, for example, just didn't get it. --A universal parser! I said, but did she even smile? Not a smirk.)

Well, the reason for the powershell obsession is that I'm currently reading "Powershell in Action" by Bruce Payette which is a cracker! It goes deep into the language, as deep as can be.

And I've been thinking about using Powershell for writing websites. Rails-style, no less.

Conveniently, one of the examples Bruce provides is a webserver implemented using powershell (download source code from the Manning website and see 'Invoke-Webserver.ps1' from chapter 11)(or for a similar example, see Vivek Sharma or this very dangerous example from soapy frog )

What got me thinking about a rail-style powershell server were Two things. One: in response to the hanselminutes on monoRail, and two because Mike Schinkel mentioned the concept of a powershell web programming in his hunt for a new language.

Mike S:

"[Jeffrey Snover said] that PowerShell can do web, and will be able to do it more easily in the future. [Mike feels that] webified PowerShell should be a url-based object-selector-and-invoker like Django or Rudy on Rails."

Which is a nice idea. Seemingly, the major limitation with using Powershell as a webserver, at the moment, is our old friend threading. A powershell webserver is just a polling loop that handles all requests synchronously. Hence, every client has to wait in line to have their request processed. Not good. Ideally it would instead receive request-events and handle each of them on new threads. This (multi-threading) is promised as a future feature.

Anyway -- looking at Bruce's example of a webserver -- it would be pretty easy to see how it could be given rails-like behaviour.

Note that I do *NOT* have the time to be thinking about this... so i just wanted to sketch the basic idea here and see if anyone is interested in taking over.

Basically Bruce's script waits for get requests and then looks for simple mathematical expressions, such a "2+2" -- which is evaluates and sends back to the browser. This is the relevant bit of code:

        $received = @($received -match "GET")[0]
        if ($received)  
            $expression = $received -replace "GET */" -replace
                'HTTP.*$' -replace '%20',' '
            if ($expression -match '[0-9.]+ *[-+*/%] *[0-9.]+') 

Well, instead of expecting a mathematical expression like that, we could look for a path that has:

Zero or more 'areas', followed by exactly one 'controller name', followed by exacly one 'action', optionally followed by one or more 'parameters'.

In honour of John Backus (r.i.p.), i'd love to express this in EBNF... but alas, the brain forgets.

Anyway, i'll just write it in DWIM: {/area{/area}}/controller/action{?paramname{=value}{+paramname{=value}}}

So once we've tokenized the path into areas, controller, action, params...

...we check that the relevant 'controller' exists in the specified 'area'.

Where a 'controller' is just a cmdLet or maybe a script, with specific parameters (action, params).

And an 'area' is just a sub-folder. Nothing more, nothing less.

We pass the action and the params to the relevant controller, and then.... either the controller takes over from there, or maybe it just returns some html for us to return to the client.

Go for it. You have one hour.

Oh, and the name I've got for this one is 'MonadRail' as a play on 'monorail' and 'monad' (the original code name for Powershell)


I'm currently writing a book about how to build your first product. If you want to build your first product, please sign up to be notified when the book is available.

(By the way, I read every comment and often respond.)

Your comment, please?

Your Name
Your Url (optional)
Note: I may edit, reuse or delete your comment. Don't be mean.