domenica 9 luglio 2017

POSSE è passato anche da Bologna

POSSE ovvero Professors' Open Source Software Experience è una sorta di linea guida per aiutare i professori universitari e, di riflesso, gli studenti ad avvicinarsi al mondo dell'Open Source. L'idea è abbastanza semplice: i professori devono arrivare ad insegnare agli studenti come collaborare in un progetto HFOSS (Humanitarian Free Open Source Software - software che abbia impatto sociale) attraverso l'apprendimento loro stessi degli strumenti e delle metodologie alla base della cultura Open Source.
POSSE si fonda su tre livelli, chiamati stage:
  1. in questa fase preliminare si prende conoscenza con gli strumenti e le licenze, nonché si inizia a valutare obbiettivi semplici e raggiungibili sui quali far lavorare gli studenti;
  2. in questa fase face-to-face si lavora tutti assieme in un workshop di due giorni per mostrare i risultati della fase 1, le esperienze, nonché valutare ed inserire obbiettivi di maggior impatto pratico per la fase successiva;
  3. in questa fase l'applicazione ad un progetto Open Source dovrebbe trovare risvolto pratico e dare soddisfazione a studenti e docenti che, nel frattempo, sono diventati membri effettivi della comunità Open Source.

Pur non avendo mai partecipato ad uno schedule POSSE mi immagino che gli stage possano essere così schematizzati:
  1. apprendimento di strumenti quali canali IRC, mailing list, revisione del codice, test;
  2. condivisione di esperienze e modalità di insegnamento degli strumenti di cui alla fase precedente, nonché loro applicazione pratica nei corsi di laurea;
  3. sviluppo di una o piu' patch per un progetto prescelto.

Francamente ritengo che i tempi per gli stage siano abbastanza lunghi, si parla ad esempio di 6 mesi per il solo stage 1!
Tuttavia occorre ricordare che si parla di didattica accademica, e quindi occorre anche avere il tempo di introdurre gli strumenti nel corso di laurea, e questo potrebbe spiegare la necessità di un simile periodo temporale.

Ma perché questa digressione su POSSE?

A Luglio si è svolto lo stage 2 dell'anno 2017 presso l'Università di Bologna, ma ahimé i partecipanti erano tutti stranieri e non leggo nessun nome italiano delle università limitrofe. Questa è secondo me una pessima notizia che dimostra ancora una volta l'arretratezza culturale alla quale sono sottoposti gli studenti delle università della mia zona.

Mi auguro che molti altri docenti e ricercatori italiani possano unirsi all'idea POSSE o a simili iniziative e possano mettere a frutto una maggiore esperienza nel mondo Open Source e nelle community ad esso collegate.

sabato 8 luglio 2017

Vivere in org-mode

Un interessante articolo sull'utilizzo di org-mode per tenere organizzate le proprie attività, e seguire la filosofia GTD (Get Things Done).
Personalmente, da affezzionato utente Emacs, uso già org-mode per molte delle mie attività, ma l'approccio conciso e ben illustrato di questo articolo potrebbe aiutare altri utenti ad avvcinarsi meglio ad Org e a utilizzarne appieno le infinite possibilità.

venerdì 7 luglio 2017

pgloader e gli URL (compresi quelli di MySQL!)

Un interessante articolo sull'ultima versione disponibile di pgloader.
Noto con piacere che lo script permette di collegarsi autonomamente ad un database differente, es. MySQL, e migrarne il contenuto verso un database PostgreSQL. Ancora meglio, pgloader è in grado di riconoscere e interpretare gli URL che gli vengono forniti scaricando file tramite altri protocolli, come HTTP, per poi leggerli e dump-arli verso una istanza PostgreSQL.

Eclipse Oxygen

Dal mese scorso è disponibile Eclipse Oxygen, la nuova versione del popolare IDE tuttofare.
Questa versione ha diverse migliorie sia alla parte di sviluppo Java che alla parte di gestione git. Una cosa che noto è che sempre di piu' gli sviluppatori pongono l'attenzione verso scorciatoie da tastiera per aiutare e velocizzare l'interazione con l'ambiente, come ad esempio CTRL-e per ciclare fra i tab degli editor o ALT-c per entrare nello staging git.

mercoledì 5 luglio 2017

Do not buy via Royal Trendy

I decided to buy to my wife a couple of shoes with Foo Fighters printed on the sides, and of course this revealed to be a great mistake!
Usually I buy from good sites, and usually I check before buying, but this time I did trust who presented me the site, which is a kind of error I did not do being a very un-trusty man. And as a result, this story tells me to be even less trusty about what I don't know well.



1 tl:dr

The short story is: I did not get the shoes I purchased, neither I got back the money and I did not get any kind of decent answer about what is going on. Consider that I placed the order about one hundred days ago, which is a very decent period of time to produce any kind of good.
On my email sent on the beginning of june I clearly stated I was going to put all the whole stuff on the net if I did not get any answer. I waited for another month, which is a very decent period of time to put together a couple of sentence and reply back, but nothing hit my inbox, so here I'm writing down all the whole "conversation" I did not have with folks at Royal Trendy.


I waited for an order update (or better an order shipping) for around 100 days (yes, it is a very high number).
I wrote 14 emails in the above period of time, and got 3 replies, that is only 21% of my emails did catch the attention of the support center, and this is not what I would label a "good support".


I URGE YOU TO DO NOT BUY ANYTHING FROM ROYAL TRENDY SINCE CHANCES ARE YOU WILL LOOSE YOUR MONEY!
It happened to me and to a lot of other people.

2 The order and the first problem

Just after placing the order I did not get any message about order confirmation. It was quite strange, since money was already taken from my credit card. I contacted the support staff, that told me I mispelled my email address, which sounds really strange since I'm used to write it down (as it is one of my job tools), as well as my browser has it already stored, but hey, I'm just an human being and errors could happen.

2.1 8 days and no news

After 8 days since the order date I wrote the following to get some news about my order.


Luca Ferrari  Mon, Mar 20, 2017 
To: support@
Dear Royal Trendy,
I kindly ask for an update about order #4979 shipping to Modena, Italy.
According to the status page
the order has been accepted but not yet shipped. Please consider the
order has been filled on March the 12, 2017.

Regards,
Luca

and the reply was quite generic, but I accepted the estimated times and waited longer.



Royal Trendy <myroyaltrendy@> Mon, Mar 20, 2017 
To: Luca Ferrari

Hello Luca,

After an order has been placed, it is promptly sent to our factory 
where we will print and ship your item(s) within 7-10 business days. 
Below are expected delivery times based on your location.

Please note: Due to the popularity of certain items in our catalog, 
shipping times may take longer than the estimates below.

When your order ships you can request your tracking number 
via email: support@

US Shipping Time Estimates

Shoes: 2-3 Weeks
Other Products: 2-3 Weeks

International Shipping Time Estimates

Shoes: 2-4 Weeks
Other Products: 2-4 Weeks

If your items have not arrived within 60 days of the date of original purchase, contact customer service.

https://www.royaltrendy.com/pages/faqs

Best Regards,
Royal Trendy

2.2 6 weeks and no news

So, six weeks passed and I asked for any news.


Luca Ferrari  Sun, Apr 23, 2017 
To: Royal Trendy <myroyaltrendy@>
Dear Royal Trendy customer support,
I'm coming back to ask you for information about my order #4979 that
is still listed as "getting ready". Please note I've placed my order
on March 12nd, I believe I've waited enough time for it to be shipped
to the final destination.
Please provide me a feedback.

Regards,
Luca

No news at all, so I asked it again after 6 weeks and 4 days.



