Saturday, November 25, 2006

New Hebruby Release

I have just released a new update of Hebruby, the Ruby hebrew date conversion library. It is now available as a proper Ruby gem, and has much improved documentation. If your Rails application needs to convert from julian date to a hebrew date, or from a hebrew date to a julian date, or display a date in hebrew (either in hebrew or transliterated into english) this gem is for you.
To install it, just:

gem install hebruby

Thank you to everyone who has helped with Hebruby, especially Joshua Harvey, and enjoy!

Sunday, November 19, 2006

Ruby Domain Specific Languages - The Basics (Part 3)

This is another installment in a series about creating domain specific languages with Ruby. In part 1 and part 2 of this series, I created a simple Ruby DSL to describe the relationship between Pets and Persons. Now I will extend the DSL, and use some cool Ruby metaprogramming tricks to demonstrate the power and benefits of using Ruby to create an internal DSL.
First, I want to simplify the syntax for declaring things in our DSL. Getting rid of the class definition stuff can make it a lot easier for domain experts to read. A simple, cool declarative style like Rake is what we want to end up with, something like this:

person "Dorothy" do
temperament :nice
food :sunflower_seeds, :carrot_juice
end

Furthermore, I want to extend our DSL to put all of the descriptions of Pets and Persons together into a PetShop. Here is our PetShop DSL:

shop = PetShop.create do
pet "Toto" do
friend_test do |person|
true unless person.temperament == :mean
end
end

pet "Tweety" do
friend_test do |person|
person.has_food?(:sunflower_seeds)
end
end

pet "Slugworth" do
friend_test do |person|
true # I like anyone
end
end

person "Dorothy" do
temperament :nice
food :sunflower_seeds, :carrot_juice
end

person "Witch" do
temperament :mean
food :cheetos, :soda
end
end

One interesting technique used is declaring the "pet" within the "do-end" block for the "petshop" object:

shop = PetShop.create do
pet "Toto" do
friend_test do |person|
true unless person.temperament == :mean
end
end

...
end

The little bit of DSL niceness is achieved using the class_eval method. The block of code within the "do" block is called in the context of the newly created object. Here is the Ruby code that achieves this for a new Pet:

def self.pet(name, &blk)
@pets = Hash.new
p = Pet.new(name)
p.class.class_eval(&blk) if block_given?
@pets[name] = p
p.copyvars
end


Now that we have declared all of the Pets and Persons in to the context of a PetShop, we can test the relationships between Pets and Persons is a more general purpose way then in my previous post. The older, more fragile code was this:

dog = Toto.new
bird = Tweety.new
snail = Slugworth.new

person = Dorothy.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"
puts

person = Witch.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts

The new, cleaner code is like this:

shop.people.each_value do person
shop.pets.each_value do pet
puts "Is #{pet.name} a friend of #{person.name}? #{pet.is_friend?(person)}"
end
end

And here is the output when we run the program:

Is Toto a friend of Witch? false
Is Slugworth a friend of Witch? true
Is Tweety a friend of Witch? false
Is Toto a friend of Dorothy? true
Is Slugworth a friend of Dorothy? true
Is Tweety a friend of Dorothy? true

We have simplified the syntax of our domain specific language, and added some additional functionality. We have also been able to reduce the amount of Ruby code required at the same time.

Here is the final version of the code:

class DSLThing
def copyvars
self.class.instance_variables.each do |var|
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end

class PetShop < DSLThing
attr_accessor :pets, :people

def self.create(&block)
f = PetShop.new
f.class.class_eval(&block) if block_given?
f.copyvars
return f
end

def self.pet(name, &blk)
@pets ||= Hash.new
p = Pet.new(name)
p.class.class_eval(&blk) if block_given?
@pets[name] = p
p.copyvars
end

def self.person(name, &blk)
@people ||= Hash.new
p = Person.new(name)
p.class.class_eval(&blk)
@people[name] = p
p.copyvars
end
end

class Animal < DSLThing
attr_accessor :name

def initialize(name=nil)
@name = name
end
end

class Person < Animal
attr_accessor :temperament

def initialize(name=nil)
super
end

def self.temperament(type)
@temperament = type
end

def self.food(*types_of_food)
@food = []
types_of_food.each do |food|
@food << food
end
end

def has_food?(type_of_food)
@food.include?(type_of_food)
end
end

class Pet < Animal
def initialize(name=nil)
super
end

def self.friend_test(&test)
@friend_test = test
end

def is_friend?(person)
@friend_test.call(person) == true
end
end

shop = PetShop.create do
pet "Toto" do
friend_test do |person|
true unless person.temperament == :mean
end
end

pet "Tweety" do
friend_test do |person|
person.has_food?(:sunflower_seeds)
end
end

