Archive for September, 2010

Mad Scientist At Work

2 commentsWritten on September 8th, 2010 by
Categories: IronRuby, NHibernate, Ruby

Just wanted to show some code, and yes, it actually works :)

    using (var session = sessionFactory.OpenSession())
    {
        var artist = ruby.ObjectFactory.CreateArtist();
        artist.Name = "some name";
        session.Save("Artist", artist);
        session.Flush();
        // and this actually prints out the id of the artist (in this case, it's defined as an identity in sql server)
        Console.WriteLine(artist.ArtistId());
    }

and

    using (var session = sessionFactory.OpenSession())
    {
        var albumId = 1;
        var artistId = 1;

        var album = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get("Album", albumId));
        // the following line does NOT issue a select statement
        Console.WriteLine(album.Artist().ArtistId());
        // but this one obviously will trigger the lazy loading of the Artist instance
        Console.WriteLine(album.Artist().Name());

        var realArtist = ruby.ObjectFactory.create_from_nhibernate_hash(session.Get("Artist", artistId));

        album.Title = album.Title() + " 2";
        realArtist.Name = realArtist.Name() + " 2";

        if (album.Artist() == realArtist && album.Artist().Name() == realArtist.Name())
        {
            // this actually persists the changes
            session.Flush();
        }
        else
        {
            throw new InvalidOperationException("The universe should collapse");
        }
    }

I can't get property syntax working properly (as in: without requiring the parentheses) when accessing mapped properties due to an issue with IronRuby that needs to be fixed first, but other than that i'm pretty happy with how this works :)

Full details will be posted once i've taken care of a few more things ;)

You Need To Step Out Of Your Comfort Zone

20 commentsWritten on September 7th, 2010 by
Categories: Opinions, work/career

Up until about a month ago, i focused almost exclusively on the .NET world, at least when it came to the purely technical stuff. I knew about the old advice of how important it is for programmers to learn a new language every year. I heard a lot of people mentioning it all the time. But at the same time i often thought "instead of learning a lot of languages, wouldn't it better to really focus on one and know it very thoroughly?". I figured that if i focused on C# and .NET that it would make me better at what i do: writing C# and .NET code.

But as i learned this month, there is a huge downside to that kind of thinking. Whether you realize it or not, you slip into a comfort zone if you're always dealing with the same environment. You're not often surprised anymore because you've probably already dealt with most issues that could come up already. If you stick to the same language, the same tools, the same libraries all the time, you'll easily start thinking that you're working with a stable basis. You know what works, and you know what to watch out for. Sure sounds like a great deal, no?

Well... the downside of that, and i'm basing this solely on what i've learned in the past month since starting my Ruby journey, is that you're not really learning anything new. Oh sure, you'll learn about the latest and greatest new features of your favorite Inversion Of Control Container or your favorite Object Relational Mapper. You'll pick up some new techniques for testing your code. You'll pick up some tricks about improving your design skills. But most of what you'll learn will be evolutionary improvement. You gradually learn small new things that incrementally improve the way you work. And that's only if you're a passionate, motivated developer.

And as great as continuous improvement is, sometimes you sort of need to give yourself a jump start, just to keep things interesting. The best way to do that is to get out of your comfort zone and learn something entirely new. Ideally, something that challenges the practices and principles that you're used to. In my case, Ruby did the trick. Now some of you are probably thinking "huh? C# is object oriented, and so is Ruby... what could possibly be so different?". Well, the whole static vs dynamic thing can really have a profound influence on how you think about OO design. It sure has had a huge influence on me already. To put it simply: it might still be OO, but the 'rules' are truly different.

And that's the key right there: the fact that learning about something makes you think different about something you already thought you had a pretty good idea about. And that really works on multiple levels. Do you think you need Visual Studio with its debugger support and intellisense? Well, i'm quite happy to say that i no longer feel that i need to rely on those tools. I now know that i don't need them and can be (way more) productive in other ways. I advise you to test yourself in a similar manner: you'll either learn that you don't need those tools, or you'll learn to appreciate them even more. You really can't lose. And to avoid any confusion: tooling is just one aspect of it. It applies to the way you think about stuff in general.

So seriously, do yourself a favor and go out and learn something new about what you thought you already knew. You'll either gain a new perspective on things, or you'll gain a renewed appreciation of whatever it is you already believe in. It's simply a win-win situation.

Using Ruby Classes In C# With IronRuby

9 commentsWritten on September 6th, 2010 by
Categories: IronRuby, Ruby

