Douglas Crockford on features

Quote

We see a lot of feature-driven product design in which the cost of features is not properly accounted. Features can have a negative value to consumers because they make the products more difficult to understand and use.

We are finding that people like products that just work. It turns out that designs that just work are much harder to produce than designs that assemble long lists of features.

Features have a specification cost, a design cost, and a development cost. There is a testing cost and a reliability cost. The more features there are, the more likely one will develop problems or will interact badly with another.

Invocazione dinamica di metodi in JavaScript

Spesso scrivendo codice in JavaScript capita di dover richiamare un determinato
metodo a seconda del contesto. Un primo approccio potrebbe essere il seguente:

if (condition) {
  obj.method1(arg1, arg2);
} else {
  obj.method2(arg1, arg2);
}

Altrettanto spesso, però, capita di dover generare dinamicamente il nome del
metodo da invocare, ma non è possibile farlo utilizzando la dot-notation:

//Errore
var obj = new Object,
    nomeMetodo = "method1"; //simulazione della generazione
                            //dinamica del nome

obj.method1 = function() {
    console.log("Invocato method1");
}

obj.nomeMetodo();
/* TypeError: o.nomeMetodo is not a function
   o.nomeMetodo()
 */

JavaScript però fornisce anche una sintassi alternativa per l’invocazione dei
metodi, la brackets-notation che, se avete programmato almeno una volta negli
ultimi 50 anni, avrete sicuramente utilizzato per accedere agli elementi di un
Array:

// brackets operator
var arr = [],
    obj = new Object,
    nomeMetodo = "method1";

obj.method1 = function() {
    console.log("Invocato method1");
}

arr.push("zero");
arr.push("uno");
// operatore [] su Array
console.log(arr[1]) //"uno"

//operatore [] su Object
console.log(obj[nomeMetodo]) //"Invocato method1"

Gli utilizzi pratici di questa tecnica sono innumerevoli, soprattutto per
scrivere codice cross-browser. Un esempio.

Tutti i moderni browser supportano gli eventi del DOM Level 2, mentre alcune
versioni precedenti di IE avevano una sintassi diversa, e browser ancora più
vecchi supportavano solo gli eventi del DOM Level 0. Quindi possiamo scrivere
una funzione che astrae queste differenze:

function addListener(element, type, handler) {
    if( element.addEventListener ) { //DOM Level 2 events
        element.addEventListener(type, handler, false);
    } else if ( element.attachEvent ) { // IE < 9
        element.attachEvent("on" + type, handler);
    } else { // Old browser: Level 0!
        element["on" + type] = handler;
    }
}

Utilizzando la capability detection :

  • se gli eventi DOM Level 2 sono supportati, li utilizziamo in fase di
    bubbling,
  • se si tratta di una versione di IE precedente alla 9, utilizziamo la
    sintassi proprietaria,
  • se invece siamo in presenza di un vecchio browser, utilizziamo gli eventi
    DOM Level 0.

In quest'ultimo caso, dato che l'event handler è considerato proprio un metodo associato
all'oggetto, possiamo utilizzare l'operatore [] per creare dinamicamente il
nome del metodo da richiamare, a seconda del tipo dell'evento (es. "click"
diventa "onclick").

Preprocessor directives in C

Il C è come il vino buono, più passa tempo, più si apprezza.
Oggi ho imparato (solo oggi, purtroppo) ad usare le direttive al preprocessore.
Ad esempio mi era utile definire se il codice dovesse essere compilato per debug oppure per produzione, e ho risolto in questo modo:

/*
 * compile_directives.c
 *
 **/
#include 

#ifdef DEV_ENV
#define DEBUG 1
#else
#define DEBUG 0
#endif

int main(){
  if(DEBUG) {
    printf("Development environment\n");
  } else {
    printf("Production environment\n");
  }
  return 0;
}

Compilando senza alcun flag aggiuntivo si ottiene:

[justb@dellill]$ gcc -Wall compile_directives.c -o compile_directives.out
[justb@dellill]$ ./compile_directives.out
Production environment

Mentre aggiungendo il flag -D DEV_ENV dato che, come recita man gcc:

-D name
Predefine name as a macro, with definition 1.

[justb@dellill]$ gcc -Wall -DDEV_ENV compile_directives.c -o compile_directives.out
[justb@dellill]$ ./compile_directives.out
Development environment

Pretty neat, uh?

Eseguire script CGI in Apache

Per permettere l’esecuzione di script CGI nella userdir è sufficiente aggiungere queste istruzioni al file userdir.conf (o parimenti httpd.conf):

