Posted on September 30th, 2007

Last night Brian Harry announced the new version of the TFS power tools. One of the really cool thingsin this release is the TFS Best Practices Analyzer. It parses through your configuration to make sure everything is set up correctly. I got to work with the tool several months back and found it to be invaluable.

No Comments


Posted on September 28th, 2007

The IronRuby team has been making great progress, and the stuff they are doing is very cool. I thought it would be a neat exercise to dive into what happens behind the scenes to take a snippet of Ruby Code and execute it.

First, you’ll need the latest version of the source from RubyForge (above). Go ahead and compile it by running “rake compile” being sure you are running it from a Visual Studio Command Prompt and have installed the Ruby module pathname2 by running “gem install pathname2″.

With that out of the way, here’s the example we’ll work with which is similar to one on the wiki:

using System;
using Ruby.Hosting;

namespace CSIronRuby
{
  class Program
  {
    static void Main(string[] args)
    {
      RubyEngine re = RubyEngine.CurrentEngine;
      string script = “puts ‘Hello, World!’”
      re.ExecuteCommand(script);
      Console.ReadLine();
    }
  }
}

If we load this up, reference the Ruby and Microsoft.Scripting projects, and hit F5, we’ll see:

But what magic actually happened to cause that to print? Looking at our code, the first thing we had to do was get a RubyEngine instance. Looking at RubyEngine.CurrentEngine, we see that it calls Factory.GetInstance to find out from the current ScriptEnvironment what the correct engine is. And sure enough if we keep digging we see that it asks the CurrentManager of ScriptDomainManager to get a language provider type, which it then passes to a GetInstance method for setup.

The interesting thing is that our engine that is loaded isn’t just for Ruby. The engine is actually capable of passing calls for any of the 4 supported types in the DLR – IronRuby, IronPython, JScript and VBScript.

Once our engine is initialized, we actually load the LanguageProvider, which will be Ruby in this case. Up until now we could have been working with any DLR language – and in fact, it doesn’t look like there is anything necessarily stopping us from having multiple LanguageProviders loaded – appearing to let us mix and match Ruby and Python and other DLR languages. Which is cool stuff – you as an application developer can allow customization using any of the DLR languages pretty much just by including the right DLLs.

We then start getting into options specific to the RubyEngine. The current options look like:

One of the notes is that if ClrDebugging is enabled we have to demand a high trust. However, it looks to be off by default.

Along the way, I see the following snippet of code:

_dict = dictionary ?? new SymbolDictionary();

Which, according to the MSDN Docs returns the left-hand operator if not null, or else returns the right-hand operator. Similar to saying:

_dict = (dictionary != null) ? dictionary : new SymbolDictionary();

I learn something new every day. ;)

Finally we load up what looks to be the binding rules for the language (although there is a “//TODO: Remove” comment, so we’ll see what happens as we get further down) and we notify the host that the engine is loaded.

We’re now on to line 2. ;) We store the script into a string – pretty boring stuff. Then we get to this:

re.ExecuteCommand(script);

and now the fun begins. The first thing that happens is that it looks to see if the code needs to be compiled, or if we should just execute it. Here, we jump into ExecuteInteractiveCode. This in turn creates a snippet using our engine, the code, and marking it as interactive code. Our string of code actually gets wrapped by a SourceStringContentProvider. We then move on to getting the RubyCompilerOptions which is…an empty class (and a TODO asking if we actually need this class). We finally get to a CompileSourceCode method where we see the juicy ParseSourceCode method. Now the real magic begins.

In order to work effectively with the code, we need to turn it into an Abstract Syntax Tree. So we grab a Parser from the Ruby.Compiler namespace and get to work. During initialization we load up Parser.y – the Yacc spec for Ruby.

With the parser initialize, we actually call Parse. We then do the following:

  • Enter a lexical scope
  • Read and Parse the Source
  • Leave the lexical scope

Reading is easy – our source is stored in a sourceStringContentProvider from above, so our reader is just a normal TextReader. Next we load up a Tokenizer, and call Parse(). Now we’re looping over the tokens to evaluate the actual source. It’s fun stuff to look at – just know that RhsLenght is probably RhsLength. ;)

