Corso di Project Management XP/Agile @ XP Labs

June 27th, 2007

Settimana scorsa ho seguito il “Workshop su Project Management XP e Agile” di Francesco Cirillo. Francesco è il pioniere di XP in Italia; ha fatto nascere team come quello di Quinary a Milano, quello di Unirel a Firenze, per non parlare del suo team “Bees” di Sutri. Ha imparato il mestiere da Kent Beck quando questi lavorava in Svizzera; possiamo ben dire che sia qualificato per insegnare queste cose :-)

Questo corso è stata per me una cosa impegnativa. Non si è trattato di starmene seduto mentre il docente fa girare delle slide e mi racconta delle cose; abbiamo dovuto impegnarci mentalmente ed emotivamente. Particolarmente dal punto emotivo la cosa è stata faticosa; la sensazione che maggiormente ho provato è quella di essere “ribaltato”, o “rivoltato come un calzino”. A un certo punto ho avuto l’impressione che mi si aprissero delle prospettive, in varie direzioni, sulla vastità delle cose che non so :-) Il che non dovrebbe stupirmi; tutto quello che ho studiato nella mia vita è stato soprattutto l’aspetto tecnico dell’informatica. E’ da attendersi dunque che quando si parla di fare il Coach o il Manager non ne sappia molto. Però ci vuole qualcuno che sia capace di _renderti l’idea_ di tutto quello che non sai… altrimenti non ci credi veramente di avere così tanta strada davanti.

C’è stato un momento, soprattutto nel secondo giorno, in cui mi sono sentito per un poco davvero depresso. E anche Simone Genini, che era al corso con me, l’ho visto con la schiena curvata… Ma in un quarto d’ora circa l’abbiamo superato. A un certo punto cerchi dentro un’appiglio, un punto di vista per superare il momento di crisi nera. La cosa interessante è che non occorre essere grandi psicologi per rendersi conto dello stato d’animo della gente; l’espressione dice tutto. (Pascal, quando scrive sul suo blog a proposito dello XP Day che lui organizza parla sempre dell’espressione della gente: “facce sorridenti all’uscita dei workshop, espressioni concentrate quando si deve scegliere che cosa seguire…”)

Naturalmente Francesco non si è limitato a farmi toccare con mano quello che non so; mi ha dato degli strumenti per muovermi nella direzione del miglioramento. Il che è alla fine il compito più importante di un Coach: darti un idea di dove sei, e darti gli strumenti per migliorare. Non conta gran che il tuo livello in assoluto, conta essere su un cammino di miglioramento.

Maximum programmer FUN!

May 25th, 2007

Finalmente in edicola il mio articoletto introduttivo a Ruby on Rails su Linux & C.! Chiaro che non c’è nulla di sconvolgentemente nuovo, ma è conciso e in italiano. E sono particolarmente contento di pubblicare su Linux & C., perché è un’ottima rivista.

Copertina

Think first, code later

May 4th, 2007

Leggo ora una nota di Dijkstra segnalata da un post di Carlo Pescio: My recollections of operating systems design. Ci sono un paio di cose che mi sembrano molto interessanti.

Parlando del famoso algoritmo di Dekker, la prima soluzione corretta al problema della mutua esclusione, Dijkstra dice che da parecchio tempo stava sfidando i suoi colleghi perché producessero una soluzione. Quando la difficoltà di trovare gli errori nelle soluzioni proposte divenne eccessiva, D. cambiò le regole del gioco, richiedendo che insieme all’algoritmo venisse proposta anche una prova di correttezza.

And then something profound and lovely happened. By analyzing by what structure of argument the proof obligations could be met, the numerical mathematician Th.J. Dekker designed within a few hours the above solution together with its correctness argument, and this settled the contest.

L’idea della derivazione di programmi è di fare guidare la soluzione dalla dimostrazione di correttezza. E’ una cosa analoga (non equivalente! ma certamente analoga) a quello che si fa in TDD, dove si fa guidare la soluzione dai test che dimostrano empiricamente che la soluzione funziona.

Ci sono profonde differenze, è ovvio, fra “program derivation” e “TDD”. Ma ci sono anche ovvie analogie: entrambe le tecniche producono programmi molto concisi e corretti. Ed entrambe le tecniche sono molto più efficaci del code & fix, che è la maniera più comune di sviluppare.

A questo proposito D. cita un’episodio divertente:

When the design of the THE Multiprogramming System neared its completion, the University’s EL X8 was getting installed, but it had not been paid yet, and we hardly had access to it because the manufacturer had to put it to the disposal of an American software house that was supposed to write a COBOL implementation for the EL X8. They were program testing all the time, and we let it be known that if occasionally we could have the virgin machine for a few minutes, we would appreciate it. They were nice guys, and a few times per week we would get an opportunity for our next test run. We would enter the machine room with a small roll of punched paper tape, and a few minutes later we would leave the machine room with the output we wanted. I remember it vividly because when they realized what we were achieving, our minimal usage of the machine became more and more frustrating for them. I don’t think their COBOL implementation was ever completed.

Come riesco a immaginarmeli questi sfortunati programmatori… Accanirsi nel code & fix non serve se non si ha un’idea chiara di quello che si sta facendo. Va detto che nei primi anni ’60 scrivere un compilatore era un’impresa un bel po’ più difficile di oggi. Non potevano andarsi a comprare il Dragon Book, perché non era ancora stato scritto!

[Insubria] Una applicazione web per tesi

April 19th, 2007

Segnalo che Federico Gobbo ha una nuova proposta di Tesi per Laurea Triennale.

Sembra divertente. Ci sarà senz’altro la possibilità di approfondire tecnologie web agili…

Essap: get aboard

April 3rd, 2007

Anche quest’anno faremo la scuola estiva su XP e programmazione agile, la famosa Essap. E’ un’occasione unica per imparare un sacco di cose in una sola settimana. (E dico unica sul serio: trovate una scuola simile se ci riuscite. Non ce ne sono, almeno non in Europa.) L’anno scorso è stata molto istruttiva e anche divertente. E dalla Essap è nato uno User Group a Varese. So che per gli studenti è un po’ problematico prendere una settimana in giugno, nel periodo più caldo degli esami. Però credo di poter promettere che (almeno gli studenti dell’Insubria) si vedranno riconosciuti alcuni crediti, se seguono con profitto per tutta la settimana.

Come on, be a part of it: iscriviti!

Tesi su Erlang… le cose si muovono

April 3rd, 2007

La tesi su Http chat server in Erlang è partita… sono molto contento. Pare che diverse cose si stiano muovendo: i Programmatori Pragmatici stanno per pubblicare un libro su Erlang scritto da Joe Armstrong, che è uno dei principali autori del linguaggio. Fra l’altro la tesi di dottorato di Armstrong è molto leggibile (prendete esempio, o studenti!)

Il mio studente mi segnala che esiste un framework per applicazioni web per Erlang, che supporta MVC, e ovviamente Yaws, lo scalabilissimo web server in Erlang.

Who needs Java?

EL&P e D&D

March 20th, 2007

Summary: nice post on _why’s blog

Divertente come sempre, _why prende in giro un pomposo accademico che critica Ruby e la sua guida. Mi è particolarmente piaciuto questo commento di “forrest”:

Furthermore, anybody who compares the Poignant Guide to the Head First guides has failed to understand the Poignant Guide altogether. There’s no false jocosity or spoonful of sugar bullcrap to the Poignant Guide. It’s like the Hypnerotomachia Poliphili—it’s a legitimate work of art and literature as well as a programming manual. (It doesn’t talk about how cool Ruby is, really. Does it?)

Man, I don’t know why that kind of response bugs me so much. Maybe it’s because I’ve read a lot of programming lore from the 70s and 80s, when there were a lot more weirdo geek-hippies striding the plains with their 41CXs and Emerson, Lake & Palmer records, playing Dungeons & Dragons and writing arcane articles for the Whole Earth guide when they weren’t cranking out the code.

Sarà che gli ELP e D&D sono due cose che ho molto amato…

Ben detto!

March 3rd, 2007

Questo articolo “Review: Mac OS X Shines In Comparison With Windows Vista” spiega bene una cosa che mi ha sempre dato molto fastidio di Windows.

Mac OS X, it’s the classic English butler. This OS is designed to make the times you have to interact with it as quick and efficient as possible. It expects that things will work correctly and therefore sees no reason to bother you with correct operation confirmations. If you plug in a mouse, there aren’t going to be any messages to tell you “that mouse you plugged in is now working.” It’s assumed you’ll know that because you’ll be able to instantly use the mouse. Plug in a USB or FireWire hard drive and the disk showing up on your desktop is all the information you need to see that the drive has correctly mounted. It is normally only when things are not working right that you see messages from Mac OS X.

Windows is … well, Windows is very eager to tell you what’s going on. Constantly. Plug something in and you get a message. Unplug something and you get a message. If you’re on a network that’s having problems staying up, you’ll get tons of messages telling you this. It’s rather like dealing with an overexcited Boy Scout … who has a lifetime supply of chocolate-covered espresso beans. This gets particularly bad when you factor in things like the user-level implementation of Microsoft’s new security features.

