giovedì 29 dicembre 2011

sudo: root o utente?

Ormai quasi tutti si sono abituati all'uso di sudo, un software che consente di fornire credenziali elevate (di amministratore) ad utenti normali. L'idea è semplice: l'amministratore di sistema fornisce una lista di utenti non amministratori che possono richiedere privilegi maggiori (specificando anche cosa possono fare). Quando uno di questi utenti deve eseguire un programma con privilegi maggiori invoca sudo che gli consente di innalzare i propri permessi.
Se ben usato sudo aumenta anche la protezione del sistema: è possibile con sudo utilizzare un account root senza nemmeno averlo abilitato, e quindi lasciando un account noto (e quindi attaccato) inaccessibile.
Molti sistemi Linux in default installano sudo abilitando per l'utente che ha effettuato la prima installazione. Un caso classico sono gli *buntu in versione sia server che desktop. L'utente quindi con una sola password puo' amministratore il computer.
PCBSD fa una scelta di default differente: abilita sudo per l'utente che effettua l'installazione ma richiede che la password fornita non sia quella dell'utente ma quella di root stesso. 
Qual'è la motivazione di questa scelta, a prima vista inutile? Se durante l'installazione l'utente principale viene abilitato a sudo allora questo avrà la possibilità di accedere direttamente come amministratore, cosa che a volte non è fattibile. Usando invece la password di root solo gli utenti che conoscono tale password saranno abili e abilitati a eseguire comandi privilegiati. Certo, potrebbero farlo come root stesso, ma il sistema puo' continuare a tenere l'account di root disabilitato permettendo un innalzamento dei privilegi dell'utente normale.
Difficile dire quale scelta sia la migliore, probabilmente quella di PCBSD, anche se richiede qualche accorgimento in piu'. In entrambi i casi il comportamento puo' essere modificato dall'amministratore in qualunque momento agendo sul file /etc/sudoer che contiene delle righe simili a:

## Uncomment to allow any user to run sudo if they know the password
## of the user they are running the command as (root by default).
Defaults targetpw  # Ask for the password of the target user


E come riporta la pagina man:

targetpw        If set, sudo will prompt for the password of the user specified
                       by the -u option (defaults to root) instead of the password of
                       the invoking user.  Note that this precludes the use of a uid not
                       listed in the passwd database as an argument to the -u option.
                       This flag is off by default.

venerdì 23 dicembre 2011

Traduzioni Italiane di PCBSD

Avendo avuto un po' di tempo, che ormai è sempre piu' una rarità, ho completato la traduzione di alcuni file di PCBSD in italiano. In particolare desktopschema.po  SysInstaller.po  SystemUpdaterTray.po sono ora completamenti localizzati. Penso possa ritenersi il mio personale regalo di Natale (al quale hanno contribuito altri prima di me) per questo sistema operativo e la sua community. Purtroppo non sono stato in grado di caricare i file sul server ufficiale, perchè sembra che al momento ci sia qualche problemino....

domenica 18 dicembre 2011

FreeBSD, gmirror e GPT

Con l'imminente uscita di FreeBSD 9 alcuni utenti hanno lamentato problemi nell'utilizzo di gmirror, il tool userland di GEOM che consente il mirroring dei provider (dischi). Il problema e la confusione nasce dal fatto che FreeBSD 9 utilizza GPT come sistema di partizionamento di default per la versione 9, mentre usava il classico e antico MBR per le versioni precedenti. Qual'è quindi la differenza? Nello schema MBR la tabella delle partizioni viene salvata all'inizio del disco, nei primi 512 bytes. Per non sovrascrivere la tabella delle partizioni, GEOM salva le proprie informazioni (label) alla fine del disco. 
GPT, al contrario di MBR, salva anch'esso le proprie informazioni (tabella delle partizioni) alla fine del disco, e quindi puo' nascere conflitto fra GPT e GEOM. Conflitto che porta a confusione, a tal punto che anche Mr. Lucas, nel suo blog, scrive la soluzione al problema. Soluzione che è molto semplice, grazie all'eleganza di GEOM: basta infatti ricordarsi che un provider non è solo un disco fisico, ma anche una singola partizione, e il gioco è fatto! Si tratta quindi di mettere in mirroring non gli hard disk, ma le singole partizioni (cosa peraltro sensata e che ricorda il md di Linux)! Si avrà quindi un disco (o meglio almeno due!) con una GPT alla fine e tante partizioni, ciascuna con una label GEOM alla fine.

sabato 17 dicembre 2011

App Store: novità o trovata commerciale?