We do one pass to initialize some things before starting to pick through the code. I won’t step into everything that is going on, but to give you an idea, here’s a snippet of the Tokenizer:

Yep, they have cases for most every symbol or character you’d come across.

As I said above, now we’ve begun looping through the source code. We first pull out “puts” by looping over the source line until we hit a non indentchar. One thing that is interesting is that you have to take into account multi-byte characters even for source code. Fun stuff.

We’ve now pulled puts off the source, and although we know the next character isn’t an identchar, we have to make sure it isn’t a “!” or a “?”. The former is used in Ruby to signify that the method call should modify the existing object, for example this:

s = “Hello”
us = s.upcase
puts s
puts us

Would output “Hello” and “HELLO”, this:

s = “Hello”
s.upcase!
puts s

Would output “HELLO”. The latter is used to signify queries in Ruby. We have neither in our source code - so it keeps going. After making sure we aren’t trying to set a global ($) or local/class variable (@, or @@), we look to see if this is a constant (upper case first letter) or identifier. After specifying it is an identifier, we look to see if it is a reserved word. The reserved words for Ruby are in the Tokenizer.cs class, but “puts” isn’t in there. We then mark it as a command, add it to the stack, and keep processing.

We pull off the next token, “Hello, World” in a similar fashion. Well, that’s a bit of an understatement. We actually have a lot to pull off – “puts”, ” “, “‘”, “Hello”, “,”, “World”, “‘”, and “\0″ (for end of file). Each one of those has to be pulled off and then
put together to make sense.

Once that is finished, we check for any errors (incomplete token, invalid, etc), and return the syntax tree. We’ve got the tree, so let’s Transform it using an AstGenerator. We create a code block, and then see if we need to create any local variables. None here, so we move on. In the code block, we add methods for GetRfc and GetSelf. With that complete, we bind any Closures.

As I was watching it walk the statements to bind the closures, I found the dump variable had been filled with:

Dump = “#\n# AST \n#\r\n.return (\r\n .action InvokeMember puts(\r\n .bound (#self)\r\n .call RubyOps.CreateMutableString (\r\n .args (\r\n (string) \”Hello, World!\”\r\n )\r\n )\r\n )\r\n)\r\n”

Interesting what a simple statement can be turned into. It’s also interesting how far in we’ve gone – with the closures bound, it checks the flow of the variables, and then returns the compiled statement back up the chain to ExecuteInteractiveCode as an ICompiledCode object. We then call PrintInteractiveCodeResult passing in the result of calling the Evaluate method on our code block.

Some magic happens in Evaluate where it takes the code block (seen in the dump above) and evaluates it. A lot of that magic is in generated code, so we can’t dive into it here. However, if you put a breakpoint on Kernel.PutString, you can see that the puts call gets converted to the Kernel.PutString call. You’ll also notice that by the time Evaluate is finished executing (but before we go into PrintInteractiveCodeResult) “Hello, World” has already been printed on the console.

With our message printed, we dive into PrintInteractiveCodeResult which is pretty straightforward:

protected override void PrintInteractiveCodeResult(object obj) {
  Kernel.Print(_defaultContext, null, “=> “);
  Kernel.PutString(_defaultContext,
    null,
    RubySites.Inspect(_defaultContext, obj));
}

The first, Kernel.Print, outputs the =>. The second looks at the return value of our expression and outputs that. Since we called puts, it returns nil, and that’s what will get printed. I was surprised to see Kernel.Print directly printed to Console instead of having the output be hooked up via a provider. Something that will be changed I’m sure.

And that’s it! We’ve now got our console window staring back at us waiting for someone to push enter. May as well go ahead and be you.

Note: This post was written just by loading up the source from RubyForge, creating a Visual Studio project, and stepping through it with a debugger. I’m not on the IronRuby team (although, if they need someone…), and I’ll update the post to fix any glaring omissions.

Also, this code is changing every day, so it may not look like this tomorrow. Especially given the number of TODOs I saw. ;)

Enjoy!

No Comments


Posted on September 24th, 2007

On Friday, Jim Newkirk announced a new .NET testing framework called xUnit.net. So far, I really like the looks of it – things like getting rid of [TearDown] in favor of making the test disposable and adding Assert.Throws instead of [ExpectedException].

