Sunday, November 12, 2006

Ubuntu Edgy 6.10 on Powerbook G4 (general)

Recently I had to install a GNU/Linux system on my notebook. Mywork-group is heavily Linux-based and the software which I'm going touse/extend for my thesis at the moment compiles only on Linux (andprobably on BSD, however, not on MacOS X). Although it's a Prologsoftware some parts are written in C++ and I haven't had time to makeit work on MacOS X. Modifications are quite trivial (it's a matter ofbuilding a dylib). However, I should port the build system to libtoolto make it work on both platforms.

So I decided to install a GNU/Linux distribution. My first choice was Fedora. I'm not particularly fond of RH little sister, but that is the first choice in my team. The PPC version quite sucks. It's not that things do not work: simply it seems just a bit more than a recompilation of the x86 version. For example package pbbuttons (that makes multimedia keys of my pb work, wasn't even on the repositories). It's not that I particularly want to have the buttons working: it is like those who built it never used it. I mean no one ever tried to use it on a notebook? Moreover, it's painfully slow. Six minutes to boot. To start some applications (Emacs, the gnome 'quick' disc burner, etc) it takes minutes. This does not happen on the x86 version.

Partitioning

So I tried Ubuntu 6.10. It's heaven. Everything worked without my intervention. Well, almost everything.

The live CD did not recognize properly my screen. It thought it was a 20000x30000 pixel screen (and of course that was *wrong*): I just had to fix that manually. After booting the live CD, I started the installation. Everything went quite smoothly. Details in next posts

Monday, November 6, 2006

ssh-copy-id

I develop a lot on unix remote machines. I have CVS/SVN accounts and shell access. In fact it's quite tedious to retype the password everytime.
For this reason I started using ssh keys to automate this project. You find a lot of tutorials and informations on this subject, I won't spend more time on this. Basically you have to generate the key and then you have to upload it with scp or similar on the remote machine. However, I find scp syntax quite boring to type... :P
There is a nifty script that does the job for you. You call something like (with you correct remote credentials), it asks you password and you're done.
ssh-copy-id -i ~/.ssh/id_rsa.pub rik0@shell.berlios.de
This script is not in my open-ssh distribution and I had to find it on CVS. The direct download is . However, the script may be upgraded. So if you read this post after some time it has been posted, you may want to find a newer version.

Sunday, November 5, 2006

Cazzeggio (Which file extension are you?)

ogg-2006-11-5-19-21.jpg Which File Extension are You?
You are .ogg Even though many people consider you cool and happening, a lot still find that you're a bit too weird to hang out with.

Agile software development

In some sense I've always done agile programming. I've been in the Python community for a while, and a lot of agile practices are very common. I've done a lot unit testing (even if not really before coding but just afterwards) since the very first years as a developer.

In fact, it was even before my Cocoa and ObjectiveC studies that I learnt about patterns and how to use them. In fact patterns are well known in the ObjectiveC community even among newbie programmers, for exampl Anguish, Buck and Yacktman describes Cocoa showing which patterns are used in the framework and how their names differ from the classical GOF ones.

Of course this is not enough to say "Agile Development": I only had some practices in common with some (most) agile developement methods. I also find quite natural to use tests and code to learn instead of documentation (that is quite common for a lot of open source libraries). What I missed was a theoretical mind-framework.

In some software engineering courses I was introduced to UP. And in fact I could not believe that some people are convinced that it could work well (I agree that you may make it work, however, I think it's a suboptimal way to develop). It is like freezing insects in order to take pictures of them. While frozen, they stand still and are easier to photograph: however, if you want to photograph insects in the wild this just doesn't happen to work.

Some of my concerns were also due to Java and to the quantity of code that is not part of the problem but needs to be written for the way Java works. Python leans quite naturally towards agility: the way components interact, the way you can change things and refactor (even without complex refactoring tools like Eclipse).

After some time I discovered Ruby and got in touch with the Ruby community and all the hype about agile programming.

Eventually, I decided to buy Kent Beck's book on Extreme Programming. However, I wanted a technical book about agile programming. I bought Martin's Agile Software Development

I love them both and I will talk about Beck's book another time.

Agile Software Development is a very interesting book. There is plenty of information on agile techniques, and even if you are not a Java developer (which in some sense is my case, since I rarely work in Java) there are lots of interesting stuff.

You learn how to use test driven development and to think using TDD (there is a big difference between writing tests and thinking in a 'test oriented way'). You learn how to design interfaces while writing tests, and there are examples on software evolution driven by tests.

You definitely have to read the sources (that are really readable and easy to understand): while the explanation is great, the sources would be enough by themselves.

The book also offers a clear explanation of classical principles of object oriented software design (OCP, SRP, LSP, DIP) and packaging (ADP, SDP, SAP). So, you may want to buy this book even if you are not into agile programming and are only interested in a book about Object Oriented software development.

Saturday, November 4, 2006

Closures in Java

This is a hint abount implementing closures in Java. Of course, if you want to do it in an acceptable way, you would create a custom interface that Does The Right Thing™, something like (semi pseudocode)
interface Closure {
    public Object foo(Object bar);
}
However, you can get some ideas from the sequent code

public classStateModifierextendsObject{
    protectedString x ;
    
    public StateModifier() {
        x = "foo";
    }
    
    public ThreadgetThread() {
        finalString y = "yy";
        Thread t = newThread() {
            public voidrun(){
                x = "boo"+ y;
            }
        };
        return t;
    }
    
    public static voidmain(String[] args) {
        StateModifier sm = newStateModifier();
        Thread t1 = sm.getThread();
        System.out.println(sm.x);
        t1.start();
        try {
            t1.join();
        } catch (Exception e){
            // ...
        }
        System.out.println(sm.x);
        System.exit(0);
    }
}

Wednesday, October 25, 2006

Niceboxes (latex)

This nice sty comes from an example I found on the web. The code is not mine. However, I wasn't able to find again the original code (and the original author) to give credit. There may be some small modifications I made: if it does not work, it's likely it's my fault.
You can define things like
\usepackage{niceboxes}
\newenvironment{definition}[1][Definition]{
\par
\SpecialEnv{#1}{LightSlateGrey}{Lavender}{LightSlateGrey}{}%
}{%
\endSpecialEnv
}
Of course you need to have imported xcolors if you want to call colors by name (like LightSlateGrey)

Latex Companion

And eventually from Amazon arrived the Latex Companion...

I leafed through it and have to say it seems a wonderful book. There's plenty of information (in my opinion more than other book on Latex like the "Guide to latex" or Lamport's book -- that seems more suited to a beginner latex user).

In fact I was spending too much time on the web to look for information on intermediate or advanced tasks, and I was also thinking to abandon latex in favor of something else (by the way, I didn't find a true candidate, a part from docbook). Thanks to Andrea Bergia (I didn't find his proper blog/website) for pointing me the listings package that solving one of my immediate problems made me understand that it wasn't latex not being suited for what I had to do: it was me who needed to learn more latex.

Monday, September 11, 2006

Rails: Loading fixtures to development with a specified order

Background
My development style is heavily test driven. One of the very first things I do write are fixtures, in order to write tests on them. For this reason the very first database I use in a Rails projects is the test database, rather than the development one.
When I have to populate the development db, I already have plenty of fixtures: if they aren't enough to try the user interface (that is what is left to do), they weren't enough to test the models and the controllers.
Of course this should be no problem, there is the rake task db:load:fixtures that plays well with this kind of issues. However, I tend to use db constraints rules such as
ALTER TABLE bars ADD FOREIGN KEY(`foo_id`)  REFERENCES foos  (`id`) ON DELETE CASCADE;
if you use MySQL or
ALTER TABLE bars ADD CONSTRAINT valid_foo FOREIGN KEY (foo_id) REFERENCES foos (id) MATCH FULL;
if you use Postgres.
Solution
Of course, in this case you can't load fixtures in any order and you must supply correct fixtures loading order.
After some searching I found this solution.
However, it does not work. In fact it builds a Hash inserting fixture names in the specified order, than builds an array with other fixtures that had not been specified as needing some particular order.
Eventually, it sums the keys of the hash and the array, and loads fixtures in this order. I don't understand how the poster got this code working, since Ruby Hashes are not ordered in any way and the documentation explicitly says that iterators and methods return values in arbitrary order and do not rely on insertion order.
This meant I had to change the code. Now it uses arrays everywhere (which seems the most reasonable thing to do, since this rake task it's about order). I also added namespaces.
You still have to define something like

ENV["FIXTURE_ORDER"] = 
    %w( entities interaction_sources interaction_devices 
        payments interactions accounts employments 
        enrollments payables receivables tenures wards ).join(' ')

My code is:

require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
ENV["FIXTURE_ORDER"] ||= ""

def print_separator_line(n=80)
    puts "\n" + '='*n
end

desc "Load fixtures into #{ENV['RAILS_ENV']} database"

namespace :db do
    namespace :fixtures do
        task :load_ordered => :environment do
            require 'active_record/fixtures'
            print_separator_line
            puts "Collecting specified ordered fixtures\n"
            ordered_fixtures = ENV["FIXTURE_ORDER"].split
            fixture_files = Dir.glob(
                File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}'))
            other_fixtures = fixture_files.collect
                { |file| File.basename(file, '.*') }.reject 
                    {|fx| ordered_fixtures.include? fx }
            ActiveRecord::Base.establish_connection(ENV['RAILS_ENV'])
            all_fixtures = ordered_fixtures + other_fixtures
            print_separator_line
            puts "Fixtures will be loaded in following order\n"
            all_fixtures.each_with_index do |fx, i|
                puts "#{i+1}. #{fx}"
            end
        
            print_separator_line
            puts "Actually loading fixtures to #{ENV['RAILS_ENV']} db..."
    
            all_fixtures.each do |fixture|
                puts "Loading #{fixture}..."
                Fixtures.create_fixtures('test/fixtures',  fixture)
            end unless :environment == 'production' 
            # You really don't want to load your *fixtures* 
            # into your production database, do you?  
        end
    end
end