tag:blogger.com,1999:blog-18364819054873848872024-03-13T23:49:20.555+01:00:: Luca Ferrari ::Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.comBlogger932125tag:blogger.com,1999:blog-1836481905487384887.post-91010119881928619952018-12-04T17:43:00.000+01:002018-12-04T17:43:15.825+01:00PostgreSQL 11 Server Side Programming Quick Start Guide<span style="font-size: small;">Last week my book <b><a href="https://www.packtpub.com/big-data-and-business-intelligence/postgresql-11-server-side-programming-quick-start-guide">PostgreSQL 11 Server Side Programming Quick Start Guide</a> </b>was released.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0rQKqGb5ZUNh5mMM4JcXrBtKcTQf5Ay-hIcAC1u3n6qEAJBlLW0SJQZPcfs0lk7KN2jlFcGobL97fcXNmuRZZzBv2o-w63YPYlCxV5urm0Gh5D73zdfDMKcW1LfDNcAtF-iQWuKOpwZk/s1600/cover.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="373" data-original-width="302" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0rQKqGb5ZUNh5mMM4JcXrBtKcTQf5Ay-hIcAC1u3n6qEAJBlLW0SJQZPcfs0lk7KN2jlFcGobL97fcXNmuRZZzBv2o-w63YPYlCxV5urm0Gh5D73zdfDMKcW1LfDNcAtF-iQWuKOpwZk/s400/cover.png" width="323" /></a></div>
<br />
<br />
The book is a <i>Quick Start Guide</i>, that means it goes straight to the point, in this case, programming on the server-side of PostgreSQL.<br />
<br />
Why is this related to <i>Perl</i>?<br />
Well, one very <u>cool feature of PostgreSQL is the capability to
execute functions, and therefore triggers and procedures, in pretty
much any programming language</u> available out there. And this of course, means <b>Perl</b>!<br />
In fact, Perl is very well supported in PostgreSQL to the point that the <i>DO</i> statement does allow you to use <b>PL/Perl</b> code instead of the <i>PL/pgSQL</i> one.<br />
<br />
The other language I show, as a "foreign" language, in this book, is <i>Java</i>.
My idea was to show to the readers the differences between using a
language like Perl and one that requires a full compile-deploy cycle.<br />
<br />
Hope the book can be useful.Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com12tag:blogger.com,1999:blog-1836481905487384887.post-59977882726447703822018-02-20T18:15:00.000+01:002018-02-20T18:15:24.622+01:00!!! BLOG MOVED !!!<div style="text-align: justify;">
<span style="font-size: large;">Come si può notare questo blog non viene piu' aggiornato da tempo. Il mio nuovo blog è disponibile al seguente URL:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<span style="color: red;"><span style="background-color: white;"><a href="https://fluca1978.github.io/"><i><b><span style="font-size: large;">https://fluca1978.github.io/</span></b></i></a></span></span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;">Il contenuto di <i>questo</i> blog è stato incluso in quello nuovo, ma le formattazioni potrebbero renderne difficile la lettura o la ricerca. Questo blog verrà mantenuto "statico".</span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;">Mi sono attivato per riconfigurare gli aggregatori di questo blog di conseguenza.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-size: large;">As you can see, this blog has not been updated since a while. My new blog is available at the following URL:</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<span style="font-size: large;"><span style="color: red;"><span style="background-color: white;"><a href="https://fluca1978.github.io/"><i><b><span style="font-size: large;">https://fluca1978.github.io/</span></b></i></a></span></span> </span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;">The posts within this blog have been imported in the new one, but the formatting and templates could make it difficult to read and search for. This blog will remain as a "static" old version.</span></div>
<div style="text-align: justify;">
<span style="font-size: large;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-size: large;">I'm migrating all aggregated feeds gradually and consequently.</span></div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com8tag:blogger.com,1999:blog-1836481905487384887.post-35862829427139005472017-07-09T19:50:00.000+02:002017-07-09T19:50:21.270+02:00POSSE è passato anche da Bologna<div style="text-align: justify;">
<a href="http://foss2serve.org/index.php/POSSE">POSSE ovvero Professors' Open Source Software Experience</a> è 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.<br />
POSSE si fonda su tre livelli, chiamati <i>stage</i>:<br />
</div>
<ol class="org-ol" style="text-align: justify;">
<li>in questa fase <span class="underline">preliminare</span> si prende conoscenza con gli strumenti e le licenze, nonché si inizia a valutare obbiettivi semplici e raggiungibili sui quali far lavorare gli studenti;<br />
</li>
<li>in questa fase <i>face-to-face</i> 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;<br />
</li>
<li>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.<br />
</li>
</ol>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Pur non avendo mai partecipato ad uno schedule POSSE mi immagino che gli stage possano essere così schematizzati:<br />
</div>
<ol class="org-ol" style="text-align: justify;">
<li>apprendimento di strumenti quali canali IRC, mailing list, revisione del codice, test;<br />
</li>
<li>condivisione di esperienze e modalità di insegnamento degli strumenti di cui alla fase precedente, nonché loro applicazione pratica nei corsi di laurea;<br />
</li>
<li>sviluppo di una o piu' patch per un progetto prescelto.<br />
</li>
</ol>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Francamente ritengo che i tempi per gli stage siano abbastanza lunghi, si parla ad esempio di <i>6 mesi</i> per il solo stage 1!<br />
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.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Ma perché questa digressione su POSSE?<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A Luglio si è svolto <a href="http://foss2serve.org/index.php/Stage_2_Activities">lo stage 2 dell'anno 2017</a> presso l'Università di Bologna, ma ahimé <a href="http://foss2serve.org/index.php/POSSE_2017-07_Participants">i partecipanti</a> erano tutti stranieri e non leggo nessun nome italiano delle università limitrofe. Questa è secondo me una <span class="underline">pessima notizia</span> che dimostra ancora una volta l'arretratezza culturale alla quale sono sottoposti gli studenti delle università della mia zona.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com1tag:blogger.com,1999:blog-1836481905487384887.post-36316022487563672022017-07-08T09:49:00.000+02:002017-07-08T09:49:10.580+02:00Vivere in org-mode<div style="text-align: justify;">
Un <a href="https://emacs.cafe/emacs/orgmode/gtd/2017/06/30/orgmode-gtd.html">interessante articolo</a> sull'utilizzo di <i>org-mode</i> per tenere organizzate le proprie attività, e seguire la filosofia <i>GTD (Get Things Done)</i>.<br />
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à.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com1tag:blogger.com,1999:blog-1836481905487384887.post-46150218643538390122017-07-07T16:51:00.003+02:002017-07-07T16:51:52.250+02:00pgloader e gli URL (compresi quelli di MySQL!)<div style="text-align: justify;">
Un <a href="http://tapoueh.org/blog/2017/07/from-mysql-to-postgresql/">interessante articolo</a> sull'ultima versione disponibile di <a href="https://github.com/dimitri/pgloader/releases/tag/v3.4.1">pgloader</a>.<br />
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, <code>pgloader</code> è in grado di riconoscere e interpretare gli URL che gli vengono forniti scaricando file tramite altri protocolli, come HTTP, per poi <i>leggerli</i> e <i>dump-arli</i> verso una istanza PostgreSQL.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com1tag:blogger.com,1999:blog-1836481905487384887.post-60307522400841883072017-07-07T16:48:00.003+02:002017-07-09T21:54:39.115+02:00Eclipse Oxygen<div style="text-align: justify;">
Dal mese scorso è disponibile <a href="http://www.eclipse.org/">Eclipse Oxygen</a>, la nuova versione del popolare IDE tuttofare.<br />
Questa versione ha <a href="https://eclipsehowl.wordpress.com/2017/06/28/eclipse-oxygen-ide-improvements-general-java-and-git/">diverse migliorie</a> sia alla parte di sviluppo Java che alla parte di gestione <a href="https://git-scm.com/">git</a>. 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 <code>CTRL-e</code> per ciclare fra i tab degli editor o <code>ALT-c</code> per entrare nello staging git.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com1tag:blogger.com,1999:blog-1836481905487384887.post-39771372161258916262017-07-05T16:11:00.001+02:002017-07-07T16:54:54.277+02:00Do not buy via Royal Trendy<div id="table-of-contents">
</div>
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!<br />
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 <i>un-trusty</i> man. And as a result, this story tells me to be even less <i>trusty</i> about what I don't know well.<br />
<br />
<br />
<br />
<div class="outline-2" id="outline-container-sec-1">
<h2 id="sec-1">
<span class="section-number-2">1</span> tl:dr</h2>
<div class="outline-text-2" id="text-1">
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 <i>very decent</i> period of time to produce any kind of good.<br />
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 <i>very decent</i> 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.<br />
<br />
<br />
I waited for an order update (or better an order shipping) for around <span class="underline">100 days</span> (yes, it is a very high number).<br />
I wrote <span class="underline">14 emails</span> in the above period of time, and got <span class="underline">3 replies</span>, 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".<br />
<br />
<br />
<i>I URGE YOU TO DO NOT BUY ANYTHING FROM ROYAL TRENDY SINCE CHANCES ARE YOU WILL LOOSE YOUR MONEY</i>!<br />
It happened to me and to a lot of other people.</div>
</div>
<br />
<div class="outline-2" id="outline-container-sec-2">
<h2 id="sec-2">
<span class="section-number-2">2</span> The order and the first problem</h2>
<div class="outline-text-2" id="text-2">
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.</div>
<br />
<div class="outline-3" id="outline-container-sec-2-1">
<h3 id="sec-2-1">
<span class="section-number-3">2.1</span> 8 days and no news</h3>
<div class="outline-text-3" id="text-2-1">
After 8 days since the order date I wrote the following to get some news about my order.<br />
<br />
<br />
<pre class="example">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
</pre>
<br />
and the reply was quite generic, but I accepted the estimated times and waited longer.<br />
<br />
<br />
<br />
<pre class="example">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 </pre>
<pre class="example">where we will print and ship your item(s) within 7-10 business days. </pre>
<pre class="example">Below are expected delivery times based on your location.
Please note: Due to the popularity of certain items in our catalog, </pre>
<pre class="example">shipping times may take longer than the estimates below.
When your order ships you can request your tracking number </pre>
<pre class="example">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
</pre>
</div>
</div>
<br />
<div class="outline-3" id="outline-container-sec-2-2">
<h3 id="sec-2-2">
<span class="section-number-3">2.2</span> 6 weeks and no news</h3>
<div class="outline-text-3" id="text-2-2">
So, six weeks passed and I asked for any news.<br />
<br />
<br />
<pre class="example">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
</pre>
<br />
No news at all, so I asked it again after 6 weeks and 4 days.<br />
<br />
<br />
<br />
<pre class="example">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
</pre>
<br />
<br />
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!<br />
<br />
<br />
<pre class="example">Royal Trendy <myroyaltrendy@> Fri, Apr 28, 2017
To: Luca Ferrari
Hello Luca,
Thank you for contacting us. We sincerely apologize </pre>
<pre class="example">for the late update. Our fulfillment team had some </pre>
<pre class="example">issues which caused the delay of shipping the items </pre>
<pre class="example">according to our estimated days given. However, </pre>
<pre class="example">they are now actively working on this so we can </pre>
<pre class="example">ship the order the soonest as we can. </pre>
<pre class="example">Upon checking your order is now in the production </pre>
<pre class="example">and currently being process. Once done and ready </pre>
<pre class="example">to shipped we will send you a tracking details.
We appreciate your patience.
Best Regards,
Royal Trendy
</pre>
</div>
</div>
<br />
<div class="outline-3" id="outline-container-sec-2-3">
<h3 id="sec-2-3">
<span class="section-number-3">2.3</span> 8 weeks and no update</h3>
<div class="outline-text-3" id="text-2-3">
Waiting a little more I found myself after almost 8 weeks, so I wrote again asking for any news.<br />
<br />
<br />
<pre class="example">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
</pre>
<br />
Again no asnwer, so I have to write again after another 5 days. Please note a pattern here: <span class="underline">Royal Trendy started to not reply on the first contac.</span><br />
<br />
<br />
<br />
<pre class="example">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
</pre>
</div>
</div>
<br />
<div class="outline-3" id="outline-container-sec-2-4">
<h3 id="sec-2-4">
<span class="section-number-3">2.4</span> Entering Susan…</h3>
<div class="outline-text-3" id="text-2-4">
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 <i>Susan</i> taking care of my order, as well as others.<br />
<br />
<br />
<br />
<pre class="example">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. </pre>
<pre class="example">We're a bit behind schedule at the moment as </pre>
<pre class="example">one of the owners' brother recently passed away.
This is a family business. It hit us hard. </pre>
<pre class="example">So, with everything going on our production </pre>
<pre class="example">has went down due to the number of staff </pre>
<pre class="example">taking time off to grieve and deal with everything </pre>
<pre class="example">that has surrounded his passing.
We're still producing shoes, of course, but we've been short staffed, </pre>
<pre class="example">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 </pre>
<pre class="example">to help us speed up the back orders.
I've never seen socks & shoes fly at the door so fast. </pre>
<pre class="example">Turn around time is amazing for back orders.
Orders are usually process and shipped with 7-10 </pre>
<pre class="example">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. </pre>
<pre class="example">Some shipping times may take longer than the estimates below,</pre>
<pre class="example"> plus as I mentioned we are a bit behind schedule </pre>
<pre class="example">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: </pre>
<pre class="example">http://www.17track.net/en
This will let you check the status of your delivery.
After receiving your tracking number - </pre>
<pre class="example">it can take 6-8 business day before the tracking </pre>
<pre class="example">appears in your country about your shipment.
You can look here to see more about our </pre>
<pre class="example">shipping policy and delivery times:
https://www.royaltrendy.com/pages/faqs
We appreciate your patience and please do let us </pre>
<pre class="example">know if you have any additional questions.
Best Regards,
Royal Trendy
</pre>
<br />
<br />
Unluckily Susan was not able to provide any kind of news I kindly asked more and more times…</div>
</div>
<br />
<div class="outline-3" id="outline-container-sec-2-5">
<h3 id="sec-2-5">
<span class="section-number-3">2.5</span> No more news at all</h3>
<div class="outline-text-3" id="text-2-5">
Since the introduction of Susan, Royal Trendy simply did not replied to any other message.<br />
<br />
<br />
<pre class="example">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
</pre>
<br />
<pre class="example">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
</pre>
<br />
<pre class="example">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
</pre>
<br />
<pre class="example">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
</pre>
<br />
<pre class="example">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
</pre>
<br />
<pre class="example">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
</pre>
<br />
<pre class="example">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
</pre>
<br />
<br />
<br />
<br />
<br />
<pre class="example">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
</pre>
</div>
</div>
<br />
<div class="outline-3" id="outline-container-sec-2-6">
<h3 id="sec-2-6">
<span class="section-number-3">2.6</span> Situation as of today</h3>
<div class="outline-text-3" id="text-2-6">
Today I still got no answer, I still got no shoes, still got no update and my money is, quite frankly, lost.<br />
<br />
<br />
<pre class="example">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 </pre>
<pre class="example"> </pre>
<pre class="example"></pre>
</div>
</div>
<br />
<br />
<b>Interestingly, trying to track my order from the main site results in <i>No order found</i> error, which I suspect is a quite true answer according to the whole situation.</b><br />
I've tried to contact the owners via Facebook and the contact module on their main site but no reply appeared.<br />
<br />
As laready stated: let me know what happened and I will post an update.</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com3tag:blogger.com,1999:blog-1836481905487384887.post-26957571471652747272017-07-04T06:58:00.000+02:002017-07-04T06:58:10.895+02:001000Cara Carmensita,<br />
sono 1000 giorni, o meglio, sono 1000 mattine che mi alzo con quel senso di vuoto, a tratti piu' forte.<br />
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. <br />
Come fanno tutti.<br />
<br />
<br />
Mille giorni sono tanti o sono pochi?<br />
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.<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-22533409607826151602017-06-27T16:43:00.000+02:002017-06-27T16:43:02.265+02:00PgAdmin III è ancora vivo!<a href="https://www.pgadmin.org/">PgAdmin</a> è sempre stato il tool di riferimento per l'amministrazione di un cluster <a href="http://www.postgresql.org/">PostgreSQL</a> mediante interfaccia grafica.<br />
Onestamente non ho mai usato molto tale applicativo, se non quando ero alle prime armi e faticavo a districarmi sulla linea comando di <code>psql</code>,<br />
ma questo non significa che il tool non sia valido, anzi è uno dei piu' completi che abbia mai visto.<br />
<br />
<br />
La versione forse piu' nota di PgAdmin è la 3, e infatti spesso si trova il nome <code>PgAdminIII</code>. L'interfaccia grafica era spartana ma funzionale, le <a href="https://www.wxwidgets.org/">wxWidgets</a> facevano il loro scopo e rendevano l'applicazione portabile, ma l'eleganza ne soffriva abbastanza.<br />
L'anno scorso è stata rilasciata la versione stabile di <i>PgAdmin 4</i>, completamente riscritto in Python e basato su interfaccia web.<br />
Ciò ha rappresentato una discontinuità nel mantenimento della versione 3, basata su altra tecnologia.<br />
<br />
<br />
Mi ha fatto piacere scoprire che <a href="https://bitbucket.org/openscg/pgadmin3-lts">esiste un fork di PgAdminIII</a> mirato a mantenere il codice attivo e funzionante per ancora qualche versione di PostgreSQL. In effetti, mea culpa, ammetto che l'installazione di <i>PgAdmin 4</i> non mi risulta mai molto semplice, sicuramente per la mia mancanza di conoscenza Python (nemmeno la <a href="https://www.pgadmin.org/download/pgadmin-4-python-wheel/">wheel</a> sembra funzionare sul mio povero computer!).<br />
<br />
<br />
Lunga vita a PgAdmin (III o IV)!<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-23523748341087448742017-06-25T14:40:00.000+02:002017-06-25T14:40:00.170+02:00Riflessioni su pl/javaBruce Momjian ha pubblicato un <a href="https://momjian.us/main/blogs/pgblog/2017.html#June_16_2017">breve articolo circa l'adozione di pl/Java</a>.<br />
I linguaggi <code>pl/</code> sono una serie di <i>bindings</i> per utilizzare un linguaggio di programmazione differente dal "plain" SQL all'interno di una istanza PostgreSQL, ovvero lato server.<br />
Pertanto <code>pl/java</code> 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 <code>pl/java</code> in produzione, e ho anche tenuto dei mini corsi e dei seminari sul suo utilizzo (si <a href="http://confsl.org/confsl10/pdf/slides/ws_pg_LFerrrari-PostgreSQL-Java.pdf">veda ad esempio qui</a>), nonché ho provato a <a href="http://fluca1978.blogspot.it/2010/06/pljava-patch-per-cancellare-loperazione.html">contribuire a minime porzioni di codice</a>.<br />
<br />
<br />
Pl/Java risulta abbastanza ostico rispetto ad altri linguaggi <code>pl/</code>, e ciò è dovuto alla natura di Java (non certo ai suoi limiti), in particolare alla fase di compilazione che richiede sempre:<br />
<br />
<ul class="org-ul">
<li>un deploy di una forza compilata del codice;<br />
</li>
<li>un pezzo di codice <i>collante</i> SQL che possa "iniettare" le funzionalità Java dentro al server PostgreSQL.<br />
</li>
</ul>
<br />
Pl/Java si basa per scelta progettuale su <i>Java Native Interface (JNI)</i>, 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, <code>pl/java</code> utilizza una virtual machine backend per ogni processo attivo, richiedendo quindi dei tempi di startup piuttosto lunghi (o diciamo piu' lunghi rispetto ad altri <code>pl/</code>).<br />
<br />
<br />
L'implementazione di <code>pl/java</code> è 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.<br />
<br />
<br />
Eppure <code>pl/java</code> non <i>sfonda</i>, come nota appunto Bruce nel suo articolo.<br />
<br />
<br />
Avendolo usato in produzione posso affermare che <code>pl/java</code> è fortemente condizionato dalla competizione con altri linguaggi <code>pl</code>, in particolare quelli di scripting. Effettivamente io stesso, ad un certo punto, ho modificato porzioni di codice abbastanza sostanziose per passare da <code>pl/java</code> a <code>pl/perl</code>. 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 <i>on-the-fly</i> al codice sorgente anche quando non fosse disponibile un ambiente di sviluppo completo. Detto in due parole: per usare <code>pl/java</code> occorre impostare un progetto (Eclipse o similare), compilare, deployare e "iniettare" il codice nel backend, in <code>pl/perl</code> basta un editor di testo per modificare il codice e la fase di deploy si riduce ad iniettare il codice nel backend.<br />
<br />
<br />
Personalmente ritengo che <code>pl/java</code> 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à <code>pl/java</code> per implementare le proprie logiche di controlle server-side.<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-27424059222313093272017-06-24T22:42:00.000+02:002017-06-24T22:42:08.989+02:00Ulteriori considerazioni sul planet PostgreSQL italianoQualche mese fa avevo espresso brevemente <a href="http://fluca1978.blogspot.com/2017/04/considerazioni-sul-planet-italiano-di.html">alcune considerazioni sul futuro dell'aggregatore di blog</a> dell'associazione ITPUG, ovvero il <a href="http://www.planetpostgresql.it/">Planet PostgreSQL Italiano</a>.<br />
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.<br />
<br />
<br />
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:<br />
<br />
<br />
<ul class="org-ul">
<li><a href="http://fluca1978.blogspot.com/2017/04/dimensioni-delle-tabelle-e-dei-dati.html">14 Aprile</a><br />
</li>
<li><a href="http://fluca1978.blogspot.com/2017/05/ancoa-sul-caso-postgresql-e-uber.html">5 Maggio</a><br />
</li>
<li><a href="http://fluca1978.blogspot.com/2017/05/toolchain-e-qualita-postgresql.html">6 Maggio</a><br />
</li>
<li><a href="http://fluca1978.blogspot.com/2017/05/api-java-per-la-replicazione-postgresql.html">8 Maggio</a><br />
</li>
<li><a href="http://fluca1978.blogspot.com/2017/05/postgresql-10-beta-1.html">19 Maggio</a><br />
</li>
<li><a href="http://fluca1978.blogspot.com/2017/05/postgresql-abbandonera-il-supporto-al.html">20 Maggio</a><br />
</li>
<li><a href="http://fluca1978.blogspot.com/2017/06/perl-blogs-will-be-powered-by-postgresql.html">11 Giugno</a><br />
</li>
</ul>
<br />
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 <a href="http://planet.postgresql.org/">Planet PostgreSQL</a>.<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-9133099560812004472017-06-24T16:39:00.000+02:002017-06-24T16:39:17.830+02:00Perl _ filehandleLeggendo la documentazione di <a href="http://search.cpan.org/~xsawyerx/perl-5.26.0/ext/File-Find/lib/File/Find.pm"></a><a href="https://www.blogger.com/:Find">:Find</a> mi sono accorto di una frase nella sezione di esempio:<br />
<br />
<br />
<blockquote>
the "_" is a magical filehandle<br />
that caches the information from the preceding "stat()", "lstat()", or<br />
filetest.<br />
</blockquote>
<br />
e così incuriosito sono andato subito ad approfondire nella documentazione di <code>stat</code>:<br />
<br />
<br />
<blockquote>
If "stat" is passed the special filehandle consisting of an<br />
underline, no stat is done, but the current contents of the stat<br />
structure from the last "stat", "lstat", or filetest are returned.<br />
</blockquote>
<br />
Diciamo che <code>_</code>, a differenza della variabile <i>topic</i> non è una vera variabile ma un segnaposto particolare che viene interpretato come <i>accesso alla cache</i> dell'ultima operazione <i>stat</i> effettuata. E' facile costruire un esempio che mostri questi:<br />
<br />
<br />
<div class="org-src-container">
<br />
<pre class="src src-perl">#!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
</pre>
</div>
<br />
Lo stesso utilizzo non può essere effettuato con <code>File::stat</code>, che infatti riporta nella documentazione:<br />
<br />
<br />
<blockquote>
As of Perl 5.8.0 after using this module you cannot use the implicit $_ or<br />
the special filehandle "_" with stat() or lstat(), trying to do so leads<br />
into strange errors.<br />
</blockquote>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-44990757891394036882017-06-23T16:38:00.000+02:002017-06-23T16:38:25.771+02:00Secondary Selection & Emacs<div style="text-align: justify;">
Una discussione sulla mailing list Perl6 mi ha portato a fare una rapida ricerca e scoprire che, <i>ovviamente</i>, Emacs supporta anche<br />
la <i>Secondary Selection</i>. Questa è una modalità nativa di X11 (che in realtà supporta fino a 4 clipboard coesistenti) che funziona un po'<br />
come il kill-ring di Emacs stesso, ma che nella sua implementazione non si appoggio al kill-ring.<br />
In sostanza <a href="https://www.emacswiki.org/emacs/SecondarySelection">è possibile copiare e incollare</a> testo indipendentemente dalla regione selezionata e senza modificare il contenuto del kill-ring,<br />
consentendo quindi ad Emacs di gestire fino a due clipboard contemporanee, una delle quali gestita tramite un ring e collegata<br />
alla clipboard principale di sistema.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-88222497429793736872017-06-18T08:56:00.000+02:002017-06-18T08:56:07.679+02:00Non 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 <code>q!</code> per uscire dall'editor.<br />
Ho <a href="http://fluca1978.blogspot.it/2015/10/il-modo-corretto-di-uscire-da-vim.html">già scritto in precedenza riguardo questo soggetto</a>, 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 <i>mortale</i> <code>:wq!</code> (<a href="https://lleksah.files.wordpress.com/2017/06/cuno.png?w=640&h=480">qui l'immagine</a> del <a href="https://lleksah.wordpress.com/2017/06/03/running-your-first-programs-in-c-part-2/">post</a>).<br />
<br />
<br />
Vediamo di approfondire ancora una volta.<br />
Anzitutto cosa suggerisce l'aiuto in linea di Vi? Eseguendo <code>:help</code> si ottiene qualcosa del genere:<br />
<br />
<br />
<pre class="example">*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!).
</pre>
<br />
Andiamo bene! L'help in linea suggerisce di uscire dall'editor con <code>:qa!</code>, in sostanza l'equivalente di una <code>kill -9</code>!<br />
<br />
<br />
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 <code>ZZ</code> che esce <i>salvando se necessario</i> le modifiche. Perché questa cosa è importante? Perché forzare un aggiornamento del file ad ogni <i>uscita</i> ne cambia il timestamp e potrebbe creare conflitti con strumenti di controllo delle versioni e di build automatico.<br />
Ma non solo, se si digita <code>:help :x</code> si scopre che:<br />
<br />
<br />
<pre class="example">*: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).
</pre>
<br />
Mettiamo ora a confronto le varie modalità:<br />
<br />
<br />
<table border="2" cellpadding="6" cellspacing="0" frame="hsides" rules="groups">
<colgroup>
<col class="left"></col>
<col class="right"></col>
<col class="left"></col>
</colgroup>
<thead>
<tr>
<th class="left" scope="col">comando</th>
<th class="right" scope="col">caratteri</th>
<th class="left" scope="col">rischio di perdita modifiche</th>
</tr>
</thead>
<tbody>
<tr>
<td class="left">:qa!</td>
<td class="right">4</td>
<td class="left">si</td>
</tr>
<tr>
<td class="left">:wq!</td>
<td class="right">4</td>
<td class="left">no</td>
</tr>
<tr>
<td class="left">ZZ</td>
<td class="right">3 (contando SHIFT)</td>
<td class="left">no</td>
</tr>
<tr>
<td class="left">:x</td>
<td class="right">2</td>
<td class="left">no</td>
</tr>
</tbody>
</table>
<br />
<br />
Quindi perché non istruire gli utenti <span class="underline">da subito</span> ad usare modalità di uscita <i>smart</i>, visto che risultano perfino piu' compatte (in termini di caratteri) rispetto a quelle <i>brutali</i>?<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-52258625251306522972017-06-16T18:50:00.000+02:002017-06-16T18:50:06.505+02:00Perl and regexps are too much verbose (!)<div style="text-align: justify;">
A colleague asked me a quick Perl way to check if a string contains only a predefined set of chars excluding a few ones.<br />
<i>Easy pal!</i><br />
<span class="underline">Regexp to the rescue!</span><br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then I was asked for a way that did no use a regular expression, because "you know, <span class="underline">regular expression can be somehow verbose</span>".<br />
Gosh!<br />
My answer was simply "<i>you don't use regexps a lot!</i>".<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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,<br />
more in general an <i>alphabet</i> (in the most wider concept).<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But let's move on, and after showing a quick and dirty one liner such as:<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div class="org-src-container" style="text-align: justify;">
<br />
<pre class="src src-perl">perl -E 'say "Wrong $_" unless ( /^[0-9]+$/ ); ' -F
</pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I got another strange sentence as "yeah, but I don't like Perl too much, it is somehow verbose as a language".<br />
And again, my answer was: "<i>you don't use it regularly!</i>".<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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<br />
a one liner…<br />
No other comments required!<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-50254447305044931612017-06-16T16:52:00.000+02:002017-06-16T16:52:03.641+02:00Distanza fra date "note" in PerlCome si può fare a conoscere se una serie di date note si trovano ad una distanza <i>interessante</i> l'una dall'altra?<br />
Facile con un po' di Perl!<br />
<br />
<br />
Anzitutto la definizione: per <i>distanza interessante</i> intendo un numero di giorni multiplo di 10, anzi meglio, potenza di 10, ovvero <code>100</code>, <code>1000</code>, ecc.<br />
Detto questo, costruiamo la struttura base:<br />
<br />
<br />
<div class="org-src-container">
<br />
<pre class="src src-perl">#!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;
</pre>
</div>
<br />
Con <code>$begin</code> si indica la data di partenza, mentre in <code>$dates</code> si inseriscono giorno e mese di alcune date a voi significative.<br />
Per capirsi, <code>$begin</code> potrebbe essere la data di nascita di vostro figlio e <code>$dates</code> contenere il vostro matrimonio, laurea, ecc.<br />
Da notare che inserisco automaticamente la data di partenza nell'array delle date da cercare, così da valutare la data contro se stessa<br />
spostata chiaramente di alcuni anni.<br />
Fino a qui, nulla di sorprendente. Beh, anche il resto è abbstanza noioso:<br />
<br />
<br />
<div class="org-src-container">
<br />
<pre class="src src-perl">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 </pre>
<pre class="src src-perl"> if ( ( log( $delta )/log( $base ) ) =~ /^\d+$/ );
}
}
</pre>
</div>
<br />
In un ciclo di 100 anni (perché oltre diventa <i>poco interessante</i>, almeno per voi visto che non ci sarete piu') si processa un anno alla volta<br />
sommandolo alla data di partenza <code>$now</code> (clone della vera data). Contro tale "annata" si testano tutte le date ricercate per vedere se<br />
la distanza in giorni <code>$delta</code> è multiplo di 10 (<code>$base</code>) e piu' precisamente se è un logaritmo in base 10.<br />
Solo di quelle date si effettua una stampa a video.<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com1tag:blogger.com,1999:blog-1836481905487384887.post-58881645715996506302017-06-12T08:46:00.000+02:002017-06-12T08:46:12.829+02:00Cosa sono gli Emacs mode? Major mode, minor mode, oh my...Uno dei concetti chiave di <a href="https://www.gnu.org/software/emacs/">Emacs</a> che mi pare sia molto spesso sottovalutato da chi non lo utilizza è quello dei <i>mode</i>.<br />
Emacs è un editor <i>multi-mode</i>, ovvero è possibile attivare piu' modi contemporaneamente.<br />
A loro volta i <i>mode</i> si suddividono in due categorie principali:<br />
<br />
<ul class="org-ul">
<li><i>major mode</i> rappresentano il contesto di un buffer;<br />
</li>
<li><i>minor mode</i> forniscono funzioni trasversali fra uno o piu' buffer.<br />
</li>
</ul>
<br />
Molto spesso la differenza non viene colta, ma è importante perché l'uso combinato dei mode può personalizzare tantissimo il comportamento<br />
di Emacs.<br />
Anzitutto Emacs <span class="underline">ammette un solo <i>major mode</i> per buffer</span>, mentre virtualmente <span class="underline">infiniti <i>minor mode</i> possono essere attivati su ogni buffer</span>.<br />
<br />
<br />
Un <i>major mode</i> definisce il "contesto" di utilizzo del buffer, nonché le funzioni principali fornite in quel buffer. Ad esempio<br />
se si sta editando un buffer che contiene uno script Perl, il relativo major mode fornirà funzioni legate a Perl. Analogamente, se<br />
si sta visualizzando il contenuto di una directory, il relativo major mode (es. <code>dired</code>) fornirà le funzioni principali<br />
per interagire con il buffer. Un major mode può anche "rimappare" alcuni tasti funzione per rendere piu' facile l'utilizzo all'interno<br />
di tale buffer.<br />
<br />
<br />
Un <i>minor mode</i> fornisce sottofunzioni specifiche all'interno del buffer, e magari a livello globale su tutti i buffer. L'esempio classico<br />
è quello del correttore ortografico (es. <code>flyspell</code>) che agisce sul testo indipendentemente questo sia codice o testo o una chat.<br />
<br />
<br />
Per meglio comprendere questi concetti, mi si passi un blasfemo paragone con Eclipse.<br />
In Eclipse è possibile editare progetti Java, C/C++, Perl, PHP, Python (e altri). A seconda del tipo di progetto Eclipse carica funzioni<br />
differenti e fornisce refactoring e renaming in modo differente, e questo è esattamente quello che fa un <i>major mode</i> Emacs. Ecco perché poco<br />
sopra ho parlato di "contesti" del buffer.<br />
Tornando ad Eclipse, i commenti e le parole chiave vengono evidenziate in modo analogo fra i vari linguaggi, come pure i marker degli errori<br />
e dei problemi, e questo è quello che fa il minor mode Emacs (ok, per i font c'è la <i>fontify</i>, ma non scendiamo a questo livello).<br />
E i template del codice? Eclipse fornisce template per, ad esempio, i <code>get</code> e <code>set</code> (getter e setter), cosa che in realtà richiede due passaggi: uno di<br />
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<br />
fatta in Emacs tramite un altro minor mode (es. <code>yas</code>).<br />
<br />
<br />
Per riassumere si tenga sempre presente che il <i>major mode stabilisce cosa è possibile fare con un buffer</i>, sia in termini di contenuti, che di tasti funzioni,<br />
che di funzioni stesse, mentre un <i>minor mode stabilisce quali arricchimenti si possono fornire al contenuto del buffer</i>.<br />
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<br />
strumento quanto sopra dovrebbe bastare.<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-85252510305593580602017-06-11T18:48:00.000+02:002017-06-23T18:22:18.352+02:00Magit spin-offs: another way to name a tracking branch.A few days ago my attention was caught by an entry in the <i>Magit Branch Pop-up</i> buffer: <code>Create a new spin-off</code>.<br />
Uh?<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitwJH_BWiqcMV0y7E3nIWDL67B7J7HlOpUqogrVyRIgUC722JnMQdxLlxME2BV-IcKv-tmAfPJ_bSkqmXSRT7-Uecko3SdaNc6tHxKDZydtQodVTZAZHwurmpu8WEjyAhyJh68HfbV91E/s1600/git1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="547" data-original-width="923" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitwJH_BWiqcMV0y7E3nIWDL67B7J7HlOpUqogrVyRIgUC722JnMQdxLlxME2BV-IcKv-tmAfPJ_bSkqmXSRT7-Uecko3SdaNc6tHxKDZydtQodVTZAZHwurmpu8WEjyAhyJh68HfbV91E/s320/git1.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOpWFkI1rMzJzFM10hSeHHURYKTx4lXpBjG35ERqGe6mc3dyuoWzTthPJ5w9Ct1pCLv7uWJsOcpneiG4zCogZiVhhPunMbcjIH9Cq_2IawYr8aCRDnCfswI2eC38Okrf-bB98hOmSR-_c/s1600/git2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
What the hell is a spin off?<br />
According to the <a href="https://magit.vc/manual/magit/The-Branch-Popup.html#The-Branch-Popup">Magit Branching documentation</a>, a <i>spin-off</i> is nothing more than a <i>tracking branch</i>.<br />
A tracking branch, created on the <code>git</code> side with the <code>-t</code> switch, is a branch that knows (i.e., it has<br />
knowlegde) about the branch it was originated from. Well, every branch in git has, of course, knowlegde<br />
about its ancestor branch (how would you merge otherwise?), but in this case<br />
the knoweldge is made explicit by the <i>tracking</i> feature.<br />
<br />
<br />
In particular, when a tracking branch is checked out <code>git</code> advices about commits that made the<br />
current (tracking) branch diverging from its ancestor, something like the following:<br />
<br />
<br />
<div class="org-src-container">
<br />
<pre class="src src-sh">% 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)
</pre>
</div>
<br />
In the above example you can see that the <code>b</code> branch is <i>behind</i> <code>master</code> two commits, as well as <i>after</i> master by one commit.<br />
In other words, your <code>b</code> branch has done a single commit while <code>master</code> advanced by two other commits. As <code>git</code><br />
suggests, you can <code>pull</code> and <code>git</code> will automagically fetch updates from the <code>master</code> branch into <code>b</code>.<br />
And in fact:<br />
<br />
<br />
<div class="org-src-container">
<br />
<pre class="src src-sh">% git pull
From .
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
</pre>
</div>
<br />
The <i>tracking</i> is useful to know transparently when and how (much) your branch is diverging from the source, and this of course<br />
is true both for local commits and remote ones:<br />
<br />
<br />
<div class="org-src-container">
<br />
<pre class="src src-sh">% 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
</pre>
</div>
<br />
What happens into Magit? Well, once you checkout a tracking branch the popup buffer shows that is unmerged from the source branch, and<br />
it does suffice to <code>F</code> pull to prompt the merging popup.<br />
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi350Vv_UWg3i1wRpkLZuVSsJMLfD1KZ-nD2nXiEzp-4U_jEwRYWgjNZiPX2iSgpzUMcv74xelQC-R_Lkhs9fFyGAju5MKZ3vyxnlHBTPog8leEowdZ_ZebXUCqQfs7r3TFrldHhqqCbMc/s1600/git3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="355" data-original-width="661" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi350Vv_UWg3i1wRpkLZuVSsJMLfD1KZ-nD2nXiEzp-4U_jEwRYWgjNZiPX2iSgpzUMcv74xelQC-R_Lkhs9fFyGAju5MKZ3vyxnlHBTPog8leEowdZ_ZebXUCqQfs7r3TFrldHhqqCbMc/s400/git3.png" width="400" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOpWFkI1rMzJzFM10hSeHHURYKTx4lXpBjG35ERqGe6mc3dyuoWzTthPJ5w9Ct1pCLv7uWJsOcpneiG4zCogZiVhhPunMbcjIH9Cq_2IawYr8aCRDnCfswI2eC38Okrf-bB98hOmSR-_c/s1600/git2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="214" data-original-width="522" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOpWFkI1rMzJzFM10hSeHHURYKTx4lXpBjG35ERqGe6mc3dyuoWzTthPJ5w9Ct1pCLv7uWJsOcpneiG4zCogZiVhhPunMbcjIH9Cq_2IawYr8aCRDnCfswI2eC38Okrf-bB98hOmSR-_c/s400/git2.png" width="400" /></a>
<br />
<br />
So, to recap, a Magit <i>spin-off</i> lies a <i>tracking</i> branch, which in turn is a branch explicitly aware of what makes it different<br />
from the source branch. This is useful, for instance, for features and short living development branches that are going to be merged<br />
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<br />
versions branches.Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-14943842275709424422017-06-11T08:54:00.004+02:002017-06-11T08:54:36.850+02:00Perl blogs will be powered by PostgreSQL<div style="text-align: justify;">
There is a <a href="http://news.perlfoundation.org/2017/06/grant-proposal-revitalize-blog-1.html">grant request</a> aiming at revamping <a href="http://blogs.perl.org/">blogs.perl.org</a>.<br />
I have to admit that <a href="http://blogs.perl.org/">blogs.perl.org</a> is in a bad shape, and in fact I do not use it anymore for my personal contents since the well known<br />
<a href="https://github.com/blogs-perl-org/blogs.perl.org/issues/291#issuecomment-69999275">login issues</a>.<br />
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:<br />
</div>
<i><br /></i>
<blockquote>
<i>[…]<br />
will be written on top of Dancer2,<br />
DBIx::Class, and DBI,<br />
with a PostgreSQL database<br />
imported from the existing<br />
[…]</i><br />
</blockquote>
<br />
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!<br />
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-87853188758759359112017-06-11T08:43:00.001+02:002017-06-11T08:43:27.906+02:00FreeDOS blog challenge: my short story about FreeDOS<div style="text-align: justify;">
I found the <a href="http://freedos-project.blogspot.it/2017/06/freedos-blog-challenge.html">FreeDos blog challenge</a> while reading one of my planets, and I decided to share a few lines about my personal experience.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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, <a href="https://www.google.it/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjYu7a7s67UAhXDMBoKHctuCLoQFggiMAA&url=http%253A%252F%252Ffluca1978.blogspot.com%252F2015%252F05%252Fme-myself-and-dataflex.html&usg=AFQjCNFbT8py9BoA9gSMaf0pMJBGYH3D8A">something I would hate for the following years</a>. 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)<br />
but installing the compiler on a Linux machine was a real pain, and so I was instrumented to work on Windows and DOS.<br />
Another reason to stay on the DOS side of development was that the source code did use the <i>cp850</i>, that is those set of characters used to create frames and decorations.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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 <code>find</code>. The deploy was as easy as copying a file from the DOS box to the Linux server via either a Secure Shell (e.g., <code>winscp</code>) or a remote share (e.g., <a href="http://www.samba.org/">Samba</a>).<br />
It was not a <i>cat's pijama</i> 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 <a href="http://www.eclipse.org/">Eclipse</a>.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I start reasoning about a way of running the DOS compiler on my Linux box directly, and of course I found out <a href="http://www.freedos.org/">FreeDOS</a>. 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.<br />
I hear you: <i>virtualization to the rescue</i>!<br />
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 <code>jails</code>, <code>chroot</code>, and <a href="http://www.vmware.com/">VMWare</a>. Unluckily booting a FreeDOS machine via VMWare on my poor Intel Celeron 733 MHz with 192 MB of ram was not an efficient idea.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<i>Therefore I was forced to throw away the idea of using FreeDOS (for that purpose).</i><br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This experience pushed me to study better the compiler and face the problem of installing the <i>cp850</i> on my Emacs editor, as well as how to configure the terminal (<code>terminfo</code>) to use the compiler entirely on Linux, and I never came back to Windows+DOS for my development.<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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 <a href="http://hylafax.sourceforge.net/">Hylafax</a> server (but that's another story).<br />
Luckily, I had made a little experience on <a href="http://www.freedos.org/">FreeDOS</a>, 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, <i>that have ran FreeDOS for 6+ years without any problem</i>. 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!<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And what about today?<br />
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!<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Thank you very much to all the developers, maintaners and people behind the FreeDOS project.<br />
Unlike other free operating systems that often share a common architecture and execution runtime, this one is especially important in my<br />
opinion because it allows us to run programs no other operating system could.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com1tag:blogger.com,1999:blog-1836481905487384887.post-61994464481879328952017-05-20T19:48:00.000+02:002017-05-20T19:48:07.792+02:00PostgreSQL abbandonerà il supporto al download FTP<div style="text-align: justify;">
<a href="https://www.postgresql.org/message-id/09fd5ea6-7e09-3101-07ba-2c1d9f2d0aec%2540joeconway.com">Dal giorno 15 Agosto 2017 non sarà piu' possibile scaricare PostgreSQL tramite FTP!</a><br />
Come spiegato nella mailing list <i>pgsql-announce</i>, visto il basso traffico<br />
del protocollo FTP, nonché la vetustà del protocollo e dei relativi programmi,<br />
il team che mantiene l'infrastruttura ha deciso di <i>spegnere</i> l'accesso FTP.<br />
Questo non dovrebbe risultare in un particolare disservizio per gli utenti finali, quanto<br />
forse solo per alcune applicazioni e script automatici.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-18981907703597247022017-05-20T09:52:00.000+02:002017-05-20T09:52:23.792+02:00Noisli: un servizio di suoni per aumentare la concentrazione al lavoro<div style="text-align: justify;">
E' molto importante rimanere concentrati durante lo svolgimento del proprio lavoro, penso sia un concetto noto a tutti.<br />
Io ho la fortuna di svolgere un lavoro ad una scrivania, senza pubblico, quindi per estraniarmi dall'ambiente circostante utilizzo<br />
la musica e, raramente, la radio. Il mio cervello <i>aggancia</i> la melodia e non si fa distrarre da altre cose e rumori, lasciandomi<br />
quindi proseguire nel mio lavoro. Tuttavia non indico questa come possibile strategia di studio, che invece richiede maggior silenzio<br />
e in generale sonorità che il cervello non è in grado di "comprendere" razionalmente (es. parole).<br />
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Ecco, ho scoperto che esiste un servizio <i>Noisli</i> che consente di <i>comporre</i> un suono ambientale che possa aumentare la produttività<br />
individuale. Ad esempio mescolando il suono della pioggia battente con quello di un caminetto. E c'è anche chi ha pensato<br />
di integrare il servizio <a href="https://blogs.gnome.org/felipeborges/focusli/">dentro a Gnome</a>.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-22344301034474541592017-05-19T19:52:00.000+02:002017-05-19T19:52:08.899+02:00Arabic to Roman number converter in Perl 5Puzzled by a post on the Planet KDE about <a href="http://rudranilbasu.github.io//blog/kde/2017/05/12/GCompris-updates-on-roman-numerals/">GCompris and roman numbers</a>,
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.<br />
Not so easy, pal!<br />
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 <em>copy-and-paste</em> alghoritm. Please note: if you need a rock-solid way to handle conversions, have a look at <a href="http://search.cpan.org/search?query=roman&mode=all">CPAN</a> that is full of modules for this particular aim.<br />
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 <em>my</em> solution from scratch.<br />
<h1 id="the-program">
The program</h1>
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:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl">say <span class="kw">"</span><span class="dt">$_</span><span class="st"> = </span><span class="kw">"</span> . <span class="dt">$roman_string</span>->( <span class="dt">$reassemble</span>->( <span class="dt">$disassemble</span>->( <span class="dt">$_</span> ) ) )
<span class="kw">for</span> ( <span class="dv">1</span>..<span class="dv">30</span> );</code></pre>
</div>
that produces the following output:<br />
<pre><code>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
</code></pre>
The steps must be read from the inner subroutine to the outer, of course, and therefore we have:<br />
<ul>
<li><code>disassemble</code> 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 <em>linear</em> string of letters. As an example the number <code>4</code> is translated into <code>IIII</code>, which is of course a non-existent roman number.</li>
<li><code>reassemble</code> applies roman rules, in particular <em>promoting</em> numbers so that groups are translated, when needed, into higher order letters. For instance <code>IIII</code> is promoted into two groups: <code>I</code> and <code>V</code>.</li>
<li><code>roman_string</code> 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 <code>I</code> and <code>V</code> the function must understand if the output have to be <code>VI</code> (6) or <code>IV</code> (4).</li>
</ul>
To speed up the writing of the code, I placed main roman letters and their correspondance with arabic numbers into a <em>global</em> hash:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="kw">my</span> <span class="dt">$roman</span> = {
<span class="dv">1</span> => <span class="kw">'</span><span class="st">I</span><span class="kw">'</span>,
<span class="dv">5</span> => <span class="kw">'</span><span class="st">V</span><span class="kw">'</span>,
<span class="dv">10</span> => <span class="kw">'</span><span class="st">X</span><span class="kw">'</span>,
<span class="dv">50</span> => <span class="kw">'</span><span class="st">L</span><span class="kw">'</span>,
<span class="dv">100</span> => <span class="kw">'</span><span class="st">C</span><span class="kw">'</span>,
<span class="dv">500</span> => <span class="kw">'</span><span class="st">D</span><span class="kw">'</span>,
<span class="dv">1000</span> => <span class="kw">'</span><span class="st">M</span><span class="kw">'</span>,
};</code></pre>
</div>
Each method references <code>$roman</code> 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:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># 4 (IV)</span>
{ <span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => <span class="dv">1</span>, <span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">1</span> }
<span class="co"># 19 (XIX)</span>
{ <span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => <span class="dv">1</span>, <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">2</span> }
<span class="co"># 5 (V)</span>
{ <span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">1</span> }
<span class="co"># 17 (XVII)</span>
{ <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">1</span>, <span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">1</span>, <span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => <span class="dv">2</span> }</code></pre>
</div>
<h1 id="the-disassemble-function">
The <code>disassemble</code> function</h1>
The following is the code for the <code>disassemble</code> function, that accepts as only input the arabic number.<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># Accepts the arabic number and provides an hash</span>
<span class="co"># keyed by each letter, with the value of how many times</span>
<span class="co"># such letter should be summed in order to obtain the</span>
<span class="co"># starting number.</span>
<span class="kw">my</span> <span class="dt">$disassemble</span> = <span class="kw">sub</span>{
<span class="kw">my</span> ( <span class="dt">$number</span> ) = <span class="dt">@_</span>;
<span class="kw">my</span> <span class="dt">$items</span> = {};
<span class="co"># sort the keys, that are arabic thresolds, from</span>
<span class="co"># the greater to the smaller one</span>
<span class="kw">for</span> <span class="kw">my</span> <span class="dt">$current_value</span> ( <span class="fu">sort</span> { <span class="dt">$b</span> <=> <span class="dt">$a</span> } <span class="fu">keys</span> <span class="dt">$roman</span>-><span class="dt">%</span><span class="kw">*</span> ){
<span class="kw">my</span> <span class="dt">$how_many</span> = <span class="fu">int</span>( <span class="dt">$number</span> / <span class="dt">$current_value</span> );
<span class="kw">next</span> <span class="kw">unless</span> ( <span class="dt">$how_many</span> );
<span class="kw">my</span> <span class="dt">$letter</span> = <span class="dt">$roman</span>-><span class="dt">%</span>{ <span class="dt">$current_value</span> };
<span class="dt">$items</span>->{ <span class="dt">$letter</span> } = <span class="dt">$how_many</span>;
<span class="dt">$number</span> -= <span class="dt">$current_value</span> <span class="kw">*</span> <span class="dt">$how_many</span>;
}
<span class="kw">return</span> <span class="dt">$items</span>;
};</code></pre>
</div>
The first thing the method does it to create the hash <code>$items</code> that is what it will return to allow other methods to consume. Each key of the <code>$roman</code> hash is passed ordered by the bigger to the smaller (please note that <code>sort</code> has <code>$b</code> first!). In this way we can surely scompose the number from the thousands, hundreds, tens, and units in this exact order. The <code>$how_many</code> variable contains the integer part of each letter. For example the number <code>29</code> is processed as follows:<br />
<ol>
<li><code>29 / 10</code> that drives <code>$how_many</code> to be <code>2</code> and the remaining to be a <code>9</code>;</li>
<li><code>9 / 5</code> that makes <code>$how_many</code> to be <code>1</code> and the remaining to be a <code>4</code>;</li>
<li><code>4 / 1</code> that makes <code>$how_many</code> to be <code>4</code> and there's nothing more to do.</li>
</ol>
At each step the roman letter and the <code>$how_many</code> value is inserted into the <code>$items</code> has, that in the above ecample becomes:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># 29 (XIX)</span>
{ <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">2</span>,
<span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">1</span>,
<span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => <span class="dv">4</span>
}</code></pre>
</div>
<h1 id="the-reassemble-method">
The <code>reassemble</code> method</h1>
The <code>reassemble</code> method takes as input the hash produced by <code>disassemble</code> and checks if any letter requires a promotion. Here it is the code:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># Accepts an hash with keys the letters and values the number</span>
<span class="co"># of times each letter should appear.</span>
<span class="co"># Traverse the hash from the smaller to the greater</span>
<span class="co"># in order to "promote" smaller aggregates. For instance</span>
<span class="co"># 'IIII' (4) is aggregated and therefore the hash is modified</span>
<span class="co"># so there's only an 'I' and another 'V', in such case</span>
<span class="co"># the quantity of the promoted letter is negative to indicate</span>
<span class="co"># it has been promoted.</span>
<span class="kw">my</span> <span class="dt">$reassemble</span> = <span class="kw">sub</span>{
<span class="kw">my</span> ( <span class="dt">$items</span> ) = <span class="dt">@_</span>;
<span class="kw">my</span> <span class="dt">@sorted_thresolds</span> = <span class="fu">sort</span> { <span class="dt">$a</span> <=> <span class="dt">$b</span> } <span class="fu">keys</span> <span class="dt">$roman</span>-><span class="dt">%*;</span>
<span class="kw">for</span> ( <span class="kw">my</span> <span class="dt">$i</span> = <span class="dv">0</span>; <span class="dt">$i</span> < <span class="dt">@sorted_thresolds</span>; <span class="dt">$i</span>++ ){
<span class="kw">my</span> <span class="dt">$current_value</span> = <span class="dt">$sorted_thresolds</span>[ <span class="dt">$i</span> ];
<span class="kw">my</span> <span class="dt">$key</span> = <span class="dt">$roman</span>-><span class="dt">%</span>{ <span class="dt">$current_value</span> };
<span class="kw">my</span> <span class="dt">$how_many</span> = <span class="dt">$items</span>-><span class="dt">%</span>{ <span class="dt">$key</span> };
<span class="kw">next</span> <span class="kw">unless</span> ( <span class="dt">$how_many</span> );
<span class="kw">my</span> <span class="dt">$greater_value</span> = ( <span class="dt">$i</span> + <span class="dv">1</span> > <span class="dt">@sorted_thresolds</span> ? <span class="dv">1000</span> : <span class="dt">$sorted_thresolds</span>[ <span class="dt">$i</span> + <span class="dv">1</span> ] );
<span class="kw">my</span> <span class="dt">$greater_key</span> = <span class="dt">$roman</span>-><span class="dt">%</span>{ <span class="dt">$greater_value</span> };
<span class="kw">my</span> <span class="dt">$need_to_promote</span> = <span class="dt">$how_many</span> == <span class="dv">4</span>
|| ( <span class="dt">$greater_value</span> / <span class="dt">$current_value</span> == <span class="dt">$how_many</span> );
<span class="kw">if</span> ( <span class="dt">$need_to_promote</span> ){
<span class="dt">$items</span>->{ <span class="dt">$greater_key</span> }++;
<span class="dt">$how_many</span> = <span class="dt">$greater_value</span> - <span class="dt">$how_many</span> <span class="kw">*</span> <span class="dt">$current_value</span>;
<span class="dt">$items</span>->{ <span class="dt">$key</span> } = <span class="dt">$how_many</span> <span class="kw">*</span> -<span class="dv">1</span>;
}
}
<span class="kw">return</span> <span class="dt">$items</span>;
};</code></pre>
</div>
The <em>promotion</em> must be done from the smaller letter to the greater one, so this time the letters are walked in ascending order (i.e., <code>sort</code> has <code>$a</code> first!). Since to promote a letter I need to access the following one, I need a C-style <code>for</code> loop.<br />
A letter requires to be promoted if its quantity is <code>4</code> or /it is 2 and the right bigger value is exactly the double of the current one~, that is while <code>( $greater_value / $current_value == $how_many )</code>. This makes, for instance <code>IIII</code> to be promoted (the quantity is 4), and <code>VV</code> to be promoted into <code>X</code> (because the quantity is 2 and the <code>X</code> is exactly the double of <code>V</code>).
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).<br />
So for instance, the 29 hash of the previous paragraph is passed as follows:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># input to the method</span>
{ <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">2</span>,
<span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">1</span>,
<span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => <span class="dv">4</span>
}
<span class="co"># first for step (I)</span>
{ <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">2</span>,
<span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">2</span>,
<span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => -<span class="dv">1</span> <span class="co"># promoted, keep 1 and increase 'V'</span>
}
<span class="co"># second step (V)</span>
{ <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">3</span>,
<span class="kw">'</span><span class="st">V</span><span class="kw">'</span> => <span class="dv">0</span>, <span class="co"># promoted, increase X by one</span>
<span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => -<span class="dv">1</span>
}</code></pre>
</div>
At the end of method we know the final string will be made by three <code>X</code> and one <code>I</code>, the point now is to understand how to render them in the correct order. This is the aim of the <code>roman_string</code> method.<br />
<h1 id="the-roman_string-method">
The <code>roman_string</code> method</h1>
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:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># Do the hard work of composing</span>
<span class="co"># each group of letters in order to compose the roman string.</span>
<span class="kw">my</span> <span class="dt">$roman_string</span> = <span class="kw">sub </span>{
<span class="kw">my</span> ( <span class="dt">$items</span> ) = <span class="dt">@_</span>;
<span class="kw">my</span> <span class="dt">@chars</span>;
<span class="kw">for</span> <span class="kw">my</span> <span class="dt">$current_value</span> ( <span class="fu">sort</span> { <span class="dt">$b</span> <=> <span class="dt">$a</span> } <span class="fu">keys</span> <span class="dt">$roman</span>-><span class="dt">%</span><span class="kw">*</span> ){
<span class="kw">my</span> <span class="dt">$letter</span> = <span class="dt">$roman</span>-><span class="dt">%</span>{ <span class="dt">$current_value</span> };
<span class="kw">my</span> <span class="dt">$how_many</span> = <span class="dt">$items</span>-><span class="dt">%</span>{ <span class="dt">$letter</span> };
<span class="kw">next</span> <span class="kw">unless</span> ( <span class="dt">$how_many</span> );
<span class="kw">if</span> ( <span class="dt">$how_many</span> > <span class="dv">0</span> ){
<span class="fu">push</span> <span class="dt">@chars</span>, <span class="dt">$letter</span> <span class="kw">for</span> ( <span class="dv">1</span> .. <span class="dt">$how_many</span> );
}
<span class="kw">else</span>{
<span class="co"># this is promoted, so it has to be inserted as last-to-last</span>
<span class="co"># in the previous chain</span>
<span class="co"># example: @chars( X, X ) and here I've 'I' to make XIX (19)</span>
<span class="fu">push</span> <span class="dt">@chars</span>, ( <span class="dt">$letter</span>, <span class="fu">pop</span> <span class="dt">@chars</span> );
}
}
<span class="kw">return</span> <span class="fu">join</span> <span class="kw">""</span>, <span class="dt">@chars</span>;
};</code></pre>
</div>
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 <code>@chars</code> array, that is then <code>join</code> -ed into a single string.<br />
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 <code>$roman</code> (again, note that <code>sort</code> has <code>$b</code> first!). If the quantity of the letter is positive <em>the letter has not been promoted</em> and therefore it will not be placed to the left of another letter, so just insert into <code>@chars</code> the <code>$letter</code> for the <code>$how_many</code> quantity. On the other hand, if <code>$how_many</code>
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:<br />
<code>push @chars, ( $letter, pop @chars );</code><br />
that inserts into <code>@chars</code> the <code>$letter</code> and the previous last character that has been removed via <code>pop</code>.<br />
With regards to the previous example of <em>29</em> we have that:<br />
<div class="sourceCode">
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="co"># method input</span>
{ <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> => <span class="dv">3</span>,
<span class="kw">'</span><span class="st">I</span><span class="kw">'</span> => -<span class="dv">1</span>
}
<span class="co"># first step: prints X</span>
<span class="co"># with quantity 3 (not promoted)</span>
<span class="dt">@chars</span> = ( <span class="kw">'</span><span class="st">X</span><span class="kw">'</span>, <span class="kw">'</span><span class="st">X</span><span class="kw">'</span>, <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> );
<span class="co"># second step: prints I</span>
<span class="co"># that has been promoted</span>
<span class="co"># and must be inserted ascending</span>
<span class="co"># as last-to-last</span>
<span class="dt">@chars</span> = ( <span class="kw">'</span><span class="st">X</span><span class="kw">'</span>, <span class="kw">'</span><span class="st">X</span><span class="kw">'</span> ,
( <span class="kw">'</span><span class="st">I</span><span class="kw">'</span>, <span class="co"># $letter</span>
<span class="kw">'</span><span class="st">X</span><span class="kw">'</span> <span class="co"># pop @chars</span>
) );</code></pre>
</div>
<h1 id="conclusions">
Conclusions</h1>
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 <code>for</code> 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!Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com2tag:blogger.com,1999:blog-1836481905487384887.post-16200683175878839272017-05-19T19:47:00.001+02:002017-05-19T19:47:26.277+02:00PostgreSQL 10 beta 1!<div style="text-align: justify;">
Ci siamo!<br />
PostgreSQL 10 fa finalmente capolino nel mondo con il rilascio, ieri, della prima <i><a href="https://www.postgresql.org/about/news/1749/">beta release</a></i>.<br />
Il <a href="https://www.postgresql.org/download/snapshots/">download</a> comprende pacchetti binari per le maggiori distribuzioni, oltre ovviamente alla possibilità<br />
di compilare i sorgenti, <a href="https://www.postgresql.org/ftp/source/">anch'essi scaricabili come archivi</a>.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0tag:blogger.com,1999:blog-1836481905487384887.post-89292557540425748332017-05-13T15:52:00.000+02:002017-05-13T15:52:05.149+02:00KDE e cgit<div style="text-align: justify;">
Il progetto <a href="http://www.kde.org/">KDE</a> utilizza <a href="https://git.zx2c4.com/cgit/about/">cgit</a> come frontend web per i repository git.<br />
Il progetto <a href="https://git.zx2c4.com/cgit/about/">cgit</a> fornisce un accesso web <i>super fast</i> ai repository git, con<br />
alcune funzione di utilità specifiche come il riconoscimento dei repository <i>on-the-fly</i>.<br />
Sicuramente rappresenta una valida alternativa alle molteplici interfacce web<br />
già presenti sul mercato.<br />
</div>
Luca Ferrarihttp://www.blogger.com/profile/16294282439525862660noreply@blogger.com0