And while I agree with a lot of the reason’s behind Jim’s post, and his and Brad’s work on the project, looking at their comparison page tells a lot. To do Unit Testing with Java, you pretty much use JUnit. For Ruby, it is built in. For .NET, you have:

  • NUnit (plus different versions)
  • NUnitLite
  • MbUnit
  • MSTest (In Visual Studio)
  • xUnit.NET

To make it more challenging, two of the frameworks – MSTest and xUnit.NET, are written by Microsoft people. Yes, MSTest is the “official” product, but since Jim and Brad have been important parts of Patterns and Practices and CodePlex inside Microsoft, they are still employed by Microsoft.

Is this a good thing? Some would argue yes – having choice is always a good thing. I just wish that either we as a .NET community could have one standard, or Microsoft would stop restricting its people from working on open source projects so that NUnit could be both an integral part of Visual Studio and benefit from enhancements like these.

But congrats to Jim and Brad (and all those that helped with the project) – it looks like a great start, and I’m looking forward to diving more into it.

No Comments


Posted on September 24th, 2007

Since around 2000, I’ve owned my own domain and pretty much had my email on it since then. When you own your own domain, one thing you get control over is the email that is sent to it. So pretty early on I made a decision that whenever I did business with a company that requested my email address, they would get an email address of companyname at my domain. By doing this I can keep track of what happens to my email address, and who really keeps up with their privacy policies.

Suprisingly, for the most part very few companies sell my email address. Sure, there’s the various contest or two, or sometimes spammers pick it up from mailing lists or web sites, but it’s been a pretty good ride. Up until recently there was only one company that every surprised me, and this week I’ve now added a second one to that list. They are:

  • Ameritrade
  • Bank of America

Yes. Two financial institutions which I trust (or trusted) my personal financial details to both sold my address off. The first one – Ameritrade – is a known issue. Feel free to search around and see for yourself. I get hundreds of spams a day for that email, and pretty much any email to it goes to the trash (since I stopped doing business with them a long time ago).

The second – Bank of America – was a little more surprising. I’ve banked with them for years now, and never had a problem. However, about two weeks ago we closed on our house with our mortgage through – yep – Bank of America. Since then I’ve started receiving spam to that email address. My only guess is that they sold my information for the stupid “Get Mortgage Life Insurance now!” junk mail I get through the post office, and my email address was attached to that.

Note that neither of these email addresses are receiving scam spam – meaning they aren’t phishing attacks, just POS (plain ol’ spam).

The sad part is that while I will call the bank and complain (as I did with Ameritrade) – my email address is out there, and there is nothing that can be done to stop that. Time to change my email address and blacklist the old one.

1 Comment


Posted on September 19th, 2007

Shiver me timbers! The vagabonds that be showin’ up fer the meetin’ tonight can laugh if they laugh on th’ other side, but they’s be as good as a dead man’s chest for not knocking their noggins fer today’s International Talk Like a Pirate Day! ARRR!

No Comments


Posted on September 18th, 2007

Tomorrow night (9/19/07) I’ll be speaking at the Space Coast .NET User Group on Ruby for .NET Developers. I’ll be covering Ruby as a language, Rails, RSpec, IronRuby and the DLR. The meeting starts at 6:30pm at a place called Charlie and Jake’s which sounds like a fun place. Hope to see you there!

1 Comment


Posted on September 13th, 2007

The past 2 weeks have been incredibly hectic. It’s all been leading up to this weekend, when we close on our house tomorrow and move in Saturday.

My wife and I were talking last night, and realized that we’ve both averaged 7 moves in 7 years, 5 of which were since we got married at the end of 2003. Whew!

The good thing is that most of our stuff is still in boxes as we were renting this house when we moved back to Florida.

All this to say that most of my computer equipment is being packed today, and I should have everything back up by Monday. See you on the flip side!

No Comments


Posted on September 12th, 2007

For those of you running Visual Studio 2005, Tuesday’s updates pushed out KB937061. If you had installed Crystal Reports as part of your install, everything was probably hunky dory. However, if you don’t have that installed, you may see a problem where Windows Update does not report the patch as being installed.

