Archive for the ‘Geeking’ Category

Diff / Patch and Eclipse

Tuesday, November 27th, 2007

In a typical opensource fashion, I receive patches for IzPack.

I always review them carefuly, then I try to apply them on the latest source code tree. I am using either the BSD or the GNU implementation of patch.

For whatever reason, I can never apply the patches using these tools if they have been generated by Eclipse… The only way to merge is to launch Eclipse and apply the patch from there.

I haven’t yet managed to figure out why these patches cannot be applied using BSD or GNU patch. They really look like normal unified-style diff output…

Any idea?

MySQL insanity

Thursday, October 25th, 2007

MySQL is going to integrate some code from Google customizations. That is extremely good and healthy, however I came across a paragraph that made me wonder if MySQL will ever stop being insane at times…

Oracle having acquired the vendor of MySQL main data storage subsystem (InnoDB), the company decided to write a new one called Falcon. This is a safe move as it could potentially threaten MySQL if Oracle decided not to play nice anymore regarding InnoDB.

However… read this:

Falcon will do crash recovery and roll-back operations faster than InnoDB because they are done from main memory, Schumacher said, but some InnoDB features, like foreign key support and full-text indexing, won’t be supported until MySQL 6.1.

Come on! How can you pretend making an enterprise-grade RDBMS and not support foreign keys? Just remember that MySQL only started to support them in version 5… I think I’ll never understand why MySQL is so bitchy about foreign keys while any other RDBMS just provides it (PostgreSQL, Firebird or Derby just do it right).

If you don’t have basic referential integrity, then please don’t call it a RDBMS: just call it a “table-based database” with SQL support.

Rails-style Ruby meta-programming

Monday, October 15th, 2007

I am giving a Ruby lecture tomorrow (some students happen to be quite lucky in fact). I wanted to present an example of a Ruby On Rails style meta programming technique. For example you can have a find_by_name or find_by_email method on your ActiveRecord objects. Those methods are in fact generated on the fly using a technique which looks like what follows. This has probably been explained a million times somewhere else on the web, but I don’t care ;-)

So let’s start with a very basic contacts book class which looks like:

class ContactBook
  def initialize
    @contacts = Hash.new
  end
 
  def add_contact(name, email)
    @contacts[name] = email
  end
 
  def contact_named(name)
    @contacts[name]
  end
end
 
book = ContactBook.new
book.add_contact "Pierre", "pierre@zzland.fr"
book.add_contact "Julien",  "julien@zzland.fr"
book.add_contact "Yoan",   "yoan@zzland.fr"
book.add_contact "Mr Bean", "info@mrbean.com"

Nothing impressive here, so now let’s get all the contacts whose email contain a given substring:

class ContactBook
  def email_containing(str)
    @contacts.select { |key, value| value.include? str }
  end
end
 
def display_contact(contact)
  puts "#{contact[0]} <#{contact[1]}>"
end
 
zzland = book.email_containing "zzland"
zzland.each { |contact| display_contact(contact) }

But what if we could have email_thestringtolookfor methods instead of this? Let’s do it by evaluating some code on the fly:

class ContactBook
  def method_missing(id, *args)
    method_name = id.to_s
    if method_name[0..5] == 'email_'
      str = method_name[6..method_name.length]
      to_eval = <<-END_FUNC
        def email_#{str}
          @contacts.select { |key, value| value.include? "#{str}" }
        end
      END_FUNC
      instance_eval to_eval
      return eval("self.email_#{str}")
    end
  end
end
 
zzland = book.email_zzland
bean  = book.email_bean
zzland.each { |contact| display_contact(contact) }
puts "-----"
bean.each { |contact| display_contact(contact) }
  1. method_missing is invoked whenever a message is sent to the class instance, but no matching method name can be found.
  2. If the name starts with email_, then we are in luck! (note that I should throw an exception if the name doesn’t start with this to comply with the Ruby semantics, but I was too lazy for that)
  3. We generate a new method for the instance through evaluation.
  4. We do not forget to invoke the new method through evaluation, as the original call would return nil since the method had not been found.

Nice isn’t it? :-)

Ruby fun with Rinda

Thursday, October 11th, 2007

