Archive for the ‘Programming’ Category
Capistrano 2 on Site5
Posted by Giovanni Intini | Filed under Capistrano, Programming, Rails, Ruby, Site5
I finally took the time to browse the capistrano 2 sources, and after reaching enlightenment I was able to write a deploy.rb file (yes I still use capify + deploy.rb instead of Capfile) that works really fine and really sweet on Site5.
Without further ado, I introduce you to deploy.rb extreme Site5 version
# Necessary to run on Site5 set :use_sudo, false set :group_writable, false # Less releases, less space wasted set :keep_releases, 2 # The mandatory stuff set :application, "YOUR_APP_NAME" set :user, "SSH_USERNAME" set :repository, "URL_FOR_YOUR_REPOSITORY" # SCM information set :scm_username, "SCM_USERNAME" set :scm_password, Proc.new { CLI.password_prompt "SVN Password: "} # This is related to site5 too. set :deploy_to, "/home/#{user}/apps/#{application}" role :app, "SERVERNAME" role :web, "SERVERNAME" role :db, "SERVERNAME", :primary => true # In the deploy namespace we override some default tasks and we define # the site5 namespace. namespace :deploy do desc <<-DESC Deploys and starts a `cold' application. This is useful if you have not \ deployed your application before, or if your application is (for some \ other reason) not currently running. It will deploy the code, run any \ pending migrations, and then instead of invoking `deploy:restart', it will \ invoke `deploy:start' to fire up the application servers. DESC # NOTE: we kill public_html so be sure to have a backup or be ok with this application # being the default app for the domain. task :cold do update site5::link_public_html site5::kill_dispatch_fcgi end desc <<-DESC Site5 version of restart task. DESC task :restart do site5::kill_dispatch_fcgi end namespace :site5 do desc <<-DESC Links public_html to current_release/public DESC task :link_public_html do run "cd /home/#{user}; rm -rf public_html; ln -s #{current_path}/public ./public_html" end desc <<-DESC Kills Ruby instances on Site5 DESC task :kill_dispatch_fcgi do run "skill -u #{user} -c ruby" end end end
May your deploys be merry and bright and I wish you all your applications be white
VBLiteUnit saved my life
Posted by Giovanni Intini | Filed under Programming, Testing, VBA
I want to personally thank the guys at VBLiteUnit. Without their unit testing framework I wouldn’t have been able to catch and squash a bug in a vba product I coded for a client some time ago.
The bug was stupid but difficult to catch because it altered a few record every ten or so in a long query that is used to pay people, so some people were getting double pay! Good for them but not for my client
I had never done testing in vba before so I started to write my own testing routines, then I decided to check google again for free testing frameworks for vba and found VBLiteUnit.
62 asserts later the bug was found and killed without any remorse whatsoever
The Chuck Norris Ruby Class
Posted by Giovanni Intini | Filed under Chuck Norris, Fun, Programming, Random Stuff, Ruby
Yesterday morning I didn’t feel like doing any real work, so I coded a Chuck Norris Ruby Class. Please feel free to edit the wiki and add features/bugfixes to it
Amazon S3, Ruby, and the failing tests
Posted by Giovanni Intini | Filed under AmazonS3, Programming, Ruby
A friend of mine, Jeko, introduced me to Amazon S3, praising the Ruby support, and the ease of use. So when Gabriele Renzi suggested me a potential wonderful use for S3 (still secret, sorry) I decided to give it a try and downloaded the Ruby sample libraries.
Unfortunately all the tests were failing, and that made me unhappy. What made it strange was that the first time I ran the tests I two errors, and the second time I ran them the first error was replaced by another one.
I dag into the code and found a simple but effective fix for all the problems.
The first-error-replacement was caused by a non emptying of the test Bucket after the tests failed. I edited the setup method in the test suite to look like this:
def setup @conn = S3::AWSAuthConnection.new(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) @conn.list_bucket(BUCKET_NAME).entries.each do |object| @conn.delete(BUCKET_NAME, object.key) end @conn.delete_bucket(BUCKET_NAME) end
Now I kept getting the same error but it was an easy fix: edit line 534 of S3.rb to look like this:
@properties.name = @curr_text.strip
With this two fixes the test suite runs correctly (I can’t certify its validity though
). After a succesful test run you can remove the fixes to the setup method, because it keeps working fine, but I would leave them untouched, you never know if there’s a problem in a test
Cookies in Ruby on Rails. You can’t store Arrays in there
Posted by Giovanni Intini | Filed under Programming, Ruby, Ruby on Rails
Yesterday I decide to implement a simple feature in iccfriends that allow people to track who is already their friend, but I didn’t want to use the db so I opted for local storage and went with a cookie.
I read the rails docs about the cookies method and decided to give it a try with this code:
def foo if cookies[:friends].blank? cookies[:friends] = [params[:id]] else cookies[:friends] = cookies[:friends] << params[:id] end end
It seemed to work correctly but the Array was converted to a String before going in the cookie. This is where my cookie ignorance showed as I tried again and again to store an Array in it, to no avail.
After googling around for a little while I discovered there was no way I could store an object in the cookie without some sort of serialization, so I had to use good old Array#join and String#split.
def bar_write if cookies[:friends].blank? cookies[:friends] = params[:id] else cookies[:friends] = cookies[:friends] << ",#{params[:id]}" end end def bar_read @var = cookies[:friends] ? cookies[:friends].split(",") || [] end
Why we need to stop designing and start delivering
Posted by Giovanni Intini | Filed under Business, Nimboo, Productivity, Programming, Ruby on Rails
Lately I’ve been very unproductive. Lost in business discussions and dreaming about the next big thing, I couldn’t finish two paid projects, and that sucks™.
The invisible shackles that didn’t allow me to finish those jobs have been holding me back so that I wasn’t able to do any real work even on personal projects.
I’ve tried finding the cause for this, blaming my lack of self discipline or the fact that I was not doing GTD as strictly as I was six months ago, but I knew there had to be something else, and the whole situation was getting on my nerves.
Last week I bought a game for the Nintendo Wii, Mario Strikers Charged, and while playing I remembered a pet project I started more than an year ago and never completed.
The project name was ICCFriends, a repository of Nintendo Friend Codes for the usenet it.comp.console community.
This time I had to finish it, so I went and looked through my code: awful. There was as much BDUF in there as in Windows Vista, and while wandering through the models and controllers, suddenly I got it!
I knew why I wasn’t delivering: I was designing things that were not useful. I lost so much time preparing for refactoring, or moving code around or laying the ground for future extractions or features that when the time came to implement the real thing I grew tired or got bored.
I then did the only thing I could possibly do to complete ICCFriends:
$ rm -rf ~/src/iccfriends $ rails ~/src/iccfriends
I then focused on the simplest and shortest set of features I could imagine and in a couple of hours ICCFriends.net was up and running, and with more interesting features than those I was bduffing.
It looks rushed out because it is, but once again I was able to think and deliver and the rush of energies that came with it is a nice feeling I really missed.
Yesterday I learnt an important lesson, and from now on I will always strip my feature list before even start thinking about the implementation.
The battle of the languages part II
Posted by Giovanni Intini | Filed under Java, Javascript, Lua, PHP, Programming, Ruby
My previous post about a programming contest I had with my friends was wildly popular. Much much more than I even thought possible.
I started with a simple comparison of PHP, C, Ruby, Erlang and Javascript and ended up with lots of comments where people posted interesting implementations in more and more languages, even obscure ones (to me) like Haskell and Ocaml.
I owe everyone a fairer benchmark so I will do the test again, this time testing the following languages:
- C
- Common Lisp
- Erlang
- Haskell
- Javascript
- Java
- Ocaml
- Perl
- PHP
- Python
- Ruby
I need submissions for most of these languages, and I actually am quite open to submissions for the languages I speak
The rules are simple, the program has to store the results in an array (not just count them) and has to run without any strange libraries or compilers or compiler switches. To avoid interpreter starting time problems, please submit programs that autotime themselves.
As usual we’ll find the pythagorean triplets up to 5000. The reference implementation is the following, in Ruby:
t = Time.now result = [] 2.upto(5000) do |c| 1.upto(c-1) do |b| a = Math.sqrt(c*c - b*b) result << [a.to_i, b, c] if a.to_i == a end end puts Time.now - t
This code takes 15.70s to run on my macbook pro.
Now it’s your turn!
Update: Lua version by Sindisil
local tt = os.clock() local result = {} local c for c = 2, 5000 do local b for b = 1, c-1 do local a = math.sqrt(c*c - b*b) if a == math.floor(a) then result[#result+1] = { a, b, c } end end end print(os.clock() - tt)
It takes 5.48s to run on my box.
Update: new Ruby version.
include Math a, b, c = 0 result = [] 2.upto(5000) do |c| d = c * c 1.upto(c-1) do |b| a = sqrt(d - b*b) result << [a.floor, b, c] if a.floor == a end end puts Process.times[0]
Following Gabriele Renzi’s suggestions we now have a faster ruby version: 12.30s
Update: faster Lua version from Chris Swetenham, it runs in 3.44s
local tt = os.clock() local result = {} local c local n = 1 local math = math local sqrt = math.sqrt local floor = math.floor for c = 2, 5000 do local b for b = 1, c-1 do local a = sqrt(c*c - b*b) if a == floor(a) then result[n] = { a, b, c } n = n + 1 end end end print(os.clock() - tt)
Update: PHP version by Fullo
<?php $start = microtime(true); $a = $b = $c = 0; $result = array(); for ($c = 2; $c <= 5000; $c++) { for ($b = 1; $b < $c; $b++) { $a = sqrt($c*$c - $b*$b); if (intval($a) == $a) $result[] = array($a,$b,$c); } } echo (microtime(true) - $start); ?>
It runs in 9.73s.
Update: Python version from ludo, it runs in 11.2s
from time import clock start = clock() from math import sqrt results = [] for c in xrange(2, 5001): d = c * c for b in xrange(1, c): a = sqrt(d - b * b) if a % 1 == 0.0: results.append((a, b, c)) print clock() - start
The results for now:
- Lua 3.44
- PHP 9.73
- Python 11.20
- Ruby 12.30
Transaction in Rails
Posted by Giovanni Intini | Filed under Nimboo, Programming, Ruby, Ruby on Rails
In an application I wrote for a client I needed transactions to handle a batch import of records from a legacy table into different models.
I browsed the documentation, googled for info and even asked in #rubyonrails, but wasn’t able to get any help, so I had to resort to good old trial and error.
First I tried nested transactions (the old way):
FirstModel.transaction do SecondModel.transaction do ThirdModel.transaction do FourthModel.transaction do fourth.do_stuff third.save second.handle_your_stuff first.good_old_foo_bar end end end end
I had a couple of problems with this code:
- Ugly
- Deprecated
It also didn’t seem to work for me, so I banged my head against my laptop for half a hour or so and suddenly the rails documentation started to make sense, so I wrote this code instead:
transaction do first.save! second.save! third.save! fourth.save! end
The reason I used save! was that the documentation says that a transaction block catches exceptions. Unfortunately that’s not true and to make it work I had to remove the exclamation marks.
Now I had another problem. I included the transaction code in a class I put in lib/, ImportJob, and I was using it with script/runner:
script/runner 'ImportJob.run' -e ENVIRONMENT
All of a sudden I started getting method missing errors on transaction. Now I could investigate and do the right thing or just hack a solution – I decided to hack a solution
class ImportJob < ActiveRecord::Migration end
Deriving ImportJob from Migration solved my problems. Now if anyone has a cleaner solution I will be happy to implement it but at least I solved my problem with transactions (and I hope this will be helpful for someone else too).
Update: Tim pointed out some flaws in my code and some more testing revealed that I needed to have an exception to trigger a Rollback, so I modified the block:
begin transaction do first.save! second.save! third.save! fourth.save! end rescue ActiveRecord::RecordInvalid => invalid # do whatever you wish to warn the user, or log something end
This works fine, thanks Tim!
Erlang, Ruby and PHP battle it out!
Posted by Giovanni Intini | Filed under Erlang, Javascript, PHP, Programming, Ruby
Update: here’s the followup!
Yesterday I attended PHP Day, in the beautiful city of Verona, and while going there by train, together with my friend Federico Feroldi, I told him that in a test I made a week ago Erlang was much slower than ruby in finding pythagorean triplets.
That was a partial lie, since the ruby implementation was somewhat optimized, while the erlang implementation wasn’t at all. So we decided to rewrite both programs using the same optimized algorithm and then test their speeds.
This is the ruby implementation of a method that counts the number of pythagorean triplets up to N:
def pythag(n) result = [] (2..n).each do |c| (1...c).each do |b| a = Math.sqrt(c*c - b*b) result << [a.to_i, b, c] if a.to_i == a end end result end
Then we coded it in Erlang. The code I’m going to show you is more complex than the ruby code because we took advantage of the parallelization features of the Erlang language:
-module(pythag). -export([bard/1, pbard/1]). my_is_integer(X) -> round(X) == X. pbard(N) -> pmap(fun(C) -> [ {C, B, trunc(A)} || B <- lists:seq(C, N), A <- [math:sqrt(C*C + B*B)], my_is_integer(A) ] end, lists:seq(2, N)). bard(N) -> lists:map(fun(C) -> [ {C, B, trunc(A)} || B <- lists:seq(C, N), A <- [math:sqrt(C*C + B*B)], my_is_integer(A) ] end, lists:seq(2, N)). pmap(F, L) -> S = self(), %% make_ref() returns a unique reference %% we'll match on this later Ref = erlang:make_ref(), Pids = lists:map(fun(I) -> spawn(fun() -> do_f(S, Ref, F, I) end) end, L), %% gather the results gather(Pids, Ref). do_f(Parent, Ref, F, I) -> Parent ! {self(), Ref, (catch F(I))}. gather([Pid|T], Ref) -> receive {Pid, Ref, Ret} -> [Ret|gather(T, Ref)] end; gather([], _) -> [].
The pythag function has been named bard, as in The Bard
The pbard function fires up a thread for each iteration of the outer loop and then gathers all the result back. This allows for up to 50% performance increase when using dual core CPUs (like my Macbook Pro
).
Once we coded it in two languages we couldn’t stop, so here’s a PHP implementation, a Javascript one and, last, but not least, a C implementation, because you can never forget C when you need speed
PHP:
<?php $i=0; for ($c = 2; $c <= 5000; $c++) { for ($b = 1; $b < $c; $b++) { $a = sqrt($c*$c - $b*$b); if (is_int($a)) { $i++; } } } print("$i"); ?>
JavaScript:
function pythag(n) { var a,b,c,i for (c = 2; c <= n; c++) { for (b = 1; b < c; b++) { a = Math.sqrt(c*c - b*b); if (Math.floor(a) == a) { i++; } } } return i; }
C:
#include <stdio.h> #include <math.h> #define MAX 5000 int main() { double c, b; int i = 0; double a; for (c = 2; c <= MAX; c++) { for (b = 1; b < c; b++) { a = sqrt(c*c - b*b); if (trunc(a) == a) { i++; } } } printf("%d\n", i); }
To test the various relative speeds I ran them from the shell using time (php ruby and c), or used the internal timer (erlang), or ran them in firefox (js only actually).
The results were interesting. At the first run, using 5000 as N in the pythag functions the order was:
- C (obviously): 0.40s
- Erlang (smp): 3.95s
- Erlang (non-smp): 5.66s
- Ruby: 15.31s
- PHP: 19s (or so)
- Javascript: couldn’t even finish running because firefox said it was taking too much time
Fullo passed by and asked what we were doing, I told him I was testing languages and that PHP was dog-slow. He said it couldn’t be and asked me what version of PHP I was using. I checked and it was PHP 4.x.x.
After downloading and compiling PHP5 I ran the tests again and the final result was this:
- C (obviously): 0.40s
- Erlang (smp): 3.95s
- Erlang (non-smp): 5.66s
- PHP5: 8.9s (or so)
- Ruby: 15.31s
- Javascript: couldn’t even finish running because firefox said it was taking too much time
Now the numbers make sense. Doing these comparations was a nice experience, because when you implement the same thing in different languages you always learn something about optimization and code beauty.
A praise for jQuery
Posted by Giovanni Intini | Filed under Ajax, Javascript, jQuery, Programming
I’ve been doing some drupal development lately, and had to make the switch from Prototype to jQuery (by the way it’s the same switch WordPress made in 2.2).
At first I had to learn the different approach jQuery has to manipulating the DOM, but once I got the hang of it I really started appreciating jQuery.
The main difference I’ve found is that I prefer programming Prototype via the Rails helpers, while programming jQuery is so fun I prefer to do it directly in JavaScript.
Actually it turned out so fun that I keep adding content to pages and changes links in JS, while I should do that in the backend.
Here’s an example, from a drupal module I wrote:
$(document).ready(function() { $('#comments h2').after('<p class="slider"><a href="#" class="slide-open">Espandi tutti i commenti</a> - <a href="#" class="slide-close">Contrai tutti i commenti</a></p>'); $('.comment .expand').html("[+]"); $('.comment .content').hide(); $('.comment h3').click(function() { $(this).siblings('.content').slideToggle(); if ($(this).children('.expand').html() == "[-]") { $(this).children('.expand').html("[+]"); } else { $(this).children('.expand').html("[-]"); } return false; }); $('#comments .slider .slide-open').click(function() { $('.content').show(); $('.comment .expand').html("[-]"); return false; }); $('#comments .slider .slide-close').click(function() { $('.content').hide(); $('.comment .expand').html("[+]"); return false; }); })
What does this code do? Add a couple of links after the comments heading, hide all the comments and add a slidedown/up functionality to them.
The best thing of adding this functionality in the frontend is that when the user has js disabled or is using a non-js browser the site falls back to the normal behavior.