The product team is working on this from what I understand, and the workaround if you need to have it installed is to install Crystal Reports from the VS install media.

Here’s the MSDN Forums thread with the first reports and a little more information.

No Comments


Posted on September 12th, 2007

Today’s post comes from a tutorial I’m working on for a customer who still does a lot of XML/XSL stuff. One of the more challenging things to do in XSL1.0 (which is what most browsers support) was getting a distinct list of values from a set of nodes. Exslt has a good article on the subject, including this link to Jeni Tenison’s XSLT Template. In the back of my mind, I kept wondering if there was some way to do this with keys, and the customer I’m working with showed a way they do it.

Let’s say you have an XML document like:


 

    FL
 

 

    GA
 

 

    MN
 

 

    FL
 

And you want to output something like:


  FL
  GA
  MN

The way to do this with keys is to define an xsl:key like this:

This let’s us set up a key to access Address nodes with. We can then get the distinct list in an xsl:for-each node by combining this with the generate-key function:

generate-id “generates a key that uniquely identifies a specified node“, in this case, basically creating a node-set of the state nodes and returning the first node for each distinct value. So our full xsl would look something like:





 


Which is all well and good. However, in the tutorial example, state isn’t in its own node – it’s embedded in the Address like:


123 Sample Way, Tampa, FL

Which is a tad trickier. In the tutorial, we’ve allowed the assumption that the state will always be the last 2 characters of the Address field. So how can we get a distinct list of states with data like this?

Turns out that we can do it in a very similar (if complex) way. We start off by specifying the key:

Here, our Address node is a child of Customer, which is a child of Customers – the root node. So we are matching Customers/Customer, and using the value of the last 2 characters of the Address. We then need to do the same for our for-each loop:


 
   
      
name=”state”
       select=”substring(Address, (string-length(Address)-1))”/>
  

So we are doing the unique select on the state value. However, this returns the matching node – which is an Address node, so to use the value (in our example here as a parameter to a named template) we have to still substring it out.

Of course, this would probably be a better time to either see if you can get State into its own node, or do some sort of pre-processing to do that, but when you have neither of those options, this will work.

Thanks to Len and the SR team for the initial key idea

6 Comments


Posted on September 11th, 2007

This afternoon I happened across a CodeProject article on creating the Sierpinski Triangle in Silverlight. It looked interesting enough, and I haven’t played much with Silverlight, so it sounded like a match made in heaven.

I started first by clicking the demo link, which led me to the “Download Silverlight” icon. The problem? I thought I had Silverlight installed already. So I headed over to the Silverlight site. Have you been there? It took me nearly 3 minutes to get to the download page because stuff was jumping around, twirling and refreshing. And then, when I did get to the download page, it came up saying “Click here to install” but before I got the chance to, the page zoomed away and was replaced with a “Congratulations for installing Silverlight” page, which linked to a test page. So, assuming that I was right and did have it installed, I clicked over.

Unfortunately, the test – whether some image was moving – was just a white box. So I clicked that I couldn’t see the image was moving and proceeded to go through the download/fly away/congrats page/test page loop a couple of times. After the 4th time landing on the test page, I was pondering what to do next when suddenly an image showed up and started moving. Ah! I guess that a) I had to wait for the image to download (without any clue and b) I did have Silverlight installed. So I went back to the demo page – but no luck.

Then I saw that the download image on the demo page had a little “Alpha” banner on it. Ah! They must want Silverlight 1.1. So I head back over to the Silverlight site and download the 1.1 installer. Everything is going fine when – poof – my IE windows disappear. All of ‘em. Shocked and amazed, I sat there slightly stunned until suddenly IE popped back up and reloaded all of the windows and tabs I had opened. Well, I’m sure glad that it felt it was perfectly Ok to just restart my browser without warning or permission.

So everything should be hunky dory, right? Nope – I head back to the demo site, and all I see is the “Get Microsoft Silverlight” image. Unfortunately, SQL is finished installing on my other machine now, so there went the chance to try out Silverlight.

Funny, I don’t remember having these problems with Flash. Not even in Linux. Oh well. Maybe some other day.

No Comments