I wanted to see how easy or difficult it would be to use your own Ruby classes from C# through IronRuby. Turns out it's pretty easy to do so.

Suppose we have the following simple Ruby classes:

class Customer
  attr_reader :name
  attr_reader :email
  
  def initialize(name, email)
    @name = name
    @email = email
  end
end

class Product
  attr_reader :name
  attr_reader :price

  def initialize(name, price)
    @name = name
    @price = price
  end
end

class OrderItem
  attr_reader :product
  attr_reader :count

  def initialize(product, count)
    @product = product
    @count = count
  end
end

class Order
  attr_reader :customer
  attr_reader :date
  attr_reader :discount
  attr_reader :items
  
  def initialize(customer, discount, date)
    @customer = customer
    @discount = discount
    @date = date
    @items = []
  end
  
  def add_item(item)
    @items << item
  end
end

Each of those classes is located in its own file, but i've listed all of the code together here. Now, how hard or easy would it be to say, create an Order instance in C#?

It turns out to be pretty easy. It's pretty easy to start up a Ruby engine in .NET and have it execute some Ruby files. Now, i don't want to tell it to execute each file, so i create a bootstrap.rb file which contains the following code:

load 'product.rb'
load 'customer.rb'
load 'orderitem.rb'
load 'order.rb'

Obviously, this just loads each entity's file into the current scope.

Now, i can just do this in C#:

            var engine = Ruby.CreateEngine();
            engine.ExecuteFile("bootstrap.rb");
            dynamic ruby = engine.Runtime.Globals;

            dynamic customer = ruby.Customer.@new("Davy Brion", "davy@gmail.com");
            dynamic product1 = ruby.Product.@new("product1", 50);
            dynamic product2 = ruby.Product.@new("product2", 60);
            dynamic order = ruby.Order.@new(customer, null, DateTime.Now);

            order.add_item(ruby.OrderItem.@new(product1, 5));
            order.add_item(ruby.OrderItem.@new(product2, 5));

            var total = 0;
            foreach (dynamic item in order.items)
            {
                total += item.count * item.product.price;
            }

            Console.WriteLine("order total: " + total);
            Console.WriteLine();
            Console.WriteLine(order.inspect());

And the output of that is this:

order total: 550

#<Order:0x000005c @customer=#<Customer:0x0000056 @name='Davy Brion', @email='davy@gmail.com'>, @discount=nil, @date=9/5/2010 22:36:14, @items=[#<OrderItem:0x000005e @product=#<Product:0x0000058 @name='product1', @price=50>, @count=5>, #<OrderItem:0x0000060 @product=#<Product:0x000005a @name='product2', @price=60>, @count=5>]>

Not sure what you think of that, but i thought it was pretty impressive. I'd hoped that this would be possible, but i wasn't sure since most of the examples you see about IronRuby seem to be focused on using .NET types from Ruby code that is interpreted by IronRuby's interpreter. But given the flexibility that you have in Ruby when it comes to designing classes, i'm much more interested in using Ruby classes from C# code instead of the other way around.

Let's go over some parts of the code...

            var engine = Ruby.CreateEngine();
            engine.ExecuteFile("bootstrap.rb");
            dynamic ruby = engine.Runtime.Globals;

This is all you need to do to start the Ruby engine (no idea why they call it that but whatever) and execute our bootstrap.rb file so that our classes are defined. We then have access to IronRuby's top-level binding through the engine.Runtime.Globals property.

So now we can simply create instances of these classes like this:

            dynamic customer = ruby.Customer.@new("Davy Brion", "davy@gmail.com");
            dynamic product1 = ruby.Product.@new("product1", 50);
            dynamic product2 = ruby.Product.@new("product2", 60);
            dynamic order = ruby.Order.@new(customer, null, DateTime.Now);

It's too bad that we have to escape the 'new' method because the C# compiler should be capable of figuring out that we aren't using the new operator there. But other than that, i'm pretty happy with how this works.

            order.add_item(ruby.OrderItem.@new(product1, 5));
            order.add_item(ruby.OrderItem.@new(product2, 5));

As you can see, calling methods on the instances of our Ruby classes looks normal as well, except for the fact that those classes use the typical Ruby naming conventions instead of offering a typical .NET-looking AddItem method. We'll fix that later though ;)

            var total = 0;
            foreach (dynamic item in order.items)
            {
                total += item.count * item.product.price;
            }