To put it simply, you can work on a Mac for hours, days even, and only minimally need to directly use the OS. With Vista? The OS demands your attention, constantly.

E’ un’istanza di un tema generale: Windows tratta i suoi utenti come sudditi. “Tieni questi aggiornamenti, e sarà meglio che li installi subito!” Sono così contento di non doverlo usare quasi mai.

Soluzione esame scritto di Applicazioni Web, febbraio 2007

February 28th, 2007

Summary: solutions and rants about my Web Applications course last exam

Parziale soluzione dell’elaborato di Applicazioni Web di febbraio 2007. Lo posto nel blog perché potrebbe essere di qualche interesse per un rails-ista alle prime armi.

Esercizio 0

Si scriva un template rhtml per visualizzare una tabella di oggetti contenuti nell’array @objects. Non sappiamo in anticipo quali saranno tutti gli attributi degli elementi di @objects; sappiamo per certo che ci sarà un attributo “name” e un attributo “image_url”. Il nome degli altri attributi si trova nell’array @other_columns. Se ad esempio @other_columns contiene [“foo”, “bar”], la tabella prodotta dovrà contenere le colonne, nell’ordine: name, image_url, foo, bar. La colonna image_url deve mostrare un’immagine.

La tabella del primo esercizio non è difficile da realizzare. L’unico punto pochi hanno colto, e nessuno ha risolto correttamente, è che @other_columns contiene nomi di attributi, e quindi non posso estrarre un attributo per nome usando semplicemente una cosa tipo

  <% for column in @other_columns %>
    <td><%= object.column %></td>
  <% end %>

perché “column” è il nome della variabile su cui iteriamo, non è il nome di un metodo di object. Si può risolvere in Ruby con il metodo “send” che usa reflection

  <% for column in @other_columns %>
    <td><%= object.send(column) %></td>
  <% end %>

(Ad esempio: 3.succ restituisce 4, come anche 3.send(“succ”)) Oppure si può usare la hash “attributes” di ActiveRecord::Base:

  <% for column in @other_columns %>
    <td><%= object.attributes[column] %></td>
  <% end %>

Altra cosa: per produrre un elemento “img” la cosa migliore è usare lo helper image_tag:

  <%= image_tag object.image_url %>

piuttosto che

  <img src="<%= object.image_url %>" />

Esercizio 2

In che cosa consiste il meccanismo della redirezione nel protocollo HTTP? Come funziona? Qual’è l’uso che se ne fa principalmente in un’applicazione web?

Come funzionano le redirezioni? E soprattutto, a che cosa servono in un’applicazione web? E’ vero che, come molti hanno fatto notare, servono per ridirigere l’utente sulla pagina di login quando cerca di accedere a una pagina protetta se l’utente non è in sessione. Ma l’uso più comune è di ridirigere l’utente su una pagina ottenuta tramite GET dopo che ha modificato una risorsa con una richiesta POST. Di questa cosa abbiamo ampiamente discusso a lezione. Infatti il codice dello scaffolding di Rails, che vi consiglio di studiare perché è migliore del codice che molti programmatori Rails principianti scrivono a mano, fa cose di questo tipo:

  def create
    @user = User.new(params[:user])
    if @user.save
      flash[:notice] = 'User was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

Se l’oggetto @user è stato salvato con successo, l’utente viene rediretto sulla pagina che lista gli utenti. Altrimenti l’utente si ritroverebbe su una pagina ottenuta tramite POST, e quindi non bookmarkabile. Peggio ancora, se l’utente facesse un reload della pagina, e ignorasse l’avvertimento del browser, si ritroverebbe a inserire due volte lo stesso oggetto @user nel database.

Esercizi 3 e 4

In un’applicazione vogliamo tenere traccia di utenti (User) e ruoli (Role) da essi ricoperti. Ogni utente può ricoprire un ruolo, ma vogliamo sapere da quando a quando il ruolo è stato ricoperto. Ciascun ruolo ha un insieme di privilegi, che devono anch’essi essere rappresentati (come stringhe) nel database. Disegnare il diagramma entità-relazioni, e il codice sql necessario per implementarlo. (In alternativa a sql scrivere il codice delle migrations.)