Sembra molto popolare oggi parlare di App Store. L'idea è semplice ed elegante: l'utente che vuole acquistare/ottenere una nuova applicazione per il suo device (computer, palmare, telefonino, ...) si collega ad un repository centralizzato (l'app store appunto), cerca la applicazione che faccia quello che interessa all'utente, accetta il contratto ed eventualmente paga un obolo, scarica l'applicazione che "automaticamente" si installa e il gioco è fatto. 
La gara alla creazione di nuovi app store è iniziata e tutti i vendor non si tirano indietro: c'è lo store per Apple, Android, Microsoft e la lista puo' continuare.
Eppure a me sembra, come riporto in questo thread, che questo concetto non sia nulla di nuovo. Basta infatti rileggere quanto scritto sopra per notare che si ha:
  • un repository centralizzato
  • un meccanismo di ricerca di una applicazione
  • un meccanismo di agreement
  • un meccanismo di download
  • un meccanismo di installazione
Cosa differenzia quindi un app store da un repository di software? Tecnicamente solo il nome. Si pensi ai repository Debian/Ubuntu, o ai ports di BSD. Cambiano gli strumenti, ma non il risultato. 

Riusciremo mai ad avere un app store globale? No. Dopotutto ancora non c'è accordo su un formato binario che possa andare bene per diversi sistemi, e perfino all'interno dello stesso sistema ci sono proposte differenti per gli stessi sistemi binari (ad esempio IPS vs OpenCSW). 

Pero' gli app store sono piu' pericolosi rispetto ai repository software. L'app store è molto legato alla tecnologia utilizzata (ad esempio Android rispetto ad Apple), molto piu' che un repository software che potrebbe fornire servizi a tecnologie leggermente differenti. Essendo cosi' legato alla tecnologia, l'app store rischia di legare anche l'utente ad essa. Dopotutto i vendor commerciali lo hanno capito: vendere uno smartphone o un pc non serve piu' a nulla. Bisogna vendere dei sistemi integrati. Ecco allora che arrivano le soluzioni all-in-one: telefono, pc, smartphone, televisore tutti dello stesso produttore, con lo stesso software, che si collegano allo stesso app store. La situazione è a tratti tragica: invece che usare la tecnologia per implementare standard interoperabili i vendor si stanno nuovamente chiudendo a riccio per imporre il proprio monopolio (chi si ricorda la guerra dei browser?). 

Non è comunque giusto fare di tutta l'erba un fascio: ci sono anche app store dalle buone intenzioni, che si propongono solo come un layer di semplificazione per l'utente. Un esempio è App Cafe' di PCBSD, che altro non è che un downloader/installer di file PBI.

venerdì 16 dicembre 2011

Qt 4.8

E' ufficiale: le Qt 4.8 sono ora disponibili per il download!
Fra le varie migliorie dovute all'evoluzione della libreria vi è anche un pesante refactoring del supporto al file system al fine di migliorare le già ottime prestazioni in I/O. E ovviamente LightHouse ha fatto in avanti al fine di supportare differenti windowing systems e porre le basi per Qt 5.

CodeSearch

Un interessante post di Miguel De Icaza illustra una considerazione economico-commerciale che ha portato Google a fare una scelta molto discutibile:
It is a shame that Google is turning their back on their officially stated mission "To organize the world‘s information and make it universally accessible and useful". It is a shame that this noble goal is not as important as competing with Apple, Facebook, Microsoft, Twitter and Yelp.
L'affermazione nasce dal fatto che Google chiuderà il validissimo e utilissimo (almeno per i programmatori) servizio CodeSearch, che consentiva una ricerca molto dettagliato all'interno del codice disponibile on-line.
Come curiosita': la ricerca di Datum in CodeSearch restituisce PostgreSQL come terzo risultato. Nessun altro motore di ricerca di codice fino ad ora mi ha dato lo stesso risultato.

Eclipse e il renaming dei getter/setter

Una delle feature che ha maggiormente contraddistinto Eclipse rispetto ad altri IDE è stato il refactoring, introdotto con la versione 2. Nel refactoring, una delle caratteristiche che uso maggiormante nel mio lavoro quotidiano è il rename che consente di modificare il nome di una variabile o metodo andando ad aggiustare automaticamente tutte le occorrenze nel progetto.
Dalla versione 3 di Eclipse il rename non viene piu' fatto tramite una dialog, ma tramite digitazione diretta del nuovo nome in overwrite. Questo ha fatto si che mi scordassi, con il tempo, che Eclipse ha anche la possibilità di aggiustare i nomi dei getter e setter di una variabile. Un collega mi ha ricordato che visualizzando la finestra di dialogo di rename all'atto della rinomina è possibile spuntare i checkbox per rinominare anche i metodi di accesso alla proprietà.


sabato 26 novembre 2011

PGDay 2011: un evento fantastico!

Il PGDay 2011 è stato un indiscusso successo. 
La conferenza, tornata a Prato (sede di origine dei PGDay) dopo 2 anni di assenza in cui ci si era spostati rispettivamente a Pisa e Roma, si è svolta nel sempre bello e accogliente palazzo della Monash University, che con la sua eleganza e l'ottima organizzazione interna ha fatto sentire ogni partecipante subito a casa. Il numero di partecipanti è stato elevato: di poche unità inferiore alle 100 persone! Questo è un grande risultato, se si pensa che la ben piu' grossa conferenza europea ha potuto contare circa 200 partecipanti. E questo risultato numerico testimonia anche il sempre maggiore interesse che PostgreSQL sta avendo in Italia. E si, perché quello che si è potuto chiaramente notare in questa quinta edizione è stata proprio la presenza prepotente di professionisti e aziende non solo semplicemente interessati a migrare verso PostgreSQL, ma con esperienze alle spalli e case studies di successo di applicazioni e stack in esecuzione con PostgreSQL. Si è quindi confermata, prepotentemente, la presenza di PostgreSQL all'interno delle soluzione software del nostro paese.
L'interesse per la conferenza è stato elevato, e nelle ultime settimane si è assistiti ad un vero e proprio incremento delle iscrizioni. Penso che tutti noi organizzatori ci possiamo ritenere soddisfatti per il risultato ottenuto, che ha sicuramente ripagato non solo i nostri sforzi di questi mesi, ma anche degli anni prcedenti.



Magnus Hagander, presidente di PGeu e membro del core-team, ha tenuto il keynote speech, illustrando le caratteristiche dell'ultima release di PostgreSQL, la 9.1 uscita pochi mesi fa. Il talk è stato molto interessante e seguito da tutti i partecipanti anche perché la neo-nata release 9.1 è ancora giovane e quindi non ancora applicata da tutti i DBA. 
Il tempo per un ottimo caffé e qualche dolcetto chiaccherando cordialmente con amici e conoscenti e si da il via alle sessioni tecniche. Io sono chair della sessione per DBA che si tiene nello splendido salone Grollo. Simon Riggs è il primo speaker, con un talk che fa riflettere sulla moda dei NOSQL e come PostgreSQL pensa di rispondere. Segue Andreas Scherbaum, con un talk su cosa sia possibile fare con PostgreSQL circa il datawarehouse e cosa ancora non sia possibile. Tocca poi a Marco Nenciarini, di 2ndQuadrant Italia, che illustra il nuovo livello di isolamento delle transazioni introdotto con la versione 9.1. Interessante il talk di CSI Piemonte che illustra come sia possibile integrare PostgreSQL all'interno delle soluzioni software adottate in regione.
Ed è il momento del pranzo, servito sempre all'interno della Monash University, che permette anche ai visitatori di fare conoscenza, parlare di argomenti tecnici e di soluzioni implementate e future. Passando fra le sale posso ascoltare (e partecipare a) conversazioni che spaziano dalla semplice installazione, alla replica, alle strategie di backup, ai linguaggi usati per lo sviluppo di applicazioni. Con grande piacere mi intrattengo a spiegare a diverse persone interessate come entrare a far parte di ITPUG e di cosa l'associazione si occupi.
Si riparte poi nel pomeriggio con la sessione di lightining talks. Io ho tenuto un talk intitolato "Da ISAM a PostgreSQL" in cui ho raccontato la mia esperienza di migrazione da tecnologie ad indici verso tecnologie relazionali. 
E' poi la volta nuovamente dei talk tecnici, e si riparte con Simon Riggs che parla di cosa pensa di implementare per PostgreSQL nel futuro. Si susseguono poi tre talk di 2ndQuadrant Italia, con Carlo Ascani (repmgr), Marco Nenciarini (PostgreSQL & Amazon EC2) e Gabriele Bartolini (barman). 
Dopo l'estrazione di due libri autografati su PostgreSQL 9 messi in palio da 2ndQuadrant tocca a me chiudere la conferenza, augurando a tutti un buon utilizzo del nostro database preferito e un arrivederci all'anno prossimo. Ma ovviamente, in puro stile community, l'arrivederci per molti è quasi immediato al pub a fianco della Monash, dove 2ndQuadrant ha offerto una birra a tutti i partecipanti!

Forza PostgreSQL!
Forza ITPUG!
Forza PGDay!

sabato 12 novembre 2011

OSX o FreeBSD?

C'è spesso molta confusione sui ruoli reciproci di OSX e FreeBSD. Ho trovato una valida citazione sul sistema di casa Apple con il quale mi trovo in perfetto accordo:

The config files don't *really* sit in /etc, home directories are 
in /Users and it's full of that kind of non-sensical nonsense. So, to say 
Mac OS X is like FreeBSD with knobs on, is like saying the Ferrari F1 car is 
like a Testarossa with knobs on - bits might have come from the same 
factory, but at different times and for different purposes.

10 anni di eclissi

Il progetto Eclipse compie 10 anni!



Ricordo ancora qualndo venni a conoscenza di questo IDE, alla conferenza Principle and Practice of Programming Java nel 2003. All'epoca quello che faceva spiccare Eclipse rispetto agli altri prodotti era il refactoring; la versione era ancora la 2, e quindi lo schema dei plugin stava prendendo forma ma senza il concetto di OSGi che ha prodotto il vero salto di qualità della piattaforma (almeno a mio avviso).
Io sono diventato utente Eclipse dal 2003, anche se l'uso intensivo dell'IDE l'ho iniziato ad avere nel 2004.


Eclipse & FreeBSD

Ho avuto recentemente dei problemi nell'installazione di Eclipse dall'albero dei ports su un FreeBSD 9 rc-1. Chiedendo aiuto nei forum ufficiali, ho scoperto che Eclipse non è un gran IDE secondo la community FreeBSD. In effetti se ci si pensa, anche la piattaforma RCP fornisce runner nativi per Windows, Linux e OSX, ma non per altri Unix generalizzati.

mercoledì 9 novembre 2011

root & Charlie

Una delle cose che mi è sempre piaciuta della cultura Unix è la simpatia con la quale alcune cose vengono/venivano nominate. Simpatia non sempre facilmente comprensibile, e non sempre colta da tutti.
Ebbene l'ultima mia scoperta a riguardo è avvenuta quando, ispezionando un file /etc/passwd di una fiammante nuova installazione di FreeBSD mi sono reso conto che l'utente root non viene banalmente etichettato come "root" o "System Administrator", ma come Charlie:


Ebbene svolgendo alcune ricerche, ho trovato che il nome Charlie è quasi certamente attribuito ad un famoso giocatore di baseball, Charlie Root appunto.
Un altro esempio di questo schema dei nomi è il nome assegnato all'utente daemon, esecutore dei demoni di sistema, che nel sistema 386 BSD veniva descritto come "The Devil himself".

martedì 8 novembre 2011

PGday 2011: programma on-line

E' finalmente disponibile il programma del PGDay 2011!
Anche quest'anno ci saranno ospiti della comunità internazionale (Magnus Hagander, Simon Riggs, Andreas Scherbaum) e della comunità nazionale, oltre ovviamente a tutto lo staff di ITPug.

domenica 16 ottobre 2011

Aggiunta di un item ad una combobox solo se questo non e' gia' presente

Un argomento che capita di discutere spesso e' come fare ad iterare fra gli elementi di una combo box, ed eventualmente selezionarne uno o aggiungerlo qualora non sia gia' presente. Ecco la mia personale soluzione.

venerdì 14 ottobre 2011

Se ne va un genio

int main(int argc, char** argv){
    printf("Bye Bye World!");
}

Mentre il mondo è ancora intento a compiangere Steve Jobbs un altro grande genio dell'informatica ci ha lasciati, in modo piu' silenzioso e discreto.
Non è finito sulla bocca di tutti, e molti pensano che non sia finito nemmeno nelle case di tutti. Eppure gli addetti ai lavori sanno che ormai ogni appliance si basa su una sua idea in particolare: Unix.

Grazie di tutto Dennis!


mercoledì 12 ottobre 2011

Qt: Login Dialog con selezione di username da una lista

Ho realizzato una dialog per effettuare il login utente. La dialog in questione consente di inserire username e password manualmente, ma permette anche di specificare una lista di username fra i quali scegliere (es. per lista di utenti prelevata da un database o da impostazioni salvate in precedenza).
Di seguito uno screenshot della dialog, e qui si trova il codice di implementazione.

lunedì 10 ottobre 2011

Qt: centrare una finestra nello schermo

In questo articolo sul Wiki Qt illustro come si possa centrare e dimensionare automaticamente una window sullo schermo. L'esempio in particolare centra e imposta al 90% dello spazio disponibile sullo schermo corrente la finestra. Occorre prestare attenzione all'uso dello schermo corrente (sistemi multischermo e/o multidesktop) e al fatto che la dimensione disponibile non include le eventuali barre/dock visualizzate. Ne consegue che nell'esempio riportato il 90% non è relativo all'intera superficie disegnabile, ma a quella principale del desktop.

venerdì 7 ottobre 2011

PgDay 2011: sempre piu' vicino!

Manca ormai poco piu' di un mese al nuovo PgDay, il quinto, che torna dopo due anni nella sua sede storica di Prato. Sono disponibili i banner per i blog, quindi se si vuole pubblicizzare l'evento non si ha che da incollare uno dei banner disponibili sul proprio sito.

mercoledì 5 ottobre 2011

QPushButton & QAction

Con rammarico e stupore ho scoperto che in Qt i pulsanti QPushButton non possono essere collegati a delle azioni QAction. La cosa è abbastanza strana perche' grosso modo in ogni toolkit grafico che conosco i pulsanti sono configurabili tramite delle azioni. Ovviare al problema non è particolarmente complesso:
  • si definisce una estensione di QPushButton
  • si implementa un metodo per associare al pulsante l'azione e si configura il pulsante di conseguenza
  • si collega ogni evento di modifica dell'azione all'aggiornamento del pulsante
  • si collega l'evento di click del pulsante al trigger dell'azione.
Il codice completo del pulsante, che ho chiamato ActionButton lo si può trovare nel wiki ufficiale Qt.

sabato 1 ottobre 2011

Qt: reboot automatico dell'applicazione

Una delle cose molto comode che il framework Eclipse RCP fornisce out-of-the-box è la capacità di riavviare automaticamente una applicazione. Qt non fornisce nulla del genere, ma non è difficile implementare un meccanismo per il reboot. In questo articolo sul Wiki ufficiale descrivo come implementare efficacemente il reboot. I passi fondamentali sono:
  1. creare una costante che sia associata al valore di uscita reboot
  2. modificare il  ciclo di vita dell'applicazione (main) affinche' usi un loop per processare l'applicazione. Il loop non termina fino a che il valore di uscita dell'applicazione non e' diverso dal valore di reboot.
  3. creare uno slot (ad esempio nella propria main window) per effettuare il reboot.
  4. creare una azione per gestire il reboot e connetterla allo slot di cui sopra.
Il nuovo ciclo main (punto 2) risulta quindi simile al seguente:

int main(int argc, char *argv[])
{
    int currentExitCode = 0;

    do{
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        currentExitCode = a.exec();

    }while( currentExitCode == MainWindow::EXIT_CODE_REBOOT );

    return currentExitCode;

}

ove ovviamente EXIT_CODE_REBOOT e' la costante definita ed opportunamente inizializzata. La MainWindow avra' uno slot (punto 3) simile al seguente:

void MainWindow::slotReboot()
{
    qDebug() << "Performing application reboot..";
    qApp->exit( MainWindow::EXIT_CODE_REBOOT );
}

e l'azione (punto 4) che gestisce il reboot sara' come la seguente:

    actionReboot = new QAction( this );
    actionReboot->setText( tr("Restart") );
    actionReboot->setIcon( QIcon(":/actions/img/reboot.png" ) );
    actionReboot->setStatusTip( tr("Restarts the application") );
    connect( actionReboot,
             SIGNAL(triggered()),
             this,
             SLOT(slotReboot()) );

venerdì 30 settembre 2011

Qt: General Purpose Database Connection Dialog

Oggi ho inserito nel Wiki Qt una pagina che mostra una dialog window generale per gestire una connessione ad un database. La dialog presenta all'utente una combo box con i tipi di database supportati (nomi dei driver) e una serie di campi che l'utente deve compilare per impostare le proprieta' di connessione (username, password, porta, host, ecc.). 



La dialog non attiva il pulsante di connessione fino a quando tutti i dati sono compilati e presenta anche una stringa URL riassuntiva della connessione (ovviamente senza la password!).
La dialog emette un signal con la connessione stabilita qualora questa avvenga con successo. 
Infine la dialog supporta la modalità auto-connect: i campi possono essere precompilati prima che la dialog sia visualizzata (es. da valori di default) e se si specifica l'auto-connect mode allora la dialog tenta immediatamente la connessione, che se avviene con successo non viene nemmeno mostrata all'utente. Di conseguenza è possibile associare la dialog ad una azione di connessione al database che chieda informazioni all'utente solo se i dati di connessione sono incompleti o sbagliati.

giovedì 29 settembre 2011

Qt Creator e gli hint nascosti

Qt Creator, l'ambiente IDE di riferimento per lo sviluppo Qt, ha dei code-hint nascosti che vengono attivati con la combinazione di tasti ALT+ENTER. Ad esempio, dopo aver dichiarato un metodo nell'header di una classe, facendo ALT+ENTER con il cursore posizionato sul nome del metodo stesso si attiva un menu' a tendina che permette di aggiungere l'implementazione del metodo (stub auto-generato).

Questo comportamento, non documentato, è variabile a seconda del membro su cui si attiva ALT+ENTER. La cosa strana è che il menu' C++ dell'IDE, che è gia' molto scarno, non riporta affatto queste opzioni. Spero anche che venga agigunto presto un sistema per l'autogenerazione dei getter/setter, e so che una richiesta è già in coda da diverso tempo per questa feature.

mercoledì 28 settembre 2011

Do not be public!

This is a well known rule of the OOP: encapsulate!
What this really means is that, as in all computer science fields, you should start giving no-rights and then adding a few allowance. In other words, each property you declare in a class should be private, each method should be final/const and so on. Of course I'm excluding the struct-alike objects from this paradigm.
Why be so reluctant to use protected? Well, you will be able to give up your rights later, and to convert your private field to protected, or even to public. You will be able to give others the capability to overload your methods, but if you don't have a real need to allow them to, don't!
Consider the following example:

     public class Foo{
         protected int counter = 0;
       
        public void sendEmail(){ // do stuff }

        public Foo(){
               counter = 10;
               sendEmail();
        }
     }


What is wrong with this kind of code? A lot of things... First of all the counter variable can be accessed directly from Foo subclasses, and this could not be what you want. Imagine you want to assure that all instances of Foo (and of its subclasses) have a counter that is initialized to 10, how can you impose this? You have to declare counter as private and provide no setter method for it. Leaving the field protected is a call for troubles.
A worst error in the above code is the sendEmail method signature, which is not final, and therefore can be overriden. Why is this wrong? Because the constructor of Foo will call a polymorphic method, and trust me, this can lead you to endless debugging sessions!
Summarizing, I can say that you should declare everything private, and when it is not private, declare at least final, and only when you are sure of what are you doing, allow direct access to methods/fields.
Now consider what happens with C++ with regard to methods: each method declared not virtual is automatically declared as final in Java. In other words, C++ does it right: it gives you the stricter behaviour on methods. I agree with you when you say that having to write "virtual" for each method is an extra-typing that can be avoided, but it is the only way to avoid awkward errors and is a good way to prevent you to release an API that is broken.

Qt: creare un nome di file con la data del giorno

Un trucchetto banale per costruire un nome di file che includa la data odierna nel proprio nome:


QString FileNameHandler::todayFileName(){
    QDate today = QDate::currentDate();
    QString relativeFileName( "data_" );
    relativeFileName.append( QString::number( today.month() ) );
    relativeFileName.append( "_" );
    relativeFileName.append( QString::number( today.day() ) );
    relativeFileName.append( "_" );
    relativeFileName.append( QString::number( today.year() ) );
    relativeFileName.append( "_" );
    relativeFileName.append( ".txt" );
    return relativeFileName;
}
Ho inserito questo esempio anche nel Wiki ufficiale Qt

domenica 25 settembre 2011

Do not be afraid of using structs for you (internal) implementations!

With the advent of OOP languages, developers seem to have forgotten that not everything need to be a fully implemented class. In a typical program you have bunch of data that must be collected together, but that not always needs to expose all the OOP features such as encapsulation (i.e., having hidden properties), accessors (i.e., getters and setters) and a polymorphic behaviour. Sometimes you need only to store a few fields together, for internal uses and just for your own convenience. A typical example is when you deal with external resources, for instance something that comes from an underlying software/library. In such cases, it is probably you will not be able to change the data that is passed back to you, but you have only to read and take actions depending on its value. In this scenario, it does not make any sense to build a fully object with a lot of getters/setters/constructors/destructors, a simple struct-like packaging will suffice.
Another example is when you have to deal with a few annotations at the same time; instead of accessing each annotation to get each value, you can pack values into a struct-like object and access such fields directly. Since you are not supposed to change an annotation at run-time, creating setters does not make sense, and therefore creating getters does not make sense either. So just skip them and use a struct!
I know that your OOP-soul is screaming about the above, but trust me, each method you add requires a new stack allocation (if not inlined, of course) and does not provide you with much more control than you require. After all, consider the following simple example (Java code):

class Person{
       private String name;
       private String surname;

       public String getName(){ return name; }
       public void   setName(String n){ name = n; }

       public String getSurname(){ return surname; }
       public void   setSurname(String n){ surnname = n; }
}


How often have you changed the accessor methods? I guess that for almost the 95% of you beans you don't have to overload the generic logic of getters and setters. In such a scenario, having the following is much simpler to write and to use at run-time:

class Person{
       public String name;
       public String surname;
}



There is of course a problem: if you need to change your accessing rules, you will not be able without breaking compatibility. In other words, once you expose a struct public property, you will never get it back!
However, as you can see, the class is not public, that in Java it means that it cannot be accessed outside the current package. In other words, the class does not represent a public API, but a private one, and you are always able to change it depending on your wills without even having clients to notice it.

There are also other cases when using struct-like objects is allowed, and an example is when your OOP API is an adaptor of an external API. An example can be found into the SWT Java GUI API, that being a kind of reimplementation of the Operating System API, it make a deep use of structures because they maps really well into the Operating System data structures.

In conclusion, the main idea of this article is that structs are good, but must be used with caution to avoid to make public something that could requires soon or later a different control path. But if you are sure you are using objects for your internal implementation and/or to map other languages/libraries structs, use them without being scared of!

sabato 24 settembre 2011

Che ore sono? Come Windows può forzare un jet-lag in Unix!

Sui sistemi dual boot Windows/Linux e/o Windows/Unix puo' capitare che all'avvio del sistema *nix alcuni file e directory risultino avere una data di creazione nel futuro, nonostante la data del sistema *nix sia impostata correttamente. Tipicamente la differenza è solo relativa all'orario, che si trova di alcune ore nel futuro. La motivazione dietro a questo problema risiede nel modo in cui Windows gestisce l'orologio di sistema: il sistema Microsoft impone infatti che l'orologio sia impostato come ora local. I sistemi *nix invece all'avvio impostano il time zone corretto prima di far partire tutti i servizi. Quello che succede è quindi che al boot di un sistema *nix l'orologio si trova in modalità local, quindi con un timezone non impostato. Il sistema *nix provvede alla creazione degli pseudo-device, /proc, ecc. con l'ora sbagliata, e poi, appena applica il timezone, si trova a correggere l'orario. Riporto un link ad un interessante thread che spiega questo problema.

venerdì 23 settembre 2011

Avoid the use of this, super and in general class qualifiers when not stricly required!

This can sound odd from me, that since my early days of OOP programming have always advocated the use of such qualifiers. The main reason I liked such qualifiers, and the main reason I presented to my students when teaching them OOP, was that the resulting code would be easier to read and, most notably, a lot of IDEs will bring up popups and code helpers to show you available completions. In other words, simply typing "this" will activate a popup that presents you with a list of choices between methods and fields to place in.
So what did change my mind? Why am I now advocating to avoid the use of qualifiers? Well, it is really simple: I switched back to some C code, and found myself comfortable while writing "unqualified" code. So I thought that in order to keep code clean and to get a more coherent syntax, avoiding qualifiers can help.
As an example consider the following piece of (imaginary) Java code:

   this.description = this.computeANewDescription();
   this.setTimeAndDate( super.getTodayDate() );
   this.setStatus( Status.STATUS_OK );


Now the above code can be rewritten in the following way, assuming you also use static imports:

   description = computeANewDescription();
   setTimeAndDate( getTodayDate() );
   setStatus( STATUS_OK );


Isn't it really much like a C code snippet? Apart keeping your fingers relaxed, due to not extra-typing keywords, the code is much more clean and can be read by any C developer.

Benchmarking tools

Solitamente per testare le prestazioni I/O di un sistema uso bonnie++, ma di recente ho scoperto un altro tool piuttosto interessante: filebench.
La cosa interessante di questo strumento è che presenta all'amministratore una shell che consente l'esecuzione dei vari comandi. Altra cosa interessante è che il tool viene installato con una serie di personalità differenti, ossia di workload pre-configurati per i test.

mercoledì 21 settembre 2011

C++11

E' ufficiale, la nuova release delle specifiche C++ (denominate C++11) è stata accettata! 
Il linguaggio subirà notevoli cambiamenti, fra i quali:
  • possibilita' di inizializzare staticamente le variabili di classe, marcando i costruttori come espliciti
  • possibilita' di definire delle espressioni da usare al posto di costanti, una sorta di macro valutabile a run-time
  • possibilità di marcare dei metodi come  final  e come ovveride per specificare e controllare meglio dove e come si sovrascrivere un metodo di classe base (e se questo sia possibile)
  • definizione di un puntatore nullo, nullptr, che sostituisce il vecchio (e compatibile) valore 0
  • ciclo foreach simile come sintassi al ciclo Java
  • utilizzo dello specificatore auto per lasciare al compilatore il compito di comprendere il tipo di una variabile (type inference)
  • possibilità di inizializzare delle liste di oggetti staticamente
  • funzionamento di sizeof anche per tipi innestati
  • multihreading
  • lamba calculus
Forse la novità piu' sconvolgente, almeno secondo la mia opinione, è proprio l'ultima, che conferma come il calcolo funzionale stia sempre piu' prendendo piede (o riprendendo piede!).
Per una lista piu' dettagliata delle modifiche al linguaggio e alla libreria si vedano i seguenti link:

Avoid naming variables with the name of their type

Often you can see code where variables are named after their type, such as for instance:

      CrudDAO crudDAO = new CrudDAO();
      String  string  = "Hello";

and so on, you get the idea. While this makes sense if you are writing an "Hello World" program, it does not scale when you have complex and long listing sources. In particular it becomes harder to refactor such code, because if you want to change such variable types, you have to change their names too. While this can be performed by an automatic refactoring tool, it almost always requires a manual intervention. Therefore, choose mnemonic names that have a correct meaning regardless of the specific type they belongs too, such as:

      CrudDAO dao      = new CrudDAO();
      String  message  = "Hello";

In the above code, it becomes very easy to change the type of the "dao" variable to another instance letting it representing what it means: a Data Access Object. Similarly, if the "message" variable is changed to a Char array, you don't have to change its name to reflect such change, since the name is much more meaningful than a simple "string".

martedì 20 settembre 2011

Qt Project


E' di qualche giorno fa l'annuncio ufficiale del Qt Project.
Finalmente, dopo tanti anni di discussioni e polemiche sul licensing delle Qt (chi non ricorda la storia di Gnome e Stallman che incita De Icaza?) si e' deciso di dare a queste fantastiche librerie grafiche una foundations che ne guiderà lo sviluppo e la gestione. Ci si muove quindi velocemente verso una piena liberalizzazione di questo ottimo framework di sviluppo.

The Java Beans specification sucks!

Ok, the title is quite harsh, but it is so true...
The Java Beans specification imposes that each object property (i.e., variable) is accessed thru a couple of setter and getter method. In particular the method must be named with set/get prefix (lowercase) followed by the name of the property (with the first letter capitalized and the remaining as the original name). The return type and the arguments depends on the type of the method (often called accessor): in the case of a getter there are no arguments and the return type is of the same type of the property; in the case of the setter there is no return type and there is a single argument of the same type of the property.
As an example, the following is a correct Java Bean class definition:

class Person{
      private String name;
      private String surname;

      public void setName( String newName ){ name = newName; }
      public String getName(){ return name; }
      public void setSurname( String newSurname ){ surname = newSurname; }
      public String getSurname(){ return surname; }
}


As you can see the "name" property generates the "setName" and "getName" methods, as well as the "surname" property generates the "setSurname" and "getSurname" methods. All the getXX methods have a return value of the same type of the property and accept no arguments; all the setXX methods do not return any value and accept a single argument of the same type of the property they refer to.

Why I don't like this naming convention?

Let's start with the naming schema: while it is clear that I have to separate a getter name from the setter one, why should I have the get prefix? I mean, if I want to access the "name" property, that is exactly what I want to type. What is the simpler and beautiful code between the following?

      person.getName();     // Java Bean style
      person.name();        // Qt style


The latter does exactly what I want: I want to access the name property, so I don't want to explicity say "get the name property", but simply "the name property". Easier to type, simpler to read: I'm accessing the person name, I don't need to emphasize that I wan to "get" the person name because it is implicit that I am asking the person's name!
On the other hand the setter can remain the same, so that my bean becomes:


class Person{
      private String name;
      private String surname;

      public void setName( String newName ){ name = newName; }
      public String name(){ return name; }
      public void setSurname( String newSurname ){ surname = newSurname; }
      public String surname(){ return surname; }
}


A drawback of this approach is that using a standard prefix I have all the method grouped together: all the getXX and all the setXX. Removing the get prefix I find only the setters grouped together, while the other methods are sorted as the property names. This can be boring only if you are used to inspect a bean by means of reading the getter method names and not by reading its documentation.
Moreover, it is not clear how to behave when you have boolean properties: should you use "is" or "has" prefixes in the method names? A lot of framework seems to deal with the "is" convention, but I'm sure that a getter method called "isMoney" to return true in the case has still money sounds awkward even to the stricter Sun's engineer.

Anyway, another big, even huge problem of the Java Bean specification is that it does not consider side-effects. How can you test a setter method? You have to create a getter method! While this can sound ok to you, it does not look very good to me. When you execute a method call like:

    person.setName( "Luca" );

how can you assure that the name has really been set to "Luca"? You have to call getName() and test the two values. While setter and getters are usually simple and straightforward methods (those that can even be inlined), a lot of things can go wrong while in the execution path of one or the other. What is the solution? To have a setter that can return the actual value of the property, so that it is defined as returning the same type of its parameter. In other words:


class Person{
      ...
      public String setName( String newName ){ 
          name = newName; return name; 
      }
      public String setSurname( String newSurname ){ 
         surname = newSurname; return surname;    
      }
}


In this way the setter methods represent a single unit of testing, therefore can be tested as they are without requiring anything else (in particular a gettere method). Moreover in this way the classes are exposing to the outside world a clear side effect of the setter methods.

In conclusion I disagree with the Java Bean specification mainly for:
- their naming convention;
- their definition of setter method.
The worst thing in the whole story is that you cannot even think to change the Java Bean convention to use a different name schema or even to change the return type of the setter methods. This is due to the fact that a lot of Java frameworks adopt reflection to inspect and access properties, and while doing so they will stupidly search for setter methods that return void!

Big Endian vs Little Endian

Una delle migliori spiegazioni visuali del problema!