Luca Ferrari  Thu, Apr 27, 2017 
To: Royal Trendy <myroyaltrendy@>, support@
Dear Royal Trendy,
sorry to bother again, but I would like to have a feedback about my
order #4979 placed on March 12, and still in the phase of "getting
ready".
Could you please provide me an estimated delivery date and/or an
update about the order?

Thanks,
Luca


Hurray! I got an answer telling me the order was on the production line, so I just have to wait a little more and all will be fine!


Royal Trendy <myroyaltrendy@> Fri, Apr 28, 2017 
To: Luca Ferrari
Hello Luca,

Thank you for contacting us. We sincerely apologize 
for the late update. Our fulfillment team had some 
issues which caused the delay of shipping the items 
according to our estimated days given. However, 
they are now actively working on this so we can 
ship the order the soonest as we can. 
Upon checking your order is now in the production 
and currently being process. Once done and ready 
to shipped we will send you a tracking details.

We appreciate your patience.

Best Regards,

Royal Trendy

2.3 8 weeks and no update

Waiting a little more I found myself after almost 8 weeks, so I wrote again asking for any news.


Luca Ferrari  Wed, May 10, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Dear Royal Trendy staff,
sorry to bother you again, but another couple of weeks passed and
apparently no order update was issued: the order page still reports
"We've accepted your order, and we're getting it ready. Come back to
this page for updates on your order status. ".
we are currently 8 weeks after the initial order, could you please
provide me any useful feedback, since the timing is twice what you
declare on your scheduling policy?

Thanks,
Luca

Again no asnwer, so I have to write again after another 5 days. Please note a pattern here: Royal Trendy started to not reply on the first contac.



Luca Ferrari  Mon, May 15, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Dear Royal Trendy staff,
I'm still waiting for an answer about the great delay in this order
#4979, that according to the today status page is still in the status
"accepted" and not even delivered. Please consider I've placed the
order on March 12, 2017, so we are at 9 weeks without a delivery,
while you clearly specified 4 weeks for international shipping.

According to your reply on April 28, the items should be now ready for
be shipped.

Could you please provide any information or, in the case you believe
you are not able to product/deliver the item, the refund policy?

Regards,
Luca

2.4 Entering Susan…

So, after the second email at around 9 weeks since the order, I got the following reply that was meant to assure me that, despite a lot of troubles, there was a person named Susan taking care of my order, as well as others.



Royal Trendy <myroyaltrendy@> Mon, May 15, 2017 
To: Luca Ferrari
Hello Luca,

Thank for contacting us. I'm sorry that you have yet to receive your order.

First, I want to personally apologise to you. 
We're a bit behind schedule at the moment as 
one of the owners' brother recently passed away.

This is a family business. It hit us hard. 
So, with everything going on our production 
has went down due to the number of staff 
taking time off to grieve and deal with everything 
that has surrounded his passing.

We're still producing shoes, of course, but we've been short staffed, 
so we are a bit behind schedule. It's been a difficult time.

I'm going to ask Susan at the factory to look into this for you.

We're fully staffed. In fact, Susan just brought on 7 new people 
to help us speed up the back orders.

I've never seen socks & shoes fly at the door so fast. 
Turn around time is amazing for back orders.

Orders are usually process and shipped with 7-10 
business days of purchase.

After that you will receive a shipment notice email.

The email will include your tracking number.

There is overwhelming popularity of some of our items. 
Some shipping times may take longer than the estimates below,
 plus as I mentioned we are a bit behind schedule 
due to the death in the family.

You can also check the status of your tracking number here:
https://www.royaltrendy.com/pages/order-lookup

Your package will be delivered to you by your local postal carrier.

Once you have your tracking number you may enter it here: 
http://www.17track.net/en

This will let you check the status of your delivery.

After receiving your tracking number - 
it can take 6-8 business day before the tracking 
appears in your country about your shipment.

You can look here to see more about our 
shipping policy and delivery times:

https://www.royaltrendy.com/pages/faqs

We appreciate your patience and please do let us 
know if you have any additional questions.

Best Regards,

Royal Trendy


Unluckily Susan was not able to provide any kind of news I kindly asked more and more times…

2.5 No more news at all

Since the introduction of Susan, Royal Trendy simply did not replied to any other message.


Luca Ferrari  Tue, May 16, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

On Mon, May 15, 2017 at 11:23 PM, Royal Trendy <myroyaltrendy@> wrote:
> I'm going to ask Susan at the factory to look into this for you.
>
> We're fully staffed. In fact, Susan just brought on 7 new people to help us
> speed up the back orders.


While we are waiting for Susan to provide me an answer about WHEN my
order will be shipped, and assuming that nothing could turn a 4 weeks
delivery into a 10 weeks not-ready order, could you please also
provide me information about the refund policy? Of course, as you can
imagine, I can wait for another couple of weeks to get my order
shipped, but not any longer.

Thanks,
Luca

Luca Ferrari  Fri, May 19, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Dear staff,
I'm still waiting for some good news from Susan or anyone else about
my order #4979 placed on March 12, 2017 (10+ weeks).
Please provide either some _concrete_ information or the refund policy.
In the meantime I've received your request for a feedback about the
product, which sounds a little awkward since I've not the produce yet
and I really would not like to start a bad feedback campaing.

Regards,
Luca

Luca Ferrari  Tue, May 23, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Hello,
I think I deserve some news from Susan or someone else about my
questions regarding order #4979 which is aging three months right now.

Luca

Luca Ferrari  Wed, May 24, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Dear staff,
another week passed and other three emails without a reply.
So what does Susan say about order #4979 and its delivery timetable?
In the case Susan does think the order cannot be product any more,
just advice and refund money back. I believe this could be a quite
good way to solve the problem and keep going with other orders. On the
other hand, if you believe the order is on its way, advice about the
delivery timetable and that's fine too.
But please, don't ignore your clients and reply.

Luca

Luca Ferrari  Mon, May 29, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Dear staff,
could you please advice about the status of the order #4979 placed 3+
months ago? The last piece of information you gave me, about 14 days
ago, was that Susan was personally checking the order to deliver it as
soon as possible.
Another couple of weeks gone by, I deserve the right to know the
status of my order.

Luca

Luca Ferrari  Wed, May 31, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Folks,
we are now at the end of may, and still I don't get any advice about
my order. Can you please reply me with some information about the
delivery sdtatus or, in the case you are no more able to product it,
the refund policy?
Not replying will make me think you have no interest in fixing the situation.

Luca

Luca Ferrari  Tue, Jun 6, 2017 
To: Royal Trendy <myroyaltrendy@>, support@

Dear all,
this is the fifth email I send you without any reply.
I pretend to get an advice about my order, #4979, placed on March the
12 2017. Your e-commerce still reports the order as "accepted".
As you can imagine, I've no any patience to wait for my order, so I
propose to either prove me you shipped it or refund my money.
On the other hand, I will consider taking actions including put on the
public all this email thread.
Threfore, if you really aim to solve the problem, contact me (even on
the phone, you have my number).

Regards,
Luca





Luca Ferrari  Mon, Jun 26, 2017 
To: support@
Dear Royal Trendy,
I kindly ask for an update about order #4979 shipping to Modena, Italy.
According to the status page
the order has been accepted but not yet shipped. Please consider the
order has been filled on March the 12, 2017.

Regards,
Luca

2.6 Situation as of today

Today I still got no answer, I still got no shoes, still got no update and my money is, quite frankly, lost.


Luca Ferrari  Mon, Jul 3, 2017 
To: support@

Folks,
any news? We are now at _one hundred days_ since the order has been placed.

Luca 
 



Interestingly, trying to track my order from the main site results in No order found error, which I suspect is a quite true answer according to the whole situation.
I've tried to contact the owners via Facebook and the contact module on their main site but no reply appeared.

As laready stated: let me know what happened and I will post an update.

martedì 4 luglio 2017

1000

