Ruby as Cross Platform Monad
Ted Neward and Glenn Vanderburg are having lines-of-code measuring contest between Ruby and Monad (MSH). They've taken Lee Holmes' clever Encarta Answers script and Glenn's written it in Ruby.
Ted says:
"...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."
Using Ted's own words against him, Glenn says:
[when considering lines of code/syntactic tokens]...Ruby is clearly the winner.
Ruby: 17 lines, 76 tokens
Monad: 37 lines, 217 tokens
Personally, I'm Switzerland in this argument. Learn them both, you'll be a better person. I know .NET better so the Monad version makes more sense to me.
One thing I would suggest that Glenn do, if he really wants to get into some fun, is take a good hard look at John Lam's RubyCLR. Sure, there've been some cursory attempts at bridging the CLR and Ruby before as well as current work to get Ruby code compiling to IL. However, for the Windows world at least, Ruby's success on our platform will be (I predict) measured by two things:
- Watir - A Ruby Interop layer on top of IE (and now Firefox with FireWatir)
- John's RubyCLR - I'm convinced that John is doing the whole world a service with this bridge.
RubyCLR is elegant in that it doesn't attempt something so lofty (or perhaps ultimately tilting at windmills) as compiling Ruby to IL. Instead it does what Watir did - it opens another whole world to the already great Ruby interpreter. Will there be a Ruby/Mono bridge? There should be, and then Glenn would have something to smack Ted over the head with as then the IRB (Ruby Interactive Shell) starts looking like cross-platform Monad.
Me? I don't care, I'll just run them both in a Tabbed Console like the Console Project at SF.NET.
(Note the screen shot above, it's the Console Demo 15 drop. Support this project!)
UPDATE: Lee Holmes has retorted brilliantly with a rewrite of the original get-answer script. Here's his rewrite along with the ruby version.
param([string] $question = $(throw "Please ask a question."))
[void] [Reflection.Assembly]::LoadWithPartialName("System.Web")
$webClient = new-object System.Net.WebClient
$text = $webClient.DownloadString("http://search.msn.com/encarta/results.aspx
q=$([Web.HttpUtility]::UrlEncode($question))")
if($text -match "<div id=`"results`">(.+?)</div></div><h2>Results</h2>")
{
$partialText = $matches[1]
$partialText = $partialText -replace "<\s*a.*?>.+?</a>", ""
$partialText = $partialText -replace "</(div|span)>", "`n"
$partialText = $partialText -replace "<[^>]*>", ""
$partialText = ($partialText -replace "`n`n","`n").TrimEnd()
$partialText
}
else
{
"No answer found."
}
And the Ruby version...
#!/usr/bin/env ruby
require 'open-uri'
require 'cgi'
fail "Please ask a question." unless ARGV.size > 0
question = ARGV.join(" ")
query = "http://search.msn.com/encarta/results.aspx
?q=#{CGI::escape(question)}"
page = URI(query).read or fail "Couldn't get response."
puts
if page =~ %r{<div id="results">(.+?)</div></div><h2>Results</h2>}
response = $1
response.gsub! %r{<\s*a.*?>.+?</a>}, "" # remove links
response.gsub! %r{</(div|span)>}, "\n" # insert newlines
response.gsub! %r{<.*?>}, "" # remove tags
puts response.squeeze("\n").rstrip # collapse adjacent newlines and trim whitespace
else
puts "No answer found."
end
Clearly Lines of Code is a ridiculous metric to measure just about anything, and this is more proof that both Ruby and Monad kick the llama's ass.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
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();
Thx.
The CLR exposes a vast array of functions from a wide range of sources in a way that allows ANY language to leverage. A good chuck of Microsoft's $7 billion yearly R&D spending is going into functions exposed via the CLR not to mention the huge investment made by the rest of the industry. All CLR languages are able to take advantage of this huge investment stream with little to no effort.
We believe that Monad provides a unique value proposition being a great production-quality interactive shell as well as a great scripting/programming environment. We think it is going to have lots of support and be used by lots of people. I encourage you to kick the tires and use it if it meets your needs (and complain to me if it doesn't). If you prefer to use Ruby over CLR - that is great as well - its a big tent. Ditto for any other language on the CLR Python, C#, VB, etc. If you want to invent a new language on the CLR - go for it, you'll find that with a little work on your part, your users can get access to all the CLR libraries as well.
The CLR is a rising tide that lifts all language boats.
Jeffrey P. Snover
Monad Architect
Comments are closed.