Archivio per il mese di luglio 2008



Gist, il pastebin definitivo

Oggi come oggi esiste una moltitudine di servizi pastebin sparsi per internet ma da qualche giorno è stato aperto quello che attualmente considero essere il pastebin definitivo: Gist. Gist è offerto dall’ormai noto GitHub, il servizio di hosting di progetti probabilmente più in voga in questo momento, e può vantare funzionalità piuttosto interessanti come:

  • supporto per una settantina di linguaggi/grammatiche differenti… anche se manca LOLCode, nonostante ci sia Brainfuck :-)
  • pastie (qui chiamati gist) pubblici o privati, anonimi oppure "identificati" se effettuati tramite il proprio account GitHub. Le operazioni, in questo caso, sono elencate all’interno della dashboard
  • ogni gist può essere composto da file multipli, con possibilità di scaricare comodamente la versione raw di ogni file oppure di effettuare il download del pacchetto intero in formato tar.gz
  • possibilità di modificare i propri gist con tanto di accesso allo storico delle varie revisioni
  • clone URL pubblici e privati per ogni singolo gist, pronti per essere dati in pasto a Git

Provatelo, è veramente ottimo. Giusto per curiosità, questa è la pagina con i miei Gist pubblici…

LuaRocks! Ovvero, un comodo package manager per le librerie di Lua

Lua è un linguaggio di programmazione dinamico e portabile particolarmente noto e utilizzato come linguaggio embdedded grazie ad alcune caratteristiche, proprie e della sua VM, che lo rendono ottimo per lo scripting di applicazioni più o meno complesse scritte in altri linguaggi, solitamente compilati. Ovviamente può essere utilizzato anche per programmare intere applicazioni oppure semplicemente script di automazione, ma in casi simili è molto facile che ci si ritrovi con la necessità di utilizzare librerie esterne da installare e gestire separatamente e manualmente: Lua infatti, diversamente da linguaggi come Ruby o Python, nella sua distribuzione ufficiale non fornisce un set di librerie standard insieme al runtime. Il crescente numero di queste librerie di terze parti ha cominciato a rendere difficile la gestione delle stesse nei propri sistemi e per questo, quasi un anno fa, è nato LuaRocks, un progetto per la realizzazione di sistema di distribuzione e gestione di moduli per Lua che per certi versi risulta essere molto simile a RubyGems.

Attualmente per installare LuaRocks nella maggior parte delle distribuzioni Linux è necessario prelevare il tarball ed eseguire i soliti passaggi ./configure && make && make install, tuttavia l’installazione sulle Ubuntu-derivate a partire da 8.04 Intrepid Ibex o su Debian a partire da 5.0 Lenny sarà molto più semplice dal momento che basterà installare il pacchetto luarocks tramite apt-get. Per Windows esiste un installer che automatizza le procedure, lasciando all’utente la scelta se installare un interprete Lua basilare senza librerie fornito dallo stesso installer o se utilizzare un interprete già installato nel proprio sistema. Tutte le informazioni necessarie al download e all’installazione di LuaRocks sono disponibili sul relativo sito.

Nel frattempo pochi mesi fa è nato un installer di Lua per Windows chiamato, con molta fantasia, Lua for Windows. Esso include molte delle più note librerie per Lua e un ambiente di sviluppo/debug già configurato e basato su SciTE. Si tratta quindi di un’ottima soluzione per avere in pochi secondi tutto il necessario per poter programmare in Lua, tuttavia LuaRocks non è stato ancora incluso per cui ecco i passaggi da seguire per integrare il tutto:

  • Scaricare Lua for Windows (LfW) e procedere con l’installazione: la mia installazione è stata effettuata nel path proposto di default, ovvero C:\Programmi\Lua\5.1
  • Scaricare LuaRocks per Windows, decomprimere l’archivio e aprire la shell dei comandi nella directory contenente install.bat
  • L’installer di LuaRocks permette di specificare alcune opzioni. Ecco come installarlo in modo che sfrutti l’interprete reso disponibile da LfW e che utilizzi un unico path per l’installazione dei pacchetti rock:

    install /LUA C:\Programmi\Lua\5.1 /BIN C:\Programmi\Lua\5.1 /P C:\Programmi\Lua\5.1\LuaRocks\0.6 /CONFIG C:\Programmi\Lua\5.1\LuaRocks /TREE C:\Programmi\Lua\5.1\LuaRocks\ /SCRIPTS C:\Programmi\Lua\5.1\LuaRocks\ /FORCECONFIG

    Di default LuaRocks permette anche ad utenti non amministrativi di installare dei pacchetti rock locali (solitamente in %APPDATA%/luarocks/rocks/), mentre con l’opzione /FORCECONFIG verrà considerato un unico file di configurazione, quello specificato da /CONFIG, e un unico path per l’installazione di rock e script a livello di sistema, specificati rispettivamente da /TREE e /SCRIPT. Potete fare riferimento alla documentazione per un approfondimento in merito.

  • La directory C:\Programmi\Lua\5.1 viene automaticamente aggiunta al PATH di sistema dall’installer di LfW per cui possiamo creare un hardlink ai file luarocks.bat e luarocks-admin.bat con il fine di poter invocare gli stessi più comodamente dalla shell. Da Windows XP in avanti si può operare come segue:

    cd C:\Programmi\Lua\5.1\LuaRocks\0.6
    fsutil hardlink create ../../luarocks.bat luarocks.bat
    fsutil hardlink create ../../luarocks-admin.bat luarocks-admin.bat

  • Modificare la variabile di sistema LUA_PATH aggiungendo ai path già impostati da LfW il seguente percorso per il caricamento dei file della libreria LuaRocks:

    C:\Programmi\Lua\5.1\LuaRocks\0.6\lua\?.lua

