JOB REFERRALS
    ON THIS PAGE
    ARCHIVES
    CATEGORIES
    BLOGROLL
    LINKS
    SEARCH
    MY BOOKS
    DISCLAIMER
 
 Friday, March 31, 2006
Need Ruby? Nah--get Monad instead

I happened across this blog entry while doing some research on Monad, Microsoft's new command shell (meaning, think "bash" or "csh", not "Explorer"), and found it so similar in many ways to what guys in the Ruby space have been hyping for a year or two now, that I just had to pass it on. Reproducing directly from the site:

One of the scripts I like the most in my toolbox is the one that gives me answers to questions from the command line.

For the past 2 years or so, Encarta has offered an extremely useful Instant Answers feature. Its since been integrated into MSN Search, as well as a wildly popular Chat Bot. MoW showed how to use that feature through a Monad IM interface (via the Conversagent bot,) but we can do a great job with good ol screen scraping.

[C:\temp]
MSH:70 > get-answer "What is the population of China?"

Answer: China: Population, total: 1,313,973,700
2006 estimate
United States Census International Programs Center


Answer: China : Population:
More than 20 percent of the worldâ?Ts population lives in China. Of the co
untryâ?Ts inhabitants, 92 percent are ethnic Han Chinese. The Han are desc
endants...

[C:\temp]
MSH:71 > get-answer "5^(e^(x^2))=50"

Answer: 5^(e ^( x^2))=50 = x=0.942428  x=-0.942428

[C:\temp]
MSH:72 > get-answer "define: canadian bacon"

Definition: Canadian bacon lean bacon

[C:\temp]
MSH:73 > get-answer "How many calories in an Apple?"

Answer: Apples: calories:
1.0 cup, quartered or chopped has 65 calories 1.0 NLEA serving has 80 calo
ries 1.0 small (2-1/2" dia) (approx 4 per lb) has 55 calories 1.0 medium (
2-3/4" dia) (approx 3 per lb) has 72 calories 1.0 large (3-1/4" dia) (appr
ox 2 per lb) has 110 calories 1.0 cup slices has 57 calories
USDA

[C:\temp]
MSH:74 > get-answer "How many inches in a light year?"

Answer: 1 lightyear = 372,461,748,226,857,000 inches
Here is the script, should you require your own command-line oracle:
## Get-Answer.msh 
## Use Encarta's Instant Answers to answer your question. 

param([string] $question = $(throw "Please ask a question.")) 

function Main 
{ 
   # Load the System.Web.HttpUtility DLL, to let us URLEncode 
   [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Web") 

   ## Get the web page into a single string 
   $encoded = [System.Web.HttpUtility]::UrlEncode($question) 
   $text = get-webpage "http://search.msn.com/encarta/results.aspx?q=$encoded" 

   ## Get the answer with annotations 
   $startIndex = $text.IndexOf('<div id="results">') 
   $endIndex = $text.IndexOf('</div></div><h2>Results</h2>') 

   ## If we found a result, then filter the result 
   if(($startIndex -ge 0) -and ($endIndex -ge 0)) 
   { 
      $partialText = $text.Substring($startIndex, $endIndex - $startIndex) 
    
      ## Very fragile, voodoo screen scraping here 
      $regex = "<\s*a\s*[^>]*?href\s*=\s*[`"']*[^`"'>]+[^>]*>.*?</a>" 
      $partialText = [Regex]::Replace("$partialText", $regex, "") 
      $partialText = $partialText -replace "</div>", "`n" 
      $partialText = $partialText -replace "</span>", "`n" 
      $partialText = clean-html $partialText 
      $partialText = $partialText -replace "`n`n", "`n" 
     
      "" 
      $partialText.TrimEnd() 
   } 
   else 
   { 
      "" 
      "No answer found." 
   } 
} 

## Get a web page
function Get-WebPage ($url=$(throw "need to specify the URL to fetch")) 
{ 
    # canonicalize the url 
    if ($url -notmatch "^[a-z]+://") { $url = "http://$url" } 
     
    $wc = new-object System.Net.WebClient  
    $wc.Headers.Add("user-agent", $userAgent) 
    $wc.DownloadString($url) 
} 