<Directory /home/*/public_html/cgi-bin>
    Options +ExecCGI
    AddHandler cgi-script .cgi .py .pl
</Directory>

In pratica si permette l’esecuzione di script (con estensione cgi, py o pl) dalla sottodirectory cgi-bin all’interno della userdir di Apache (tipicamente /home/utente/public_html)

Sostituire il testo in Vim

Per sostituire una parola con un’altra in Vim, facendo in modo che l’editor chieda la conferma:

:%s/vecchia_parola/nuova_parola/gc

Spiegazione comando

:
Entrare in modalità comando
%
Esegui questo comando su tutto il file
s
Abbreviazione per :substitute
/vecchia_parola/
Espressione regolare che specifica cosa cercare nel file
/nuova_parola/
Testo da inserire al posto di quello cercato
Flag g
Cambia ogni occorrenza, non solo la prima di ogni riga
Flag c
Chiedi conferma prima di ogni sostituzione

Installare Oracle Express Edition in Windows

Per il Laboratorio di Basi di Dati si è resa necessaria l’installazione del DBMS Oracle.
Per non appesantire con un tale macigno la mia partizione Linux, ho deciso di passare la palla a Windows.

Download e installazione

Oracle fornisce una versione stripped down, gratuita e liberamente utilizzabile per progetti personali e open source: Oracle Express Edition 11g Release2.
Continue reading

Sui parametri dei metodi in Ruby

Un metodo (o funzione) in Ruby può accettare zero o più parametri:

class Document
  attr_accessor :title, :author, :content

  def initialize(title, content, author)
    @title = title
    @author = author
    @content = content
  end

  def words
    @content.split
  end

  def word_count
    words.size
  end
end

In questo esempio, initialize accetta tre parametri, mentre words e
word_count accettano zero parametri. Fin qui tutto semplice ed in linea con
gli altri linguaggi di programmazione.

È possibile rendere alcuni parametri opzionali, fornendo un valore di default:

class Document
  attr_accessor :title, :author, :content

  def initialize(title, content, author='unknown')
    @title = title
    @author = author
    @content = content
  end

  . . . 

  def word_count
    words.size
  end
end

In questo esempio modificato, initialize può accettare sia tre parametri, come
prima, sia soltanto i primi due, impostando il terzo parametro al valore
predefinito. Il risultato, ad esempio:

irb %> Document.new('Prima poesia della storia umana', 'Urgh! Argh!')
 => #<Document:0x9855b20 @title="Prima poesia della storia umana", @author="unknown", @content="Urgh! Argh!">

A volte è però necessario avere un elenco completamente arbitrario di parametri:
per questa evenienza Ruby ha una sintassi particolare:

class Post
  # resto della classe

  def add_tags( *tags )
  	@tags += "#{ tags.join(" "}"
  end

  def post_meta
  ...
  end
end

Preponendo un * davanti al nome del parametro, Ruby passa al metodo tutti i
valori, “impacchettandoli” in un array che è possibile ispezionare all’interno
del metodo. Una utile prova potrebbe essere:

def stampa( *params )
  params.each do |param|
    puts param
  end
end

Inoltre l’operatore * (splat) funziona anche in senso inverso. Riprendendo l’esempio della classe Document, è possibile passare un array contenente i tre elementi richiesti preponendolo con un *:

libro = ["L'identità", "Un albergo...", "Kundera"]
Document.new( *libro )

Per ora mi fermo qui. Integrerò la pagina con altre informazioni in proposito.

Caratteri accentati in file di testo in Vim

Capita a volte di scrivere dei file di testo e poi visualizzarli in un browser. Dato che l’Italiano sfrutta molto le lettere accentate ed i browser non hanno come encoding di default UTF-8 escono spesso artefatti tipo èòÃ.
Per ovviare a questo problema si può:

  • Impostare l’header HTTP Content-Type: text/html; charset=UTF-8 come encoding
  • Se si tratta di un file HTML inserire un meta-tag: <meta http-equiv="Content-Type" content="text/html; 
  • Inserire all’inizio del file un BOM (Codepoint U+FEFF). Con Vim è possibile inserirlo nel buffer corrente tramite il comando :set bomb on

Benchmarking in Ruby

Dato che l’esame di Algoritmi mi sembrava troppo teorico, ho deciso di implementare tutti i vari algoritmi che studierò in Ruby (così almeno faccio due cose buone).

Si è posto subito il problema del Benchmarking per misurare empiricamente il tempo impiegato dai vari algoritmi per la risoluzione e per il successivo confronto dei risultati con l’analisi teorica.
Continue reading

La cicala e la formica: dobbiamo veramente tenere conto delle “personalità”?

Una decina di giorni fa, Antonio Fullone nel suo blog ha scritto un post, abbastanza duro, puntando il dito contro le cosiddette "Blogstar", o come li ha definiti lui "Guru".

Il punto del suo attacco è "Ci sono un sacco di persone alle luci della ribalta, che si credono chissà chi, sanno poco e niente  e si atteggiano a divi e vengono seguiti e inneggiati da fans sfegatati, che sono ignari di queste cose". Continue reading

Le liste ci uccideranno tutti ovvero un appello ai web designer

Non se ne può più. Dico davvero. Ormai siamo invasi. Liste di qualunque genere. Il numero degli elementi può variare: si va dai classici dieci (la storica top ten) a numeri astrusi (47, 59, 88). Gli argomenti: i più disparati. "Le 53 tecniche CSS senza cui non puoi vivere". "23 titoli per un blogging più accattivante". "57 texture prese dalla carta igienica".

Continue reading