Cara Carmensita,
sono 1000 giorni, o meglio, sono 1000 mattine che mi alzo con quel senso di vuoto, a tratti piu' forte.
In questi 1000 giorni non posso dire che mi ci sono abituato, sarebbe irrispettoso, semplicemente mi sono convinto che quella sensazione c'è e ci sarà, e così ho mio mal grado dovuto accettare la cosa.
Come fanno tutti.


Mille giorni sono tanti o sono pochi?
Onestamente non saprei, certo è curioso, quasi macchinoso, che questo numero ricorra proprio in questa data per me molto felice. Dopotutto è insito in come noi misuriamo il tempo, circolarmente, riuscire a far ricadere ogni data su  n'altra, ma se proprio lo vuoi sapere al momento non trovo altri legami così evidenti.

martedì 27 giugno 2017

PgAdmin III è ancora vivo!

PgAdmin è sempre stato il tool di riferimento per l'amministrazione di un cluster PostgreSQL mediante interfaccia grafica.
Onestamente non ho mai usato molto tale applicativo, se non quando ero alle prime armi e faticavo a districarmi sulla linea comando di psql,
ma questo non significa che il tool non sia valido, anzi è uno dei piu' completi che abbia mai visto.


La versione forse piu' nota di PgAdmin è la 3, e infatti spesso si trova il nome PgAdminIII. L'interfaccia grafica era spartana ma funzionale, le wxWidgets facevano il loro scopo e rendevano l'applicazione portabile, ma l'eleganza ne soffriva abbastanza.
L'anno scorso è stata rilasciata la versione stabile di PgAdmin 4, completamente riscritto in Python e basato su interfaccia web.
Ciò ha rappresentato una discontinuità nel mantenimento della versione 3, basata su altra tecnologia.


Mi ha fatto piacere scoprire che esiste un fork di PgAdminIII mirato a mantenere il codice attivo e funzionante per ancora qualche versione di PostgreSQL. In effetti, mea culpa, ammetto che l'installazione di PgAdmin 4 non mi risulta mai molto semplice, sicuramente per la mia mancanza di conoscenza Python (nemmeno la wheel sembra funzionare sul mio povero computer!).


Lunga vita a PgAdmin (III o IV)!

domenica 25 giugno 2017

Riflessioni su pl/java

Bruce Momjian ha pubblicato un breve articolo circa l'adozione di pl/Java.
I linguaggi pl/ sono una serie di bindings per utilizzare un linguaggio di programmazione differente dal "plain" SQL all'interno di una istanza PostgreSQL, ovvero lato server.
Pertanto pl/java altro non è che un binding per poter utilizzare il linguaggio Java direttamente all'interno del server PostgreSQL, ad esempio per la costruzione di trigger o stored procedures. Io stesso ho utilizzato in passato pl/java in produzione, e ho anche tenuto dei mini corsi e dei seminari sul suo utilizzo (si veda ad esempio qui), nonché ho provato a contribuire a minime porzioni di codice.


Pl/Java risulta abbastanza ostico rispetto ad altri linguaggi pl/, e ciò è dovuto alla natura di Java (non certo ai suoi limiti), in particolare alla fase di compilazione che richiede sempre:

  • un deploy di una forza compilata del codice;
  • un pezzo di codice collante SQL che possa "iniettare" le funzionalità Java dentro al server PostgreSQL.