Nell’applicazione del punto precedente: scrivere le classi ActiveRecord per tutti i modelli che ritenete necessari, facendo in modo che

  • Il metodo current_role di User restituisca il ruolo correntemente ricoperto da un utente, oppure nil se non ricopre alcun ruolo.
  • Il metodo roles di User restituisca tutti i ruoli ricoperti in ordine di tempo
  • Non sia possibile salvare un utente nel database se non è presente almeno uno fra i seguenti campi: first_name, last_name, nickname. Deve essere possibile salvare se uno dei tre è compilato ma gli altri no.

Quasi nessuno dei miei studenti sa usare le relazioni molti-a-molti. Che vergogna! E quel che è peggio, molti degli altri non sono in grado nemmeno di mettere in piedi una relazione uno-a-molti. Doppia vergogna. Vai a leggere la sezione 14.6 Relationships between Tables
del libro di Rails e non farti rivedere fino a quando non hai capito quello che c’è scritto.

Prima di tutto, è necessario capire come funziona lo schema dei dati. Dobbiamo leggere con attenzione il tema, per capire quali siano le cardinalità giuste delle relazioni. Ora, è chiaro che gli utenti e i ruoli sono associati. Ma un utente, quanti ruoli può avere avuto nella sua vita? Zero, uno o anche più di uno, quindi “molti”! E un ruolo, da quanti utenti può essere stato ricoperto nel tempo? Ancora, molti! Stesso discorso per i privilegi, che possono essere associati a più di un ruolo. Ad esempio, il privilegio di “cancellare tutti i file degli utenti” può essere associato sia al ruolo “amministratore” che al ruolo “boss”.

Normalmente una relazione molti a molti come questa

          *        *
     User ---------- Role

viene implementata con una tabella di supporto.

   create table roles_users (
     user_id int not null references users(id),
     role_id int not null references roles(id),
     primary key(user_id, role_id)
   )

Quei due campi “user_id” e “role_id” sono chiavi esterne, o foreign keys. Se non sai di che cosa sto parlando, vuol dire che non capisci nulla di basi di dati.

Ora, il nostro caso è un po’ più complicato perché l’assegnamento di un utente a un ruolo ha una data di inizio e una possibile data di fine. La soluzione canonica è arricchire la tabella di supporto con gli attributi necessari:

create table roles_users (
  user_id  int      not null references users(id),
  role_id  int      not null references roles(id),
  start_on datetime not null,
  end_on   datetime null,
  primary key(user_id, role_id)
)

Ora questa tabella roles_users comincia ad assomigliare a un’entità a sè stante. Si dà il caso che ogni relazione molti-a-molti può essere sempre vista come una coppia di relazioni uno-a-molti; e in questo caso diventa vantaggioso inventarsi un nuovo concetto: la nomina (grant) di un utente in un ruolo. Un utente ha (avuto) molte nomine, un ruolo è stato assegnato in molte nomine. Una nomina è di un utente e di un ruolo.

        1    *       *   1
   User ------ Grant ----- Role

A questo punto, invece di usare il vecchio has_and_belongs_to_many, conviene usare il nuovo has_many :through, che è più in linea con la maniera moderna, REST, di fare codice Rails.

  class Grant < ActiveRecord::Base
    belongs_to :user
    belongs_to :role
  end
  
  class User < ActiveRecord::Base
    has_many :grants
    has_many :roles, :through => :grants
  end
  
  class Role < ActiveRecord::Base
    has_many :grants
    has_many :users, :through => :grants
  end

L’unico accorgimento da prendere è di dare una sua propria chiave alla tabella, che non è più una semplice tabella di supporto ma è un’entità a tutti gli effetti.

create table grants (
  id       int      auto_increment,
  user_id  int      not null references users(id),
  role_id  int      not null references roles(id),
  start_on datetime not null,
  end_on   datetime null,
  primary key(id)
)

C’è un interessante e conciso articolo di Scott Raymond sui vantaggi di rifattorizzare un’applicazione Rails per avvantaggiarsi di uno stile rest. (cache di google)

Per quanto riguarda la validazione, basta ricordare che non esistono solo le validazioni prefabbricate come validates_presence_of; si può sempre scrivere una validazione ad hoc, come ad esempio:

def validate
  if first_name.blank? and last_name.blank? and nickname.blank?
    errors.add_to_base "inserisci nome, cognome o nickname"
  end
end

Busy, busy, busy

February 19th, 2007

Sono entrato in Sourcesense, un’azienda di cool kids che fornisce sviluppo e consulenza su software open source. Siamo appena partiti con un nuovo team e un nuovo cliente. Sviluppiamo un’applicazione gestionale in Java, e stiamo adottando quanto più XP riusciamo.

Fra poco farò l’annuncio della nuova edizione di Essap. Stay tuned!