Now this is actually cooler than it might appear on first sight. First of all, notice the lack of parentheses when we call order.items, item.count and item.product.price. Big deal, you use properties all the time right? Well, Ruby doesn't have properties... it just has methods and due to some of its rules you can write this in Ruby:

  count = item.count
  item.count = 5

Which is actually only syntactical sugar for what it really is:

  count = item.count()
  item.count=(5) # the method name actually is 'count='

The fact that using these methods as if they are properties in C# is a nice touch, though it only works for accessor methods which were defined with the attr_reader, attr_accessor and attr_writer methods in your Ruby classes. If you defined your own accessor methods, you will have to use parentheses when you call them in C#.

The other thing that i find pretty cool about that piece of code is that you can use the foreach statement to loop through the return value of the order.items method, which is a Ruby array. Not sure whether IronRuby implicitly wraps Ruby arrays as IEnumerables or if it does that with all Ruby types which mix in the Enumerable module, but whatever it is, it's cool.

All in all, it's pretty nice that we can easily create and use these instances of classes that we defined in Ruby. But i'm a big fan of sticking to the accepted naming guidelines for each language. In Ruby, each method is lowercased and optionally uses underscores instead of the capitalized pascal cased method names that we typically use in C#. And when you use CLR types in Ruby code that is running in IronRuby, you can indeed stick to Ruby's naming conventions and IronRuby will automatically 'translate' method calls like write_line to WriteLine. It would be cool if, for instance, we could do order.AddItem in the example above and that it would just be 'translated' to order.add_item. And of course, if we could use capitalized versions of the accessor methods then it would look like pretty typical .NET code apart from the call to the @new method.

With Ruby code, pretty much everything is possible so it shouldn't be a surprise that we can easily 'fix' the naming convention issue. Keep in mind though that the approach i'm going to show is quite crude, and there most likely is a better way that i haven't thought of yet. I just added the following code at the bottom of the bootstrap.rb file:

if defined? IronRuby
  def add_dotnet_friendly_method_aliases_for(klass)
    klass.public_instance_methods.each do |method|
      klass.instance_eval do
        dotnet_friendly_name = IronRuby::Clr::Name.unmangle(method)  
        alias_method dotnet_friendly_name, method unless dotnet_friendly_name.nil? # in this case, it's already a dotnet friendly name
      end
    end
  end

  add_dotnet_friendly_method_aliases_for Product
  add_dotnet_friendly_method_aliases_for Customer
  add_dotnet_friendly_method_aliases_for OrderItem
  add_dotnet_friendly_method_aliases_for Order
end

Since we only need to do this if we're running in IronRuby, we first check whether the IronRuby constant is defined. If it isn't there's no point in adding the .NET-friendly method aliases. If we are running in IronRuby, we just add a method alias for each public instance method of our 4 classes. Again, it's a crude solution, but it does enable us to write the following C# code:

            var engine = Ruby.CreateEngine();
            engine.ExecuteFile("bootstrap.rb");
            dynamic ruby = engine.Runtime.Globals;

            dynamic customer = ruby.Customer.@new("Davy Brion", "davy@gmail.com");
            dynamic product1 = ruby.Product.@new("product1", 50);
            dynamic product2 = ruby.Product.@new("product2", 60);
            dynamic order = ruby.Order.@new(customer, null, DateTime.Now);

            order.AddItem(ruby.OrderItem.@new(product1, 5));
            order.AddItem(ruby.OrderItem.@new(product2, 5));

            var total = 0;
            foreach (dynamic item in order.Items)
            {
                total += item.Count * item.Product.Price;
            }

            Console.WriteLine("order total: " + total);
            Console.WriteLine();
            Console.WriteLine(order.Inspect());

And it works just like you'd expect it to. So far, i'm pretty happy, and very impressed with IronRuby :)

What’s Up With These Belgians?

19 commentsWritten on September 5th, 2010 by
Categories: About The Blog

Don't worry, this post isn't about the ongoing political problems that Belgium has been suffering from for the past 3 years. It's about something far more interesting (ahem): the way they read my blog. I was going over the blog's stats for last month:

As you can see, the numbers for the Belgians are far different than they are for each other country in that list. The number of pages they read each visit is way above the average. The average time they spend on this site is also much higher than most countries. And the percentage of new visitors and the bounce rate is a lot lower than what we see from other countries. That means that almost 4 out of 5 Belgians that visit this site have been here before, and keeping the total number of visits in mind and the fact that it has a much smaller population than the other countries in the top 7, they seem to keep coming back as well. And this isn't just an anomaly because the all-time stats for this blog show pretty much the same picture:

So that makes me wonder: what's up with these Belgians? And yes, i know that some of you are probably thinking: "well duh, it's because you're Belgian too!". But there are a couple of reasons why i don't think that me being from Belgium explains it:

  • The Google Analytics plugin that i'm using does not count my own visits :)
  • I do very, very little networking so it's not like i'm often in contact with a lot of Belgian developers to plug my blog
  • I don't go to developer events to evangelize my ideas, in fact, i generally don't go to developer events
  • I don't give talks or presentations, except for one that i did on NHibernate a year ago. And i don't see myself doing a lot of talks in the future either since i have no idea what i'd talk about.

So, it can't be because i've been pushing this blog among the Belgian developers. So what is it then? Is it because we Belgians are generally quite thorough when it comes to learning about stuff we like? Or are we just lazy and do we love to waste a lot of time online? Both are true to some degree :) . Either way, it's nice to see Belgium among the top of a list (even if it doesn't mean shit) that isn't related to female tennis, chocolate, beer, organized crime or fraud.

Seriously though, i do find this kind of stuff interesting so if you are Belgian (or are familiar with how Belgians are) and have some ideas on why those numbers are so different from other countries, please do share :)

Writing A Simple DSL

3 commentsWritten on September 4th, 2010 by
Categories: DSL, Ruby

Creating a DSL seems like a hard thing to do, right? While there are various interesting challenges that you'll need to deal with if you want to build and use a real DSL, the initial step of getting it working is actually a lot easier than you might think it is. I'm gonna walk you through the creation of a simple DSL, suitable for a domain that all of us have experience with. The domain is quite simple: describing entities, their properties and their relationships. Forget for a second that you could obviously get the exact same information from a set of class definitions. It's merely a technical exercise using a domain that we all know :)

One of the key questions that we need to ask ourselves is: what kind of concepts do we want to be able to describe with our DSL? In our case, we want to describe a model consisting of entities. Disregarding behavior for now, we can say that each entity will consist of properties. Properties could be regular properties, references to other Entities, or collections of other entities. Here's one way (of many, obviously) to model that in Ruby (since that language makes it very easy to define a DSL):

require 'forwardable'

class Model
  extend Forwardable
  
  def initialize
    @entities = []
  end

  def add_entity(entity)
    @entities << entity
  end
  
  def entity_for(name)
    @entities.detect { |entity| entity.name == name }
  end

  def_delegator :@entities, :each, :each_entity  
end

class Entity
  extend Forwardable

  attr_reader :name

  def initialize(name)
    @name = name
    @collections = []
    @properties = []
    @references = []
  end
  
  def add_collection(collection)
    @collections << collection
  end
  
  def add_property(property)
    @properties << property
  end
  
  def add_reference(reference)
    @references << reference
  end
  
  def identifier
    @properties.detect { |property| property.is_identifier? }
  end

  def_delegator :@collections, :each, :each_collection
  def_delegator :@properties, :each, :each_property
  def_delegator :@references, :each, :each_reference  
end

class Property
  attr_reader :name
  attr_reader :required
  attr_reader :type
  
  def self.new_identifier(name, type)
    self.new(name, type, false, true)
  end
  
  def initialize(name, type, required=false, is_identifier=false)
    @name = name
    @type = type
    @required = required
    @is_identifier = is_identifier
  end
  
  def is_identifier?
    @is_identifier
  end
end

class Reference
  attr_reader :name
  attr_reader :entity
  attr_reader :is_required
  
  def initialize(name, entity, is_required)
    @name = name
    @entity = entity
    @is_required = is_required
  end
end

class Reference
  attr_reader :name
  attr_reader :entity
  attr_reader :is_required
  
  def initialize(name, entity, is_required)
    @name = name
    @entity = entity
    @is_required = is_required
  end
end

class Collection
  attr_reader :name
  attr_reader :entity

  def initialize(name, entity)
    @name = name
    @entity = entity
  end
end

That gives us a simple, yet complete object model to describe entities, their properties and their relationships. The next question is: how do we define the DSL? Considering an Invoice entity, suppose we'd like to describe it in our DSL like this:

entity "Invoice"
identified_by "Id", :guid
must_reference "Customer"
must_have "Date", :date
can_have "Discount", :double
contains "Lines", "InvoiceLine"

This really tells us anything we need to know about this entity, and we could use this data for pretty much everything we want. There is no explicit or implicit link to any specific kind of technology, like say, a relational database, a document database, or some kind of databinding technology. We could transform or extend this data to suit whichever purpose we deem fit.