Pl/Java si basa per scelta progettuale su Java Native Interface (JNI), scelta abbastanza efficiente se si considera che il codice deployato risulta locale al server cluster e quindi non è necessario utilizzare chiamate remote (es. RMI). In modo coerente con le scelte architetturali di PostgreSQL, pl/java utilizza una virtual machine backend per ogni processo attivo, richiedendo quindi dei tempi di startup piuttosto lunghi (o diciamo piu' lunghi rispetto ad altri pl/).


L'implementazione di pl/java è elegante e interessante, permette la sincronizzazione dei thread su un mutex singolo e consente di interagire con gli oggetti di backend arrivando perfino a implementare una sorta di SQL MED del poveraccio.


Eppure pl/java non sfonda, come nota appunto Bruce nel suo articolo.


Avendolo usato in produzione posso affermare che pl/java è fortemente condizionato dalla competizione con altri linguaggi pl, in particolare quelli di scripting. Effettivamente io stesso, ad un certo punto, ho modificato porzioni di codice abbastanza sostanziose per passare da pl/java a pl/perl. Ovviamente ciò è stato possibile perché potevo scrivere codice in entrambi i linguaggi, competenza non sempre presente, e l'esigenza principale è stata quella di dover garantire una modifica on-the-fly al codice sorgente anche quando non fosse disponibile un ambiente di sviluppo completo. Detto in due parole: per usare pl/java occorre impostare un progetto (Eclipse o similare), compilare, deployare e "iniettare" il codice nel backend, in pl/perl basta un editor di testo per modificare il codice e la fase di deploy si riduce ad iniettare il codice nel backend.


Personalmente ritengo che pl/java sia uno strumento interessante e importante, e che la sua adozione in contesti fortemente Java-based (per competenze, librerie, stack) sia opportuna, ma solo da un punto di vista degli sviluppatori. Difficilmente un DBA utilizzerà pl/java per implementare le proprie logiche di controlle server-side.

sabato 24 giugno 2017

Ulteriori considerazioni sul planet PostgreSQL italiano

Qualche mese fa avevo espresso brevemente alcune considerazioni sul futuro dell'aggregatore di blog dell'associazione ITPUG, ovvero il Planet PostgreSQL Italiano.
La mia preoccupazione era dovuta al fatto che nei primi mesi dell'anno corrente non vi erano stati post relativi all'associazione e al mondo PostgreSQL in generale, e infatti facevo notare come solo io avessi pubblicato 13 post fra Gennaio e Aprile.


Ad oggi, giro di boa della metà anno, la situazione non è migliorata, e ancora una volta pare che il planet sia utilizzato solo per aggregare i miei post:



Ancora una volta sento la necessità di sollecitare l'associazione e il consiglio a valutare l'utilizzo di questo strumento di aggregazione e informazione, che risulta ormai evidentemente abbandonato a se stesso e in rapido declino di contenuti (a differenza del sempre aggiornato Planet PostgreSQL.

Perl _ filehandle

Leggendo la documentazione di :Find mi sono accorto di una frase nella sezione di esempio:


the "_" is a magical filehandle
that caches the information from the preceding "stat()", "lstat()", or
filetest.

e così incuriosito sono andato subito ad approfondire nella documentazione di stat:


If "stat" is passed the special filehandle consisting of an
underline, no stat is done, but the current contents of the stat
structure from the last "stat", "lstat", or filetest are returned.

Diciamo che _, a differenza della variabile topic non è una vera variabile ma un segnaposto particolare che viene interpretato come accesso alla cache dell'ultima operazione stat effettuata. E' facile costruire un esempio che mostri questi:



#!env perl

use v5.20;

my $file_name = $0; # myself

my @stat_values   = stat $file_name;
my @cached_values = stat _;

say "Same values for $file_name!" if ( $stat_values[1] == $cached_values[1] # inode
           && $stat_values[7] == $cached_values[7] # size
           && $stat_values[8] == $cached_values[8]  ); # atime

Lo stesso utilizzo non può essere effettuato con File::stat, che infatti riporta nella documentazione:


As of Perl 5.8.0 after using this module you cannot use the implicit $_ or
the special filehandle "_" with stat() or lstat(), trying to do so leads
into strange errors.

venerdì 23 giugno 2017

Secondary Selection & Emacs

Una discussione sulla mailing list Perl6 mi ha portato a fare una rapida ricerca e scoprire che, ovviamente, Emacs supporta anche
la Secondary Selection. Questa è una modalità nativa di X11 (che in realtà supporta fino a 4 clipboard coesistenti) che funziona un po'
come il kill-ring di Emacs stesso, ma che nella sua implementazione non si appoggio al kill-ring.
In sostanza è possibile copiare e incollare testo indipendentemente dalla regione selezionata e senza modificare il contenuto del kill-ring,
consentendo quindi ad Emacs di gestire fino a due clipboard contemporanee, una delle quali gestita tramite un ring e collegata
alla clipboard principale di sistema.

domenica 18 giugno 2017

Non usate :wq! per uscire da vi!

Una cosa che non capisco di Vi(m) e dei suoi utenti è la costante ed errata abitudine di usare il comando q! per uscire dall'editor.
Ho già scritto in precedenza riguardo questo soggetto, ma sono incappato in una innocente immagine di un minicorso del linguaggio C che, ancora una volta, insegna a chi è alle prime armi ad uscire da Vi con la combinazione mortale :wq! (qui l'immagine del post).


Vediamo di approfondire ancora una volta.
Anzitutto cosa suggerisce l'aiuto in linea di Vi? Eseguendo :help si ottiene qualcosa del genere:


*help.txt*      For Vim version 7.4.  Last change: 2016 Mar 31

                        VIM - main help file
                                                                         k
      Move around:  Use the cursor keys, or "h" to go left,            h   l
                    "j" to go down, "k" to go up, "l" to go right.       j
Close this window:  Use ":q<Enter>".
   Get out of Vim:  Use ":qa!<Enter>" (careful, all changes are lost!).

Andiamo bene! L'help in linea suggerisce di uscire dall'editor con :qa!, in sostanza l'equivalente di una kill -9!


Eppure ci sono alcuni modi molto piu' furbi di uscire da Vi senza rischiare di perdere i dati, e il mio preferito è quello di usare ZZ che esce salvando se necessario le modifiche. Perché questa cosa è importante? Perché forzare un aggiornamento del file ad ogni  uscita ne cambia il timestamp e potrebbe creare conflitti con strumenti di controllo delle versioni e di build automatico.
Ma non solo, se si digita :help :x si scopre che:


*:x* *:xit*
                        Like ":wq", but write only when changes have been
                        made.

ZZ                      Write current file, if modified, and quit (same as
                        ":x").  (Note: If there are several windows for the
                        current file, the file is written if it was modified
                        and the window is closed).

Mettiamo ora a confronto le varie modalità:


comando caratteri rischio di perdita modifiche
:qa! 4 si
:wq! 4 no
ZZ 3 (contando SHIFT) no
:x 2 no


Quindi perché non istruire gli utenti da subito ad usare modalità di uscita smart, visto che risultano perfino piu' compatte (in termini di caratteri) rispetto a quelle brutali?

venerdì 16 giugno 2017

Perl and regexps are too much verbose (!)

A colleague asked me a quick Perl way to check if a string contains only a predefined set of chars excluding a few ones.
Easy pal!
Regexp to the rescue!

Then I was asked for a way that did no use a regular expression, because "you know, regular expression can be somehow verbose".
Gosh!
My answer was simply "you don't use regexps a lot!".

I don't believe I have to explain to any (Perl) programmer that regexps have been designed to express in short a whole set of choices,
more in general an alphabet (in the most wider concept).

But let's move on, and after showing a quick and dirty one liner such as:


perl -E 'say "Wrong $_" unless ( /^[0-9]+$/ ); ' -F

I got another strange sentence as "yeah, but I don't like Perl too much, it is somehow verbose as a language".
And again, my answer was: "you don't use it regularly!".

It is clear Perl was seen in the wrong way, since both the language as well as regular expressions can be really short, as well as
a one liner…
No other comments required!

Distanza fra date "note" in Perl

Come si può fare a conoscere se una serie di date note si trovano ad una distanza interessante l'una dall'altra?
Facile con un po' di Perl!


Anzitutto la definizione: per distanza interessante intendo un numero di giorni multiplo di 10, anzi meglio, potenza di 10, ovvero 100, 1000, ecc.
Detto questo, costruiamo la struttura base:



#!env perl

use v5.20;
use DateTime;

my $begin = DateTime->new( year => ..., month => .., day => .. );
my $now = $begin->clone();
my $dates = [
    { day => 4, month => 7 }
    , { day => 19, month => 7 }
   ...
    ];

push @$dates, { day => $begin->day, month => $begin->month };
my $base = 10;

Con $begin si indica la data di partenza, mentre in $dates si inseriscono giorno e mese di alcune date a voi significative.
Per capirsi, $begin potrebbe essere la data di nascita di vostro figlio e $dates contenere il vostro matrimonio, laurea, ecc.
Da notare che inserisco automaticamente la data di partenza nell'array delle date da cercare, così da valutare la data contro se stessa
spostata chiaramente di alcuni anni.
Fino a qui, nulla di sorprendente. Beh, anche il resto è abbstanza noioso:



for ( 1 .. 100 ){
    $now->add( years => 1 );
    for my $when ( @$dates ){
 $now->set( day => $when->{ day }, month =>  $when->{month} );
 my $delta = ( $now->epoch - $begin->epoch ) / ( 60 * 60 * 24 );
 next if ( $delta % $base != 0 );
 say "La data " . $now->dmy . " si trova a $delta giorni da " . $begin->dmy 
           if ( ( log( $delta )/log( $base ) ) =~ /^\d+$/ );
    }
}

In un ciclo di 100 anni (perché oltre diventa poco interessante, almeno per voi visto che non ci sarete piu') si processa un anno alla volta
sommandolo alla data di partenza $now (clone della vera data). Contro tale "annata" si testano tutte le date ricercate per vedere se
la distanza in giorni $delta è multiplo di 10 ($base) e piu' precisamente se è un logaritmo in base 10.
Solo di quelle date si effettua una stampa a video.

lunedì 12 giugno 2017

Cosa sono gli Emacs mode? Major mode, minor mode, oh my...

Uno dei concetti chiave di Emacs che mi pare sia molto spesso sottovalutato da chi non lo utilizza è quello dei mode.
Emacs è un editor multi-mode, ovvero è possibile attivare piu' modi contemporaneamente.
A loro volta i mode si suddividono in due categorie principali:

  • major mode rappresentano il contesto di un buffer;
  • minor mode forniscono funzioni trasversali fra uno o piu' buffer.

Molto spesso la differenza non viene colta, ma è importante perché l'uso combinato dei mode può personalizzare tantissimo il comportamento
di Emacs.
Anzitutto Emacs ammette un solo major mode per buffer, mentre virtualmente infiniti minor mode possono essere attivati su ogni buffer.


Un major mode definisce il "contesto" di utilizzo del buffer, nonché le funzioni principali fornite in quel buffer. Ad esempio
se si sta editando un buffer che contiene uno script Perl, il relativo major mode fornirà funzioni legate a Perl. Analogamente, se
si sta visualizzando il contenuto di una directory, il relativo major mode (es. dired) fornirà le funzioni principali
per interagire con il buffer. Un major mode può anche "rimappare" alcuni tasti funzione per rendere piu' facile l'utilizzo all'interno
di tale buffer.


Un minor mode fornisce sottofunzioni specifiche all'interno del buffer, e magari a livello globale su tutti i buffer. L'esempio classico
è quello del correttore ortografico (es. flyspell) che agisce sul testo indipendentemente questo sia codice o testo o una chat.


Per meglio comprendere questi concetti, mi si passi un blasfemo paragone con Eclipse.
In Eclipse è possibile editare progetti Java, C/C++, Perl, PHP, Python (e altri). A seconda del tipo di progetto Eclipse carica funzioni
differenti e fornisce refactoring e renaming in modo differente, e questo è esattamente quello che fa un major mode Emacs. Ecco perché poco
sopra ho parlato di "contesti" del buffer.
Tornando ad Eclipse, i commenti e le parole chiave vengono evidenziate in modo analogo fra i vari linguaggi, come pure i marker degli errori
e dei problemi, e questo è quello che fa il minor mode Emacs (ok, per i font c'è la fontify, ma non scendiamo a questo livello).
E i template del codice? Eclipse fornisce template per, ad esempio, i get e set (getter e setter), cosa che in realtà richiede due passaggi: uno di
front-end e uno di backend. Il front-end mostra la UI all'utente, il back-end scrive il codice contestualizzato. Questa operazione può essere
fatta in Emacs tramite un altro minor mode (es. yas).


Per riassumere si tenga sempre presente che il major mode stabilisce cosa è possibile fare con un buffer, sia in termini di contenuti, che di tasti funzioni,
che di funzioni stesse, mentre un minor mode stabilisce quali arricchimenti si possono fornire al contenuto del buffer.
La linea di separazione non è così marcata, perché come è noto Emacs è un ecosistema che si piega su stesso e si espande, ma per avvicinarsi a questo
strumento quanto sopra dovrebbe bastare.

domenica 11 giugno 2017

Magit spin-offs: another way to name a tracking branch.

A few days ago my attention was caught by an entry in the Magit Branch Pop-up buffer: Create a new spin-off.
Uh?




What the hell is a spin off?
According to the Magit Branching documentation, a spin-off is nothing more than a tracking branch.
A tracking branch, created on the git side with the -t switch, is a branch that knows (i.e., it has
knowlegde) about the branch it was originated from. Well, every branch in git has, of course, knowlegde
about its ancestor branch (how would you merge otherwise?), but in this case
the knoweldge is made explicit by the tracking feature.


In particular, when a tracking branch is checked out git advices about commits that made the
current (tracking) branch diverging from its ancestor, something like the following:



% git checkout b
Switched to branch 'b'
Your branch and 'master' have diverged,
and have 1 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

In the above example you can see that the b branch is behind master two commits, as well as after master by one commit.
In other words, your b branch has done a single commit while master advanced by two other commits. As git
suggests, you can pull and git will automagically fetch updates from the master branch into b.
And in fact:



% git pull
From .
 * branch            master     -> FETCH_HEAD
Merge made by the 'recursive' strategy.

The tracking is useful to know transparently when and how (much) your branch is diverging from the source, and this of course
is true both for local commits and remote ones:



% git status
On branch b
Your branch is ahead of 'master' by 2 commits.
  (use "git push" to publish your local commits)
nothing to commit, working tree clean

What happens into Magit? Well, once you checkout a tracking branch the popup buffer shows that is unmerged from the source branch, and
it does suffice to F pull to prompt the merging popup.





So, to recap, a Magit spin-off lies a tracking branch, which in turn is a branch explicitly aware of what makes it different
from the source branch. This is useful, for instance, for features and short living development branches that are going to be merged
surely by design and must be kept up to date from the normale release history. I don't see the point in using tracking into
versions branches.

Perl blogs will be powered by PostgreSQL

There is a grant request aiming at revamping blogs.perl.org.
I have to admit that blogs.perl.org is in a bad shape, and in fact I do not use it anymore for my personal contents since the well known
login issues.
Well, the important part about the grant request, at least with regard to the PostgreSQL community, is that…surpise! The new platform will store content on a PostgreSQL backend:

[…]
will be written on top of Dancer2,
DBIx::Class, and DBI,
with a PostgreSQL database
imported from the existing
[…]


A great news for two of my favourite Open Source projects (Perl and PostgreSQL) and a great wat to spread the word thru our own content!

FreeDOS blog challenge: my short story about FreeDOS

I found the FreeDos blog challenge while reading one of my planets, and I decided to share a few lines about my personal experience.

Back in the days when I was a little tiny poor developer just kicked off by the university, I found a job where I was supposed to use a fourth-level language, something I would hate for the following years. The development chain was awkward: while the production machine was a Linux system, and thus the deployment was done on a Linux server, the development machine was a DOS one. Allow me to explain: you could develop and compile applications both on Linux, some Unix, and DOS (or Microsoft Windows including a DOS)
but installing the compiler on a Linux machine was a real pain, and so I was instrumented to work on Windows and DOS.
Another reason to stay on the DOS side of development was that the source code did use the cp850, that is those set of characters used to create frames and decorations.

Therefore, at that point, I was forced to boot my laptop on Windows, open the DOS prompt and interact with all the DOS basic programs and commands, like the text editor and find. The deploy was as easy as copying a file from the DOS box to the Linux server via either a Secure Shell (e.g., winscp) or a remote share (e.g., Samba).
It was not a cat's pijama for me, since I was a kind of "Unix-inside" developer, and I was coming out of university where I saw a lot of shiny brand new development tools like Eclipse.

I start reasoning about a way of running the DOS compiler on my Linux box directly, and of course I found out FreeDOS. The problem was I needed to run both FreeDOS and Linux at the same time to get out of the latter all the command line power I was used to and out of the former the ability to run the required compiler and tools.
I hear you: virtualization to the rescue!
Not so easy pal, since back in those days (I think it was 2003) there was not the widespread of virtualization as we mean today, and the only tools available to me were jails, chroot, and VMWare. Unluckily booting a FreeDOS machine via VMWare on my poor Intel Celeron 733 MHz with 192 MB of ram was not an efficient idea.


Therefore I was forced to throw away the idea of using FreeDOS (for that purpose).

This experience pushed me to study better the compiler and face the problem of installing the cp850 on my Emacs editor, as well as how to configure the terminal (terminfo) to use the compiler entirely on Linux, and I never came back to Windows+DOS for my development.


After a few months I had to manage another ancient machine used to send out faxes. The machine was bare metal directly attached to a moden on its own phone line, running a DOS program to send faxes. Due to an hydraulic problem, the machine blown away and so I had to replace it. Of course, it was not possible to either find a decent running copy of MS-DOS, as well as to substitute such machine with an Hylafax server (but that's another story).
Luckily, I had made a little experience on FreeDOS, I decided to ran that version on the fax machine. Several years after I was on another job, and I got an email from a previous colleague of mine telling me that they have turned off the fax machine, that have ran FreeDOS for 6+ years without any problem. OK, let's be honest here: the job of the machine and, thus, of the operating system, was not so complex in this deployment, but I think it is great to have a project as FreeDOS that allows anyone to run ancinet programs and access data even years after the programs developers are no more on the market!

And what about today?
Well, today I believe it is a lot easier to run a FreeDOS instance, and in fact I've always a virtual machine around with a recent version of FreeDOS that I use to run my 20+ years old C programs I made at school!

Thank you very much to all the developers, maintaners and people behind the FreeDOS project.
Unlike other free operating systems that often share a common architecture and execution runtime, this one is especially important in my
opinion because it allows us to run programs no other operating system could.

sabato 20 maggio 2017

PostgreSQL abbandonerà il supporto al download FTP

Dal giorno 15 Agosto 2017 non sarà piu' possibile scaricare PostgreSQL tramite FTP!
Come spiegato nella mailing list pgsql-announce, visto il basso traffico
del protocollo FTP, nonché la vetustà del protocollo e dei relativi programmi,
il team che mantiene l'infrastruttura ha deciso di spegnere l'accesso FTP.
Questo non dovrebbe risultare in un particolare disservizio per gli utenti finali, quanto
forse solo per alcune applicazioni e script automatici.

Noisli: un servizio di suoni per aumentare la concentrazione al lavoro

E' molto importante rimanere concentrati durante lo svolgimento del proprio lavoro, penso sia un concetto noto a tutti.
Io ho la fortuna di svolgere un lavoro ad una scrivania, senza pubblico, quindi per estraniarmi dall'ambiente circostante utilizzo
la musica e, raramente, la radio. Il mio cervello aggancia la melodia e non si fa distrarre da altre cose e rumori, lasciandomi
quindi proseguire nel mio lavoro. Tuttavia non indico questa come possibile strategia di studio, che invece richiede maggior silenzio
e in generale sonorità che il cervello non è in grado di "comprendere" razionalmente (es. parole).

Ecco, ho scoperto che esiste un servizio Noisli che consente di comporre un suono ambientale che possa aumentare la produttività
individuale. Ad esempio mescolando il suono della pioggia battente con quello di un caminetto. E c'è anche chi ha pensato
di integrare il servizio dentro a Gnome.

venerdì 19 maggio 2017

Arabic to Roman number converter in Perl 5

Puzzled by a post on the Planet KDE about GCompris and roman numbers, and needing an easy way to explain to my six-years old son about roman numbers, I thought it would be an easy task to make a simple program in Perl to convert an arabic number into its roman notation.
Not so easy, pal!
Well, it's not a problem about Perl, of course, rather I found it required a quite brainpower for me to write down rules to convert numbers, and I did not search for the web for a copy-and-paste alghoritm. Please note: if you need a rock-solid way to handle conversions, have a look at CPAN that is full of modules for this particular aim.
Here I'm going to discuss the solution I found and how I implemented it. It is not supposed to be the best one, or the faster one, it's just my solution from scratch.

The program

I split the problem of converting an arabic number into a roman one into three steps, with one dedicated subroutine for each step, so that the main loop reduces to something like the following:
say "$_ = " . $roman_string->( $reassemble->( $disassemble->( $_ ) ) )
              for ( 1..30 );
that produces the following output:
1 = I
2 = II
3 = III
4 = IV
5 = V
6 = VI
7 = VII
8 = VIII
9 = IX
10 = X
11 = XI
12 = XII
13 = XIII
14 = XIV
15 = XV
16 = XVI
17 = XVII
18 = XVIII
19 = XIX
20 = XX
21 = XXI
22 = XXII
23 = XXIII
24 = XXIV
25 = XXV
26 = XXVI
27 = XXVII
28 = XXVIII
29 = XXIX
30 = XXX
The steps must be read from the inner subroutine to the outer, of course, and therefore we have:
  • disassemble that translates an arabic number into roman basis, that is computes how many units, tens, hundreds and thousands are required. In this phase there is no application of roman rules, so numbers are decomposed into a linear string of letters. As an example the number 4 is translated into IIII, which is of course a non-existent roman number.
  • reassemble applies roman rules, in particular promoting numbers so that groups are translated, when needed, into higher order letters. For instance IIII is promoted into two groups: I and V.
  • roman_string compose the promoted groups into the final string. The main difficulty of this part is to understand when a letter has to be placed on the right (addition) or on the left (subtraction) of another letter. For instance, having the groups I and V the function must understand if the output have to be VI (6) or IV (4).
To speed up the writing of the code, I placed main roman letters and their correspondance with arabic numbers into a global hash:
my $roman = {
    1    => 'I',
    5    => 'V',
    10   => 'X',
    50   => 'L',
    100  => 'C',
    500  => 'D',
    1000 => 'M',
};
Each method references $roman when needing to convert from an arabic number to its roman letter. In order to allow method to cooperate together, they accept and return an hash keyed by a roman letter and the number of occurences such letter must appear in the final string. The following is an example of the hash for a few numbers:
# 4 (IV)
{ 'I' => 1, 'V' => 1 }
# 19 (XIX)
{ 'I' => 1, 'X' => 2 }
# 5 (V)
{ 'V' => 1 }
# 17 (XVII)
{ 'X' => 1, 'V' => 1, 'I' => 2 }

The disassemble function

The following is the code for the disassemble function, that accepts as only input the arabic number.
# Accepts the arabic number and provides an hash
# keyed by each letter, with the value of how many times
# such letter should be summed in order to obtain the
# starting number.
my $disassemble = sub{
    my ( $number ) = @_;
    my $items = {};

    # sort the keys, that are arabic thresolds, from
    # the greater to the smaller one
    for my $current_value ( sort { $b <=> $a } keys $roman->%* ){

        my $how_many = int( $number / $current_value );
        next unless ( $how_many );

        my $letter = $roman->%{ $current_value };
        $items->{ $letter } = $how_many;

        $number -= $current_value * $how_many;
    }

    return $items;
};
The first thing the method does it to create the hash $items that is what it will return to allow other methods to consume. Each key of the $roman hash is passed ordered by the bigger to the smaller (please note that sort has $b first!). In this way we can surely scompose the number from the thousands, hundreds, tens, and units in this exact order. The $how_many variable contains the integer part of each letter. For example the number 29 is processed as follows:
  1. 29 / 10 that drives $how_many to be 2 and the remaining to be a 9;
  2. 9 / 5 that makes $how_many to be 1 and the remaining to be a 4;
  3. 4 / 1 that makes $how_many to be 4 and there's nothing more to do.
At each step the roman letter and the $how_many value is inserted into the $items has, that in the above ecample becomes:
# 29 (XIX)
{ 'X' => 2,
  'V' => 1,
  'I' => 4
}

The reassemble method

The reassemble method takes as input the hash produced by disassemble and checks if any letter requires a promotion. Here it is the code:
# Accepts an hash with keys the letters and values the number
# of times each letter should appear.
# Traverse the hash from the smaller to the greater
# in order to "promote" smaller aggregates. For instance
# 'IIII' (4) is aggregated and therefore the hash is modified
# so there's only an 'I' and another 'V', in such case
# the quantity of the promoted letter is negative to indicate
# it has been promoted.
my $reassemble = sub{
    my ( $items ) = @_;
    my @sorted_thresolds = sort { $a <=> $b } keys $roman->%*;

    for ( my $i = 0; $i < @sorted_thresolds; $i++ ){
        my $current_value = $sorted_thresolds[ $i ];
        my $key      = $roman->%{ $current_value };
        my $how_many = $items->%{ $key };

        next unless ( $how_many );

        my $greater_value = ( $i + 1 > @sorted_thresolds ? 1000 : $sorted_thresolds[ $i + 1 ] );
        my $greater_key   = $roman->%{ $greater_value };


        my $need_to_promote = $how_many == 4
            || ( $greater_value / $current_value == $how_many );

        if ( $need_to_promote ){
            $items->{ $greater_key }++;
            $how_many = $greater_value - $how_many * $current_value;
            $items->{ $key } = $how_many * -1;

        }

    }

    return $items;
};
The promotion must be done from the smaller letter to the greater one, so this time the letters are walked in ascending order (i.e., sort has $a first!). Since to promote a letter I need to access the following one, I need a C-style for loop.
A letter requires to be promoted if its quantity is 4 or /it is 2 and the right bigger value is exactly the double of the current one~, that is while ( $greater_value / $current_value == $how_many ). This makes, for instance IIII to be promoted (the quantity is 4), and VV to be promoted into X (because the quantity is 2 and the X is exactly the double of V). The promotion manipulates the hash increasing by one the right bigger letter and leaving a single current letter. In order to flag the promoted letter, I decided to use a negative quantity (where the absolute value is the exact one).
So for instance, the 29 hash of the previous paragraph is passed as follows:
# input to the method
{ 'X' => 2,
  'V' => 1,
  'I' => 4
}


# first for step (I)
{ 'X' => 2,
  'V' => 2,
  'I' => -1  # promoted, keep 1 and increase 'V'
}

# second step (V)
{ 'X' => 3,
  'V' => 0,  # promoted, increase X by one
  'I' => -1
}
At the end of method we know the final string will be made by three X and one I, the point now is to understand how to render them in the correct order. This is the aim of the roman_string method.

The roman_string method

The method accepts the normalized hash (i.e., groups are already formed) and compose the final string placing letter on the left or the right of each other depending on their quantity. The following is the code of the method:
# Do the hard work of composing
# each group of letters in order to compose the roman string.
my $roman_string = sub {
    my ( $items ) = @_;
    my @chars;

    for my $current_value ( sort { $b <=> $a } keys $roman->%* ){
        my $letter   = $roman->%{ $current_value };
        my $how_many = $items->%{ $letter };

        next unless ( $how_many );


        if ( $how_many > 0 ){
            push @chars, $letter for ( 1 .. $how_many );
        }
        else{
            # this is promoted, so it has to be inserted as last-to-last
            # in the previous chain
            # example: @chars( X, X ) and here I've 'I' to make XIX (19)
            push @chars, ( $letter, pop @chars );
        }

    }

    return join "", @chars;
};
In order to be able to manipulate easily the final string, moving letters from left to right and vice-versa, I decided to place each single letter into the @chars array, that is then join -ed into a single string.
Let's suppose we need just to add letters: in this case we need to write letters from the greater to the smaller from left to right, and this is the order I traverse the letters of $roman (again, note that sort has $b first!). If the quantity of the letter is positive the letter has not been promoted and therefore it will not be placed to the left of another letter, so just insert into @chars the $letter for the $how_many quantity. On the other hand, if $how_many is negative, the letter has been promoted and therefore have to be printed on the left of the last printed letter. This is as easy as doing:
push @chars, ( $letter, pop @chars );
that inserts into @chars the $letter and the previous last character that has been removed via pop.
With regards to the previous example of 29 we have that:
# method input
{ 'X' => 3,
  'I' => -1
}

# first step: prints X
# with quantity 3 (not promoted)
@chars = ( 'X', 'X', 'X' );

# second step: prints I
# that has been promoted
# and must be inserted ascending
# as last-to-last
@chars = ( 'X', 'X' ,
           ( 'I', # $letter
             'X'  # pop @chars
         ) );

Conclusions

Well, it has been much code that I expected to write. Using an object notation, instead of plain hashes, could surely make the program more robust. I'm pretty sure there's a way to shrink the code down and to avoid that ugly C-style for loop, as well as the promotion part could be simplified keeping in mind that it often reduces to -1 for the current letter and +1 for the greater one. Anyway, it does what I need and seems correct!

PostgreSQL 10 beta 1!

Ci siamo!
PostgreSQL 10 fa finalmente capolino nel mondo con il rilascio, ieri, della prima beta release.
Il download comprende pacchetti binari per le maggiori distribuzioni, oltre ovviamente alla possibilità
di compilare i sorgenti, anch'essi scaricabili come archivi.

sabato 13 maggio 2017

KDE e cgit

Il progetto KDE utilizza cgit come frontend web per i repository git.
Il progetto cgit fornisce un accesso web super fast ai repository git, con
alcune funzione di utilità specifiche come il riconoscimento dei repository on-the-fly.
Sicuramente rappresenta una valida alternativa alle molteplici interfacce web
già presenti sul mercato.

venerdì 12 maggio 2017

Postfix dereference operator

Starting from Perl 5.20 it is allowed to use a postfix dereference notation, first as an explicit feature, and since Perl 5.24 it is enabled by default.
The postfix dereference notation allows you to use the arrow operator -> on a reference (as often used when combined with references) specifying the type of the deferencing you want to. Types are indicated by their well know sigils, so for instance a $ means a scalar, a @ an array, & is for a subroutine, % for an hash and * for a typeglob. The sigil on the right of the arrow operator is enhanced by a star, so it really becomes type and *, as in $*. In the special case of arrays and hashes the star can be dropped in favor of a slicing operator, e.g., the square brackets.
The following is a sample program that prints out the values of an array using full access (->@*) and slicing (->@[]):

#!env perl
use v5.24;

my @array = ( 'a' .. 'z' );
my $ref   = \@array;
say "Here comes the array @{ $ref }";
say "And post dereferences is $ref->@*";

say "Here comes a slice @{ $ref }[ 0 .. 5 ]";
say "And using it as post dereference is $ref->@[ 0 .. 5 ]";
 
 
As you can see, $ref->@* is the equivalent of @{ $ref }, while $ref->@[] is the same as @{ $ref }[]. The same applies to hash references.
Code and subroutine references are a little more controversial, at least to my understanding of references. First of all there is only the star operator, so ->&*, and the behavior is such that $ref->&* is the same as &{ $ref }. This makes me think there is no short way of passing method arguments thru a postfix deference, as the following code demonstrates:

#!env perl
use v5.24;

my $sub_ref = sub { say "Hello sir @_ !" };
$sub_ref->( 'Luca' );         # Hello sir Luca !
&{ $sub_ref }( 'Luca' );      # Hello sir Luca !
$sub_ref->&* ;                # Hello sir  !
{ $sub_ref->&* }( 'Luca' );   # Hello sir  !
&$sub_ref( 'Luca' );          # Hello sir Luca !

If you try to pass arguments in any way to the ->&* dereferencing, you got either a compile time error or a code that does not what you expect:

{ $sub_ref->&>* }( 'Luca ');   # Hello sir  !
$sub_ref->&( 'Luca' );        # syntax error at tmp/ref.pl line 19, near "->&"
$sub_ref->&*( 'Luca' );       # syntax error at tmp/ref.pl line 20, near "&*( "
{ $sub_ref->& }( 'Luca ');    # syntax error at tmp/ref.pl line 21, near "->&"

The only catch-all way of passing arguments, as suggested on irc.perl.org, is to use the @_, so I suggest to localize it:


  local @_ = qw( Luca ); 
  $sub_ref->&*; # Hello sir Luca ! 
}

I must admit this is a little too much for my poor brain in order to efficiently use the references, so if anyone has something to comment is truly welcome!
Now, back to the main topic, it seems to me that the postfix dereference notation is a way of managing reference more like objects, at least it reminds me a kind of as_xx methods (yes, Ruby-ers, I'm looking at you). If we read the arrow operator like as and the type on sigil on the right as the type name, we have that, for instance:
  • $ref->$* is $ref as scalar;
  • $ref->@* is $ref as array or $ref>@[] becomes $ref as array slice
and so on. While I'm pretty sure this is not the real meaning of this notation, it is sure most readable than the "usual" one, where we have the type on the left and the reference on the right (or better in the middle), as in @$ref or @{ $ref }.

mercoledì 10 maggio 2017

Diamonds in Perl

A diamond ascii is a geometric structure represented as, ehm, a diamond. For example, in the case of letters it becomes something like:


      a
    b  b
   c    c
  d      d
 e        e
f          f
 e        e
  d      d
   c    c
    b  b
     a

How hard can it be to build a Perl program to represent a diamond like the above one?
Well, not so much hard, but we have to observe some geometric properties:

  • the diamond is simmetric (in the sense it becomes and ends with the same letters), but the
    central row is reproduced only once (that is, the f appears only on one line, not two!);
  • each letter or couple of letters is vertically centered around the number of letters in the whole diamond, that is
    the letter a (vertical centre) is shifted to right of 6 chars (the total number of letters is a..f = 6);
  • each couple of letters has a left and right position, and both are equally distant from the vertical
    centre of the diamond.

Ok, so here it comes my shorter solution:



#!env perl

use v5.20;

my @letters = qw( a b c d e f );

my %index;
@index{ @letters } = ( 0 .. $#letters );


    say {*STDOUT}
  " " x ( $#letters - $index{ $_ } )
 , $_
 , " " x ( $index{ $_ } * 2 )
 ,( $index{ $_ } > 0 ? $_ : '' )
     for  ( ( @letters, reverse @letters[ 0 .. $#letters - 1 ] ) );

Allow me to explain it in all its pieces.


First of all, @letters contains the letters to be printed in the right order, and this of course could come from user's input, a sequence, an array slice, or whatever, it does not mind here. Since I have to place letters depending on where they are in the array of @letters, I need to have an handy way to get the index within the array for each letter, so I build up an hash where the keys are the letters themselves and the values are the positions of such letters. In other words, $index{a} = 0, $index{f] = 5 and so on.


Finally, I print a line every time I need with say. Let's dissect the say statement:

  • " " x ( $#letters - $index{ $_ } ) shifts to right a number of spaces required to reach the vertical centre or the right distance from it, in other words it is the left position. For example, for the letter a it comes
    down to 5 - 0 = 5, while for b it comes to 5 - 1 = 4 and so on.
  • then I print $_ that is the current char;
  • then I move again to the right of " " x ( $index{ $_ } * 2 ), that is in the case of a nothing, in the case of b by 2, and so on;
  • then if required I print again the char. Here "required" means the char is not the first one (i.e., not the one at index 0), since that is the only one character printed exactly one time per line.

The say is repeated over the whole @letters array, so this produces the first part of the diamond:


      a
    b  b
   c    c
  d      d
 e        e
f          f

then I need to get the bottom, so I need to iterate over the reverse @letters with the exception of the last element, that is I need to iterate over a reversed slice of @letters with the missing f: reverse @letters[ 0 .. $#letters - 1 ] ). This provides me the whole bottom of the diamond.

L'importanza dell'operatore qq

Non si finisce mai di imparare!
Guardando uno script Perl per la gestione di backup testuali PostgreSQL
sono rimast incuriosito dall'uso massivo di printf legato all'operatore qq:
A double-quoted, interpolated string. Ebbene una utilita' di questo operatore
è nell'utilizzo delle virgolette doppie, che non devono ovviamente essere
legate a sequenze di escape. Quindi invece che scrivere:


printf "Un esempio di stringa \"%s\" ", 'quotata';

si può scrivere la versione molto piu' semplice e leggibile


printf qq( Un esempio di stringa "%s" ), 'quotata';

Sembra una banalità, ma non essendo abituato ad usare qq come invece
lo sono per q e qw, non mi sono mai posto il problema di come
semplificare ulteriormente le mie stringhe con doppi apici.


Ora diventerò anche io un avido utilizzatore di qq!

Applicare la geolocalizzazione massivamente in Digikam 5.5

digikam1.pngDigikam è veramente uno strumento di gestione delle immagini potentissimo, ma paradossalmente pecca di alcune carenza (a mio avviso)
proprio nella gestione massiva delle immagini, in particolare metadata e geolocalizzazione.
Con quest'ultima mi sono dovuto scontrare per inserire la località massivamente partendo dalle coordinate.
Ecco quindi come fare (versione attuale 5.5.0):


  1. selezionate una sola immagine e dal menu' Item selezionate Edit Geolocation… che aprirà la finestra di dialogo per
    la georeferenziazione. Da qui abilitate il pannello Details sulla destra e, dopo aver riselezionato l'immagine nella lista
    che compare all'interno della finestra, inserite le coordinate.

  2. cliccate sul tasto Apply nel pannello Details (non è quello che compare a fianco di Close!).
  3. dalla lista delle immagini della finestra di dialogo, dove ve ne è sempre e solo una, click destro e selezionate dal menu'
    contestuale Copy coordinates e infine chiudete la finestra di dialogo.



  4. selezionate ora tutte le immagini alle quali volete applicare le modifiche e nuovamente dal menu' Item scegliete
    Edit Geolocation…. Nella finestra di dialogo che appare selezionate nuovamente tutta la lista di immagini
    e fate click destro, poi dal menu' contestuale scegliete Paste coordinates.



  5. cliccate su Apply, questa volta il pulsante in fondo alla finestra, e il sistema inizierà a inserire le coordinate
    in tutte le immagini.

Nuovo sito web per Digikam!

Digikam, uno dei software che uso di piu' attualmente, ha un nuovo sito web completamente rinnovato e sicuramente molto piu' accattivante
rispetto a quello precedente!
Dopotutto, anche il sito web è importante per un progetto, perché consente di attirare nuovi utenti e potenziali sviluppatori.
Veramente un lavoro elegante e ben fatto.

martedì 9 maggio 2017

L'importanza della descrizione dei ticket...

La corretta gestione dei ticket, si sa, è una questione difficile. O meglio, non è certo la difficoltà di compilare
qualche campo in una form web, bensì è lo shift mentale che vi è richiesto per organizzare
bene i singoli ticket e le varie attività.


Un errore che vedo fare molto spesso, anche da persone che si definiscono dei professionisti informatici è quello
di usare la descrizione del ticket come il testo di una email. Ecco un esempio inventato ma non molto lontano
da diversi ticket che vedo regolarmente:


Ciao Mr.X,
avrei bisogno che mi controllassi il problema di stampa dei pdf prodotti in automatico, che hanno
l'orientamento orizzontale e non verticale. Questo non è comunque urgente, piuttosto è molto
urgente risolvere il problema di autenticazione del nuovo collega G., che non riesce
ad accedere al sistema.

Saluti,
Mr. Y

Quanti errori ci sono nella descrizione del suddetto ticket?


Anzitutto il tono "discorsivo" e quasi formale con saluti di apertura e chiusura, cosa corretta in una email, ma non
in un ticket (che ha già un owner (Mr. Y) e un assignee (Mr. X). Tali dettagli fanno solo perdere tempo e spazio,
e non sono assolutamente rilevanti per la risoluzione del ticket stesso.


Il secondo errore è la specificazione, verbale, della priorità dell'attività: […]non è comunque _urgente[…].
Tutti i sistemi di ticketing includono la possibilità di specificare la priorità delle singole attività collegate
al ticket, e il modo corretto di farlo è ovviamento usando tali campi. Perché? Beh, semplicemente perché chi prende in
mano il vostro ticket lo potrebbe fare basandosi su un filtro per priorità, dunque se il vostro ticket risulta a priorità
"normale", il fatto che voi inseriate la dicitura "urgente" non farà balzare il ticket nei primi posti della lista.


Infine, errore ancora piu' subdolo, nella descrizione di cui sopra si specificano due attività distinte (con due distinti
gradi di priorità):

  1. risolvere il problema dell'orientamento dei PDF, priorità bassa;
  2. risolvere il problema di autenticazione di un singolo utente, priorità alta.

La modalità corretta è quindi quella di aprire due ticket differenti, con priorità differente e descrizione limitata
al problema specifico.
Ecco cosa avrei prodotto io:


Ticket 1
Priorità: bassa

Problema layout stampa PDF: attualmente tutti i PDF escono con orientamento orizzontale,
mentre l'orientamento deve essere VERTICALE.

Ticket 2
Priorità: Alta

L'utente G. (username=g) non riesce ad autenticarsi. Il messaggio di errore
che riceve è "username o password errati".
Questo è per lui bloccante, non può collegarsi al sistema.


Come si può notare, oltre a "spaccare" un singolo messaggio in due, si usano livelli di priorità differente
e si specifica in maniera dettagliata ma senza fronzoli (saluti, ecc.) i problemi e i messaggi di errore.


Usare un sistema di ticketing può risultare in un meccanismo particolarmente potente e strutturato per la gestione
delle attività, ma occorre una impostazione mentale adeguata e rigorosa.
Uno dei consigli che mi sento di dare a chi si vuole "formare" e preparare adeguatamente a questo approccio è quello
di usare un sistema di ticketing anche per progetti mono-sviluppatore. In questo sistemi integrati come
Fossil consentono di unire agilmente la gestione del codice e dei ticket.