## Clean HTML from a text chunk 
function Clean-Html ($htmlInput) 
{ 
    [Regex]::Replace($htmlInput, "<[^>]*>", "") 
} 

. Main
That's nifty stuff, if you ask me. And, what's best, this is a loosely-typed, dynamic language every bit as interesting and powerful as Ruby, though admittedly without some of the metaprogramming capabilities that Ruby has. But notice how we're making use of the vast power underneath the .NET framework to lay out a pretty straightforward use of the code, in a way that's entirely dynamic and loosely-typed, including the assumed return value from the if/else block, and so on. It's going to be a whole new world for automating projects (among other things) once Monad ships, and the saavy .NET developer (and even the saavy Java developer who builds on Windows) will already be looking at Monad for ways to streamline the things they need to do on Windows.

Added to my list of developer interview questions: "What is Monad, and why do I care?"


Saturday, April 01, 2006 10:06:12 AM (Pacific Daylight Time, UTC-07:00)
Monad is great, but will someone please develop a tabbed shell for windows? Anyone know of one?
Monday, April 03, 2006 7:39:26 AM (Pacific Daylight Time, UTC-07:00)
Heh heh, good one! But one day early.
Wednesday, April 05, 2006 2:30:45 PM (Pacific Daylight Time, UTC-07:00)
There's a lovely tabbed shell on SF.NET called "Console" that does MSH or CMD.
Scott Hanselman
Thursday, April 06, 2006 5:22:18 AM (Pacific Daylight Time, UTC-07:00)
Or you could just use native OS scripting capabilities :-)

Save the following as GetAnswer.js, then from command prompt type

cscript GetAnswer.js "What is the populations of China?"

var ie = new ActiveXObject("InternetExplorer.Application");
ie.Navigate2("http://search.msn.com/encarta/results.aspx?q="+encodeURI(WScript.Arguments(0)));
while(ie.ReadyState !=4)
{
WScript.Sleep(1000);
}
if(ie.Document.getElementById("bubble_header"))
WScript.StdOut.Write(ie.Document.getElementById("bubble_header").innerText);
else
WScript.StdOut.Write("No Answer Found for: [" +WScript.Arguments(0) +"]");
ie.Quit();
Friday, April 07, 2006 6:48:46 AM (Pacific Daylight Time, UTC-07:00)
You'be better check out Ruby CLR bridge, which allows you to take advantage of .Net library with a much beautiful language.
piggy
Monday, April 10, 2006 6:02:03 PM (Pacific Daylight Time, UTC-07:00)
Why /bin/bash ruby?
See the response to this on Glenn Vanderburg's blog:
http://www.vanderburg.org/Blog/Software/Languages/whelmed_by_monad.blog

Monad is certainly a big improvement over the past commandline tools that were bundled with Windows (basically, nothing) so it's good to see the Microsoft is finally starting to understand the power of the commandline (I recall being part of a panel at a technical conference in 1999 and when the Microsoft member of the panel said "The need for scripting is a failing of Unix" the audience boo'ed and hissed). However, one wonders why Microsoft bothered to invent a new language when Ruby (with some easily-added DSL goodness) could have sufficed quite nicely in addition to the advantage of scripts working cross-platform (though, I suspect that cross-platform interoperability is not high on Microsoft's list of priorities ;-)

As Glenn points out in his post, Apple does not share Microsoft's NIH attitude: Ruby, Python and Perl are all bundled with OS X (as well as bash) in addition to Apple's homegrown AppleScript.
Phil
Monday, April 10, 2006 11:34:23 PM (Pacific Daylight Time, UTC-07:00)
Certainly better than batch files or WSH.

However, it looks like a weird combination of Visual Basic and Bourne shell script. And since it's Microsoft, it will almost certainly only run on Windows.

I still think Python and Ruby are better bets.

Why is it called Monad? Does it borrow the concept of monads from Haskell?
Comments are closed.