Today I had fun playing with Rinda, the Ruby implementation of the Linda distributed process coordination paradigm. I also had some time for blogging, something that I haven’t done for a few days because of too much work (and there still a bunch left to be done :-) )

I won’t go through the theory behind Linda, but the gross idea is to use a shared memory space that implements the distributed blackboard paradigm : the Tuple Space. It can be summarized on the following figure:

tuplespace.png

Data is represented as sets of tuples which often have a limited lifetime. The tuple space provides the distributed processes the following primitives:

  • write: writes a tuple to the tuple space
  • read: reads a tuple from the tuple space
  • take: reads and removes a tuple from the tuple space

The beauty of the model lies in the fact that the tuple space guarantees atomic operations and periodically cleans up old tuples. Also, reading operations match a tuple on:

  1. the length of the requested and available tuples
  2. the matching (exact value, regular expressions, …) of certain elements of the tuple.

I have put together a first Ruby program that reads text from the console, and writes tuples whenever a line is entered. The other program takes every new tuple that is emitted.

emitter.rb

#!/usr/bin/env ruby
 
require 'drb/drb'
require 'rinda/ring'
require 'rinda/tuplespace'
 
DRb.start_service
 
tuple_space = Rinda::TupleSpace.new
ring_server = Rinda::RingServer.new tuple_space
 
while true
  tuple_space.write [:message, gets]
end

receiver.rb

#!/usr/bin/env ruby
 
require 'drb/drb'
require 'rinda/ring'
require 'rinda/tuplespace'
 
DRb.start_service
 
tuple_space = Rinda::RingFinger.primary
 
while true
  puts tuple_space.take([:message, nil])[1]
end

What I really like is the simplicity of the code, thanks to the cleanness of Linda and the elegance of Ruby :-) The other thing is that DRb is such a straightforward way to use distributed objects in Ruby…

BTW there is a Java implementation of this paradigm called JavaSpaces.

The Joy of C++ Templates Metaprogramming

Sunday, September 9th, 2007

I am in charge (with 2 fellow snipers) of a lecture about Advanced Programming. This includes the C++ standard library and we will probably include some stuff regarding dynamic languages (how they work, functional-style features like closures or continuations, and so on). This morning, I had a look at C++ templates metaprogramming.

In fact, not that many people know about C++ templates metaprogramming. It has many funny use-cases, including loops unrolling and performing computations at compile-time rather than at runtime. It is also at the heart of many parts of the STL and libraries such as the Boost ones.

I would not use it for everything as it is quite a tricky way of writing programs. In fact, it either compiles fine, or you most probably get errors and warnings that you just can’t understand at all :-)

Here is an example that I wrote this morning:

#include<iostream>
 
using namespace std;
 
template<int N> struct Fibo
{
  static const unsigned long long
    value = Fibo<N - 1>::value + Fibo<N -2>::value;
};
 
template<> struct Fibo<1>
{
  static const unsigned long long value = 1;
};
 
template<> struct Fibo<0>
{
  static const unsigned long long value = 0;
};
 
template<int N> void unroll_fibo()
{
  unroll_fibo<N - 1>();
  cout << Fibo<N>::value << endl;
}
 
template<> void unroll_fibo<0>()
{
  cout << Fibo<0>::value << endl;
}
 
int main()
{
  unroll_fibo<60L>();
  return 0;
}

It computes the Fibonacci number. In fact when you run it, you will get the Fibonacci numbers from 0 to 60 instantly! It leverages the two techniques mentionned above: loops unrolling and compile-time computations.

By constrast, the following is a more traditional way of computing the Fibonacci numbers… and the execution time is not even comparable (it has not finished after 3 minutes on my G4 processor).

#include <iostream>
 
using namespace std;
 
long long fibo(const long long &n)
{
  if (n == 0L)
  {
    return 0L;
  }
  else if (n == 1L)
  {
    return 1L;
  }
  else
  {
    return fibo(n - 1) + fibo(n - 2);
  }
}
 
void display_fibo(const int &max)
{
  for (int i = 0; i <= max; ++i)
  {
    cout << fibo((long long) i) << endl;
  }
}
 
int main()
{
  display_fibo(60);
  return 0;
}

Funny isn’t it? ;-)