Ora LuaRocks è installato e funzionante, basta aprire la shell dei comandi e lanciare luarocks search –all per visualizzare tutti i pacchetti rock disponibili sul server (è disponibile anche un elenco consultabile più comodamente) e luarocks install nomepacchetto per installare i pacchetti rock nel sistema. A questo punto negli script Lua basterà aggiungere la riga require "luarocks.require" che si occuperà di effettuare l’override della funzione require standard di Lua, rendendo possibile il caricamento delle librerie installate tramite LuaRocks. Alternativamente si può ottenere lo stesso risultato lanciando così l’interprete: lua -lluarocks.require

Ecco un esempio di come sfruttare una libreria installata tramite LuaRocks:

-- luarocks install colors require "luarocks.require" require "colors" green = colors.new("#0f8923") print("Verdolino:", green) -- Verdolino: #0f8923

LuaRocks con l’ultima release ha raggiunto un livello di maturità accettabile e l’elenco delle librerie disponibili sotto forma di pacchetti rock è in lento ma costante aumento, ma ci sono alcune applicazioni o framework che ne traggono beneficio per l’installazione e la gestione delle loro dipendenze come per esempio Kepler (un framework per lo sviluppo web generico in Lua), Orbit (un altro framework per lo sviluppo web in Lua, ma MVC oriented) e Sputnik (un wiki scritto in Lua, leggero ma estendibile). Per la cronaca, ecco invece cosa si era costretti a fare solamente un anno fa per avere un’installazione minimale di Lua in Windows e cominciare ad aggiungere librerie come LuaSocket.

We Can’t Stop Here! This Is Bat Country!!

Scusate per il messaggio inutile, ma l’ultimo upgrade di WordPress alla versione 2.6 sembra avermi portato a 2 o 3 problemini sparsi qua e là per cui mi tocca fare qualche prova di troppo. Per renderlo un po’ meno inutile posso dirvi che mi sono finalmente deciso a installare Debian sul mio NSLU2 (per l’occasione ho scelto la più aggiornata Lenny, sono temerario). Il device in oggetto è ufficialmente supportato con alcuni pacchetti mirati specificatamente ad esso ed è un’altra vita rispetto a SlugOS/BE. Nonostante quest’ultima sia leggermente più ottimizzata poiché specificatamente creata per uso su sistemi embedded, con Debian il sistema sembra comportarsi comunque piuttosto bene soprattutto dopo qualche tweak. More to come, ora devo sistemare qualche pezzo di blog…

Ancora su lambda e closure in PHP

Anche se a pochi giorni di distanza, ho pensato di tornare a parlare di funzioni lambda e closure in PHP approfittando di un nuovo aggiornamento della RFC (con relativa patch che implementa quanto descritto) in cui sono state finalizzate alcune idee e sono stati introdotti alcuni nuovi concetti.

Prima di tutto è stata presa una decisione per quanto riguarda la sintassi dichiarativa, infatti precedentemente erano state formulate due possibilità. La prima prevedeva la cattura delle variabili esterne alla chiusura tramite una nuova keyword creata ad hoc, lexical:

$lambda = function($arg1, $arg2) { lexical $reference, &$valueByRef; // ... };

La seconda, quella che è stata effettivamente scelta, prevede invece il riutilizzo della keyword già esistente use:

$lambda = function($arg1, $arg2) use ($reference, &$valueByRef) { // ... };

Qualcuno preferiva la prima opzione e personalmente ero dello stesso avviso, ma alla fine la scelta è stata dettata dall’intenzione di raggiungere un compromesso in maniera tale da ottenere le stesse funzionalità mantenendo la consistenza con l’attuale semantica di PHP e senza intaccare la retrocompatibilità.

La prima estensione nella RFC riguarda invece l’utilizzo della keyword static per stabilire se importare o meno $this all’interno di una chiusura definita all’interno del metodo di una classe. Non effettuare l’importazione di $this all’interno di una chiusura quando non necessario permette di ottenere un risparmio non solo in termini di velocità d’esecuzione, anche si tratta di differenze veramente minimali, ma anche e soprattutto di memoria, evitando che delle long-lived closure possano tenere in vita inutilmente le istanze delle classi in cui esse sono state create. La chiusura che cattura $this infatti impedisce che il refcount interno per l’oggetto che referenzia possa arrivare a 0 e ciò ne comporta l’esclusione dal processo automatico di raccolta delle risorse che viene effettuato dal garbage collector. Vediamo un esempio pratico con tanto di risultato:

class NRK { private $_whoAmI = __CLASS__; public function foo() { $method = __METHOD__; return function() use ($method) { return sprintf("created in %s (w/ \$this):\n%s", $method, print_r($this, true) ?: 'null' ); }; } public function bar() { $method = __METHOD__; return static function() use ($method) { return sprintf("created in %s (w/o \$this):\n%s", $method, print_r($this, true) ?: 'null' ); }; } } $nrk = new NRK(); $fun1 = $nrk->foo(); $fun2 = $nrk->bar(); echo $fun1(), "\n", $fun2(); /* created in NRK::foo (w/ $this): NRK Object ( [_whoAmI:NRK:private] => NRK ) created in NRK::bar (w/o $this): null */

In realtà trovo che sarebbe molto più comodo e pulito avere $this importata in automatico nel caso essa venga esplicitamente richiamata nel corpo della closure, per il compilatore non sarebbe difficile accorgersene ed agire di conseguenza, ad ogni modo non mi piace l’uso della keyword static dal momento che rende ancora più verbosa la definizione di una chiusura.

Proseguendo con le nuove funzionalità, nell’ottica di una maggiore integrazione con PHP sono state estese le classi ReflectionMethod e ReflectionFunction implementando il metodo getClosure() che permette di ottenere una funzione lambda generata dinamicamente partendo da una funzione o da un metodo di istanza/classe:

class NRK { public function instanceMeth() { return __METHOD__; } public static function staticMeth() { return __METHOD__; } public static function methWithArgs($a, $b) { return $a + $b; } } $instance = new NRK(); $class = new ReflectionClass('NRK'); $fun1 = $class->getMethod('instanceMeth')->getClosure($instance); $fun2 = $class->getMethod('staticMeth')->getClosure(); $fun3 = $class->getMethod('methWithArgs')->getClosure(); echo $fun1(), "\n", $fun2(), "\n", $fun3(5, 3); /* NRK::instanceMeth NRK::staticMeth 8 */

Per finire, un’altra novità ispirata dall’implementazione dell’oggetto Closure riguarda la generalizzazione del concetto di oggetto invocabile attraverso l’implementazione di un nuovo metodo magico, __invoke(). Un esempio vale più di mille parole:

class CallableObject { public function __invoke () { return 'Guess what?'; } } $callable = new CallableObject(); $notCallable = new stdClass(); echo '$callable is ', is_callable($callable) ? '' : 'not ', "a callable object\n"; echo '$notCallable is ', is_callable($notCallable) ? '' : 'not ', "a callable object\n"; echo $callable(); echo $notCallable(); /* $callable is a callable object $notCallable is not a callable object Guess what? Fatal error: Function name must be a string in [...] */

Tirando le somme lo stato dell’implementazione di lambda e closure in PHP sembrerebbe essere in uno stato particolarmente avanzato al punto tale che lo stesso Andi Gutmans su php.internals ha chiesto, soprattutto ai release manager, di pensare se sia effettivamente possibile includere tutto questo già in PHP 5.3. In effetti PHP 5.3 sarà già ricco di novità di per sè (namespace e collaterali, LSB, __callStatic, etc) quindi l’introduzione di un’altra nuova feature è da valutare bene, tuttavia vista la buona salute della proposta e dei lavori per implementarla sarebbe un peccato dover aspettare un altro anno o più. Intanto però c’è anche chi si chiede: ma alla fine le novità di PHP 6 saranno rappresentate solo dal supporto per Unicode?