pet "Slugworth" do
friend_test do |person|
true # I like anyone
end
end

person "Dorothy" do
temperament :nice
food :sunflower_seeds, :carrot_juice
end

person "Witch" do
temperament :mean
food :cheetos, :soda
end
end

shop.people.each_value do |person|
shop.pets.each_value do |pet|
puts "Is #{pet.name} a friend of #{person.name}? #{pet.is_friend?(person)}"
end
end

Monday, November 13, 2006

The Dark Side Of Metrics

I have usually been in favor of measurement of any possible aspect of the software development process. Proper techniques of gathering and analyzing metrics have been espoused since Capers Jones created the study of software measurement. I was first introduced to many of these concepts in the writings of Steve McConnell, particularly when his book Rapid Development first came out. If a thing cannot be measured, it cannot be easily studied or improved.
But any tool, no matter how well intentioned its purpose, can be used for ill. Any system that relies entirely on user entered information can by lied to. Such systems can be gamed, for various purposes. In a very political environment, a rogue group can manipulate their own metrics to gain power over other groups, gain budget, or simply steer the company in the direction of their own egos. Sometimes metrics can be used to hide something important. "But look at our metrics," protests the manager in charge of a spectacular failure.
Even worse, once this starts to happen, the "everybody's doing it" syndrome strikes, and it can spread like a disease. Pity the poor foolish team that actually tries to tell the truth within such a system once this dynamic sets in. They will be punished, sometimes severely, for "not measuring up to the standards of the company".
The best sorts of metrics are collected automatically. All sorts of interesting information can be learned from analysis of the source code repository. Other information can be assessed from other dynamic sources such as number of unit tests passed, or Fitnesse tests, or measuring Running Tested Features. The important thing is that it is a lot more reliable to use metrics that are not so easily fooled by people with various agendas.

Wednesday, November 08, 2006

Ruby Domain Specific Languages - The Basics (Part 2)

Previously, I was exploring the basics of DSL creation using Ruby. This post continues sharing my lessons learned while developing a prototype of a domain specific language in the mortgage industry. Since I cannot share the actual code itself belonging to my client, I will continue to extract the useful concepts into these simple examples.

Last time we created a simple Animal DSL class. The important part of that class is this bit that makes sure our DSL like syntax works for the declarative methods:

class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
self.class.instance_variables.each do |var|
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end

Now we will create a Person class that can interact with the Animals. Each Person will have a temperament (either mean or nice), and will be carrying some kind of food in their pocket to feed their pet. We will define people using our DSL as follows:


class Dorothy < Person
temperament :nice
food :sunflower_seeds, :carrot_juice
end

class Witch < Person
temperament :mean
food :cheetos, :soda
end


The implementation is very similar to the basic Animal class

class Person < Animal
attr_accessor :temperament

def self.temperament(type)
@temperament = type
end

def self.food(*types_of_food)
@food ||= []
types_of_food.each do |food|
@food << food
end
end

def has_food?(type_of_food)
@food.include?(type_of_food)
end
end


Since we are working with an array, the self.food method has a variable number of parameters, represented using the asterisk in front of the parameters list. The cool little idiom @food ||= [] returns with the current @food variable, or if it is nil, returns an empty array. There is also a has_food? method to tell us if a person is carrying a certain type of food.

Now let us introduce the Pet. We will use the power of Ruby blocks to tell each pet the rules about when it likes a person, or not. Here is the DSL we want to use for the Pets:

class Toto < Pet
friend_test do |person|
true unless person.temperament == :mean # I like anyone who is not mean
end

end

class Tweety < Pet
friend_test do |person|
true if person.has_food?(:sunflower_seeds) # I like anyone who has sunflower seeds
end
end

class Slugworth < Pet
friend_test do |person|
true # I like anyone
end
end


And now the implementation of the Pet class:

class Pet < Animal
def self.friend_test(&test)
@friend_test = test
end

def is_friend?(person)
@friend_test.call(person) == true
end
end


The friend_test method stores a block containing the test for that Pet, and the is_friend? method tests to see if a Pet will be friendly toward a particular Person.
Last, we put it all together with some simple code to display the interactions between the People and the Pets:

dog = Toto.new
bird = Tweety.new
snail = Slugworth.new

person = Dorothy.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"
puts

person = Witch.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"


The result of running this code is:

Toto is a friend of Dorothy: true
Tweety is a friend of Dorothy: true
Slugworth is a friend of Dorothy: true

Toto is a friend of Witch: false
Tweety is a friend of Witch: false
Slugworth is a friend of Witch: true

Using this simple Ruby DSL approach, it is very easy to add a new Person or Pet, just by entering the rules that define its behavior. As the objects in a system become more complex, one of the best ways to manage that complexity is to create an abstraction that hides the ugly bits.