So now that we know how we want to describe our entities and their relationships, we can implement the language. As mentioned in the title of this post, this is the implementation of a simple DSL. It's just to illustrate an idea, and not an approach that is guaranteed to stand up to the real-world requirements that a DSL could face (and that depends on a case by case basis). So in this case, we're going to go with an implementation where each entity is described in its own file, and its filename must end with '_def.rb'. With that limitation in mind, we can do this:

require_relative 'application.rb'
require_relative 'entity.rb'
require_relative 'collection.rb'
require_relative 'property.rb'
require_relative 'reference.rb'

@model = Model.new

def entity(name)
  entity = Entity.new(name)
  @model.add_entity entity
  @current_entity = entity
end

def identified_by(name, type)
  @current_entity.add_property Property.new_identifier(name, type)
end

def must_have(name, type)
  has name, type, true
end

def can_have(name, type)
  has name, type, false
end

def must_reference(entity_name, name=nil)
  references entity_name, true, name
end

def can_reference(entity_name, name=nil)
  references entity_name, false, name
end

def contains(name, entity_name)
  referred_entity = @model.entity_for entity_name
  @current_entity.add_collection Collection.new(name, referred_entity)
end

def has(name, type, required=false)
  @current_entity.add_property Property.new(name, type, required)
end

def references(entity_name, is_required=false, name=nil)
  referred_entity = @model.entity_for entity_name
  name = entity_name if name.nil?
  @current_entity.add_reference Reference.new(name, entity_name, is_required)
end

Dir.glob('*_def.rb').each do |file| 
  @current_entity = nil
  load file
end

@model.each_entity do |entity|
  puts entity.name
  print_name = Proc.new { |item| puts "\t\t#{item.name}"}
  puts "\t has the following properties:"
  entity.each_property &print_name
  puts "\t has the following references:"
  entity.each_reference &print_name
  puts "\t has the following collections:"
  entity.each_collection &print_name
end

As you can see, we have 'global' method definitions (they're actually implicitly added to the Object class) which correspond with our language 'keywords'. Those method implementations use the model that we defined earlier to build a nice object graph based on what we describe through our DSL.

You'll notice that after the method definitions, you can see the following code:

Dir.glob('*_def.rb').each do |file| 
  @current_entity = nil
  load file
end

And that's the clue to this simple DSL: it loops through each file that matches the '*_def.rb' pattern, sets an instance variable named @current_entity (implicitly added to the current Object instance in this case) to nil, and then loads the current file in the loop. The load method (it might look like a keyword, but it's a method) executes the ruby code in the given file in place, meaning that it shares the same scope. In other words, the methods that we've defined here are accessible to our DSL declarations since those are executed within the same scope. And since those method implementations manipulate our domain model, we just built a simple 'language' to describe our entities, their properties and their relations.

Suppose we've got the following entity definitions (each would be in a separate file, but they are just listed all at once here):

entity "Customer"
identified_by "Id", :guid
must_have "Name", :string
can_have "Email", :string

entity "Product"
identified_by "Id", :guid
must_have "Name", :string
must_have "Price", :integer

entity "InvoiceLine"
identified_by "Id", :guid
must_reference "Product"
must_have "Count", :integer

entity "Invoice"
identified_by "Id", :guid
must_reference "Customer"
must_have "Date", :date
can_have "Discount", :double
contains "Lines", "InvoiceLine"

This describes a very small domain model consisting of 4 entities. In the code listed above, you may have noticed the following piece at the end:

@model.each_entity do |entity|
  puts entity.name
  print_name = Proc.new { |item| puts "\t\t#{item.name}"}
  puts "\t has the following properties:"
  entity.each_property &print_name
  puts "\t has the following references:"
  entity.each_reference &print_name
  puts "\t has the following collections:"
  entity.each_collection &print_name
end

Given the 4 described entities, running the code above results in the following output:

Customer
     has the following properties:
        Id
        Name
        Email
     has the following references:
     has the following collections:
Invoice
     has the following properties:
        Id
        Date
        Discount
     has the following references:
        Customer
     has the following collections:
        Lines
InvoiceLine
     has the following properties:
        Id
        Count
     has the following references:
        Product
     has the following collections:
Product
     has the following properties:
        Id
        Name
        Price
     has the following references:
     has the following collections:

So there you have it, we described our entities, their properties and their relationships in a very simple manner and those descriptions were interpreted and the data has been put into an object model that we can use for a variety of purposes if we wanted to. And there really are a lot of interesting things we can do with this, especially when keeping IronRuby in mind :)