Here is the full code for this example:

class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
self.class.instance_variables.each do |var|
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end

class Person < Animal
attr_accessor :temperament

def self.temperament(type)
@temperament = type
end

def self.food(*types_of_food)
@food ||= []
types_of_food.each do |food|
@food << food
end
end

def has_food?(type_of_food)
@food.include?(type_of_food)
end
end

class Pet < Animal
def self.friend_test(&test)
@friend_test = test
end

def is_friend?(person)
@friend_test.call(person) == true
end
end


class Toto < Pet
friend_test do |person|
true unless person.temperament == :mean
end

end

class Tweety < Pet
friend_test do |person|
person.has_food?(:sunflower_seeds)
end
end

class Slugworth < Pet
friend_test do |person|
true
end
end

class Dorothy < Person
temperament :nice
food :sunflower_seeds, :carrot_juice
end

class Witch < Person
temperament :mean
food :cheetos, :soda
end


dog = Toto.new
bird = Tweety.new
snail = Slugworth.new

person = Dorothy.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"
puts

person = Witch.new
puts "#{dog.class.name} is a friend of #{person.class.name}: #{dog.is_friend?(person)}"
puts "#{bird.class.name} is a friend of #{person.class.name}: #{bird.is_friend?(person)}"
puts "#{snail.class.name} is a friend of #{person.class.name}: #{snail.is_friend?(person)}"

The Planning Game Vs. The Crying Game

James Shore just posted a very cool chapterette from his upcoming book on agile development called "The Planning Game". The concept simply enough is that customers and developers work together to plan what features are going to be implemented, and in what order. Customers know what features have the most value to the business, so they get to choose the order in which features are developed. Developers know about the costs, so they get to say how long something is going to take.
In the Planning Game, the play is not quite so simple as the description above might suggest. As each team discusses a feature from their perspective (cost vs. value), the requirements for that feature can come into clearer focus, or be negotiated to reduce their cost.
More often, what I have experienced is the "Crying Game": whoever cries the loudest gets their way. The outcome of the Crying Game is not a good one. Either arbitrary and unrealistic deadlines are set by customers, or the wrong solution is provided by the developers. The crying doesn't end there; everyone is crying later as the recriminations fly back and forth. The moral of the story is that internal cooperation yields a lot more business value than internal competition.

Saturday, November 04, 2006

Ruby Domain Specific Languages - The Basics (Part 1)


I have been working on a prototype of a Ruby domain specific language for one of my clients, a very large financial services company. I have learned a whole bunch of really interesting lessons, which I will share over a short series of posts as I make more progress.

The first thing I tried to do was create a basic bit of DSL tastiness like this:


class Dog < Animal
number_of_legs 4
end

class Bird < Animal
number_of_legs 2
end

class Snail < Animal
number_of_legs 0
end



My first implementation of the Animal class looked like this:


class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end
end




Just looking at this bit of code, it seems like it should work. However, when trying this, it doesn't work as expected.


pet = Dog.new
p pet.number_of_legs # prints nil




In Ruby EVERYTHING is an object. This includes the class objects themselves, not just the instances of class objects! This means that when the number_of_legs method is called, it is actually being called before the actual instance object itself has been created. We need to get to our instance variable, and one way is to copy the class-level instance variable to the instance itself when the actual instance is being initialized like this:


class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
instance_variable_set("@number_of_legs", self.class.instance_variable_get("@number_of_legs"))
end
end


Now the class works as expected:


pet = Dog.new
p pet.number_of_legs # prints 4




As you add new things to your DSL, having to copy each variable manually is boring. The final change is to copy every class instance variable automatically at initialization, as follows:


class Animal
attr_accessor :number_of_legs

def self.number_of_legs(number_of_legs)
@number_of_legs = number_of_legs
end

def initialize
self.class.instance_variables.each do var
instance_variable_set(var, self.class.instance_variable_get(var))
end
end
end


This is a lot cleaner, and is much more maintainable code.

Thursday, November 02, 2006

Gmail For Mobile Rocks


I just installed the brand new Gmail for Mobile on my Motorola RAZR. In just a matter of a couple moments, I was looking at my Gmail inbox! Gmail for Mobile is a Java-applet that runs on your Java enabled phone. Keeping the network traffic down this way is a lot better option that a WAP-based email solution, which is what I had tried and abandoned previously.


Not having a QWERTY keyboard is a big limitation for smartphones especially where something heavily textual like email is concerned. Gmail for Mobile deals with this thru a clever mapping of hotkeys to the most commonly used functions (delete, in my case).

Between Google Reader, and now this Gmail for Mobile, another bit of my online existence has been sucked into the Googlesphere...and I like it!