<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Stathis Sideris</title>
 <link href="http://www.stathis.co.uk/atom.xml" rel="self"/>
 <link href="http://www.stathis.co.uk"/>
 <updated>2012-03-18T13:07:23-04:00</updated>
 <id>http://www.stathis.co.uk/</id>
 <author>
   <name>Stathis Sideris</name>
   <email>stathis@stathis.co.uk</email>
 </author>
 
 
 <entry>
   <title>Self-explanatory code</title>
   <link href="http://www.stathis.co.uk/self-explanatory-software"/>
   <updated>2012-03-04T00:00:00-05:00</updated>
   <id>id:/self-explanatory-software</id>
   <content type="html">&lt;p&gt;In most database systems, there is the
&lt;a href=&quot;http://www.sql.org/sql-database/postgresql/manual/sql-explain.html&quot;&gt;EXPLAIN&lt;/a&gt;
command, which when given a query, it will tell you how the database
system will execute the query. This provides you with the query plan,
which tells you which indices will be looked up in the database, and
other possibly non-obvious performance tuning that might happen to
your query. I was always fascinated with EXPLAIN, because it is a bit
unusual in the sense that it's a piece of code that takes another
piece of code as its parameter, looks at it, and tells you what it
will do. The self-referential nature of this made it exciting.&lt;/p&gt;

&lt;p&gt;For a bit less than a year now, I have been developing the
&lt;a href=&quot;https://github.com/stathissideris/clarity&quot;&gt;Clarity&lt;/a&gt; library, which
can be used to develop GUIs in &lt;a href=&quot;http://clojure.org/&quot;&gt;clojure&lt;/a&gt;. It's
been a very interesting experience, and the library is getting to the
point where it can automate useful GUI tasks, like styling a hierarchy
of Swing components using a pre-defined stylesheet. This kind of
automation can feel a bit magical to the developer, because they may
not be familiar with the exact semantics of stylesheets. In order to
make development with Clarity a bit easier (and to scratch my itch), I
have introduced the &lt;code&gt;explain&lt;/code&gt; macro in the &lt;code&gt;clarity.dev&lt;/code&gt; namespace.&lt;/p&gt;

&lt;p&gt;Currently the &lt;code&gt;explain&lt;/code&gt; macro only supports explaining what will
happen when a stylesheet is applied to a hierarchy of
components. Let's look at a working example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;testing&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:use&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;clarity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;make&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;clarity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;style&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;clarity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;;;a stylesheets that makes all buttons&amp;#39; backgrounds red&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defstylesheet&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;the-style&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:background&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:red&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;;;a panel with just 2 buttons&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;panel&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:panel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:id&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;panel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:button&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Test&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:id&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;button1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;make&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:button&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Test 2&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;:id&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;button2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now, you can ask Clarity to explain what will happen when &lt;code&gt;the-style&lt;/code&gt;
is applied to &lt;code&gt;panel&lt;/code&gt;. In the REPL:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&lt;span class=&quot;nv&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;explain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply-stylesheet&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;panel&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;the-style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;...and you get:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;--- Showing matches only ---
1 out of 1 styles match

---

Style: &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt; :button&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Mutator:
  &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;:background &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;color :red&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
Matches &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:
  &lt;span class=&quot;nv&quot;&gt;$panel&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$button1&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$panel&lt;/span&gt;/&lt;span class=&quot;nv&quot;&gt;$button2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If your components did not have an ID nor a category, the output of
the matches would look slightly less attractive, but it would still be
readable.&lt;/p&gt;

&lt;p&gt;By default, &lt;code&gt;explain&lt;/code&gt; will show you only the styles that match at
least one component in your component hierarchy, but you can make it
show all styles, or only the ones that will not match at all:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;clojure&quot;&gt;&lt;span class=&quot;c1&quot;&gt;;;show everything&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;explain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply-stylesheet&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;panel&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;the-style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:show&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;;;show not matched&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;explain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;apply-stylesheet&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;panel&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;the-style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:show&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;:not-matched&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;explain&lt;/code&gt; ony covers stylesheets for the time being. I'm planning to
extend its functionality as appropriate. Clojure being a Lisp makes
the development of such &quot;meta&quot; functionality very enjoyable and you
end up with developer-friendly software.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>David Foster Wallace speech</title>
   <link href="http://www.stathis.co.uk/david-foster-wallace-speech"/>
   <updated>2011-06-23T00:00:00-04:00</updated>
   <id>id:/david-foster-wallace-speech</id>
   <content type="html">&lt;p&gt;I have translated here into Greek a speech of the late author David Foster Wallace, which was &lt;a href=&quot;http://www.guardian.co.uk/books/2008/sep/20/fiction&quot;&gt;originally published in the Guardian&lt;/a&gt;. If you're not Greek, it's still definitely worth reading the original, it's very insightful.&lt;/p&gt;

&lt;p&gt;Στο παρακάτω κείμενο μετέφρασα έναν λόγο που είχε βγάλει ο David Foster Wallace, ένας Αμερικάνος συγγραφέας που πέθανε το 2008, για μια αποφοίτηση στο Kenyon College στο Ohio. &lt;a href=&quot;http://www.guardian.co.uk/books/2008/sep/20/fiction&quot;&gt;Αρχικά το κείμενο δημοσιεύτηκε&lt;/a&gt; στην Αγγλική εφημερίδα Guardian, με τίτλο (κατά προσέγγιση) &lt;em&gt;&quot;Οικεία, ντεμοντέ προβλήματα και συναισθήματα&quot;&lt;/em&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Είναι δύο πιτσιρίκια ψάρια και καθώς κολυμπούν πετυχαίνουν ένα γέρικο ψάρι που κολυμπάει προς την αντίθετη κατεύθηνση. Το γέρικο ψάρι τα χαιρετάει και λέει: &quot;Καλημέρα παιδιά, πως σας φαίνεται το νερό σήμερα;&quot; και τα προσπερνάει. Τα μικρά ψαράκια κολυμπούν για λίγο αμίλητα μέχρι που το ένα γυρνάει και ρωτάει το φίλο του &quot;Τι σκατά είναι αυτό το «νερό»;&quot;&lt;/p&gt;

&lt;p&gt;Μην φοβάστε οτι σκοπεύω να φανώ σαν σοφό γέρικο ψάρι. Δεν είμαι το σοφό ψάρι. Το άμεσο συμπέρασμα της παραπάνω ιστόριας είναι οτι οι πιο προφανείς, πανταχού παρούσες και σημαντικές αλήθειες συχνά είναι οι πιο δυσδιάκριτες και αυτές που είναι και πιο δύσκολο να τις εκφράσουμε. Βέβαια αυτό σαν φράση στα Αγγλικά ακούγεται εντελώς σαν ασήμαντη κοινοτυπία, αλλά στα χαρακώματα της ενήλικης ζωής καμμιά φορά οι κοινοτυπίες γίνονται ζήτημα ζωής και θανάτου. Μπορεί όλα αυτά να σας φαίνονται υπερβολικά ή πολύ αφηρημένα, οπότε ας γίνω πιο συγκεκριμένος...&lt;/p&gt;

&lt;p&gt;Ένα τεράστιο ποσοστό πραγμάτων για τα οποία είμαι απόλυτα βέβαιος, είναι, απ'ότι φαίνεται, τελείως λάθος. Ορίστε ένα παράδειγμα για το πόσο εντελώς λάθος είναι κάτι που σε γενικές γραμμές τείνω να πιστεύω ακράδαντα: τα πάντα στην άμεση εμπειρία μου υποστηρίζουν την βαθεία ριζωμένη άποψη μου οτι είμαι το απόλυτο κέντρο του σύμπαντος, το πιο αληθινό, ζωντανό και σημαντικό άτομο που υπάρχει. Σπανίως μιλάμε για αυτόν το φυσικό και βασικό εγωκεντρισμό, επειδή σε κοινωνικό πλαίσιο ειναι κατάπτυστος, αλλά για όλους είναι λίγο-πολύ το ίδιο μέσα μας. Ετσι είναι η εργοστασιακή μας ρύθμιση, εντυπωμένη στην πλακέτα μας εκ γεννετής. Σκεφτείτε το: δεν είχατε ποτέ καμμία εμπειρία στην οποία δεν πρωταγωνιστούσατε. Ο κόσμος όπως τον βιώνετε βρίσκεται εκεί μπροστά σας, ή πίσω σας, δεξιά ή αριστερά σας, στην τηλεόραση σας, στην οθόνη σας, κλπ. Οι σκέψεις άλλων ανθρώπων έχουν φτάσει στην αντίληψη σας με κάποιους τρόπους, αλλά οι δικές σας σκέψεις είναι πολύ πιο άμεσες, πιο επείγουσες, πιο αληθινές -- με πιάνετε πιστεύω. Μην ανησυχείτε οτι θα σας κάνω κύρηγμα για αλληλεγγύη, αλληλοκατανόηση και άλλες τέτοιες «αρετές». Το θέμα δεν είναι η αρετή -- το θέμα είναι να επιλέξω να κάνω την απαιτούμενη δουλειά για να αλλάξω ή να απελευθερωθώ από τη φυσική, εργοστασιακή μου ρύθμιση, η οποία υπαγορεύει βαθύ και κυριολεκτικό εγωκεντρισμό, και με κάνει να βλέπω και να ερμηνεύω τα πάντα μέσα απο την σκοπιά του εαυτόυ μου.&lt;/p&gt;

&lt;p&gt;Για παράδειγμα, ας πούμε οτι μια κανονική μέρα ξυπνάς το πρωί, πας στην δουλειά σου και δουλευέις σκληρά για εννιά-δέκα ώρες, και στο τέλος της μέρας είσαι κουρασμένος, και αγχωμένος, και απλά θέλεις να πας σπίτι να φας ένα ωραίο βραδυνό, να χαλαρώσεις δυό ώρες και να πας για ύπνο νωρίς γιατί αύριο πρέπει να ξυπνήσεις νωρίς και να κάνεις πάλι τα ίδια. Αλλα συνειδητοποιείς οτι δεν έχεις φαι στο σπίτι -- δεν πρόλαβες να πας για ψώνια αυτή τη βδομάδα γιατί δουλεύεις πολλές ώρες -- και τώρα, μετά τη δουλειά, πρέπει να πάρεις το αυτοκίνητο και να πας στο super market. Εχουν σχολάσει όλοι και έχει πολύ κίνηση, οπότε η μετακίνηση πέρνει πιο πολύ από το κανονικό, και όταν φτάνεις στο super market έχει πολύ κόσμο, γιατί φυσικά είναι η ώρα που κι όλοι οι άλλοι εργαζόμενοι πάνε να κάνουν τα ψώνια τους, και το supermarket έχει αυτόν τον απαίσιο φωτισμό φθωρισμού, και ακούγεται και αυτή η τυποποιημένη ποπ μουσική απο τα ηχεία, και γενικά δεν θέλεις να βρίσκεσαι εκεί, αλλά δεν μπορείς να ξεμπερδέψεις γρήγορα: πρέπει να περιπλάνηθεις στους απέραντους διαδρόμους, κατάμεστους με κόσμο και με εκτυφλωτικά φώτα, για να εντοπίσεις τα πράγματα που θέλεις, και πρέπει να μανουβράρεις το καροτσάκι σου ανάμεσα σε κουρασμένους, βιαστικούς ανθρώπους με καροτσάκια, και βέβαια υπάρχουν και παππούδες που κινούνται με ταχύτητα παγετώνων, υπάρχουν διάφοροι που είναι χάμενοι στο διάστημα, παιδάκια που κάθονται μεσ'τη μέση και σε μπλοκάρουν και σφίγγεις τα δόντια για να μην τα βρίσεις, και τελικά, μετά απ'όλα αυτα, βρίσκεις αυτά που ήθελες, πας στα ταμεία, αλλά δεν εχούν βάλει αρκετό προσωπικό στα ταμεία, παρόλο που είναι ώρα αιχμής, οπότε οι ουρές είναι ατέλειωτες, πράγμα ηλίθιο και εξοργιστικό, αλλά δεν μπορείς να εκτονώσεις την οργή σου στην κυρία που δουλεύει στο ταμείο γιατί έχει βάλει τα δυνατά της να εξυπηρετήσει τον κόσμο γρήγορα.&lt;/p&gt;

&lt;p&gt;Με τα πολλά έρχεται η σειρά σου, πληρώνεις, πέρνεις τις εύθραστες σακούλες σου με τα φαγητά στο καροτσάκι και μπαίνεις στο κατάμεστο parking που είναι γεμάτο με λακούβες και σκουπίδια, βάζεις τις σακούλες στο αυτοκίνητο προσεκτικά για να μην αδειάσουν ενώ οδηγείς, και μετά πρέπει να επιστρέψεις σπίτι οδηγώντας σε πυκνή κίνηση επειδή έχουν σχολάσει όλοι κλπ, κλπ.&lt;/p&gt;

&lt;p&gt;Το θέμα είναι οτι η ευκαιρία για επιλογή εμφανιζεται σε τέτοια μικρά και σπαστικά πράγματα. Τα μποτιλιαρίσματα, τα κατάμεστα super market και οι τεράστιες ουρές είναι για μένα στιγμές που έχω χρόνο να κάνω σκέψεις και αν δεν πάρω μια συνειδητή απόφαση για το τί θα σκεφτώ και που θα στρέψω την προσοχή μου, θα τσαντίζομαι και θα αγχώνομαι κάθε φορά που πάω για ψώνια, γιατί σύμφωνα με την εργοστασιακή μου ρύθμιση σε αυτές τις καταστάσεις εγώ είμαι το κέντρο της προσοχής, η πείνα μου και η κούραση μου και η επιθυμία μου να πάω σπίτι, οπότε μου φαίνονται όλοι οι άλλοι σαν εμπόδια, και με ποιό δικαίωμα με μπλοκάρουν κατ'αυτό το τρόπο; Και δες πόσο αποκρουστικοί είναι οι περισσότεροι, και πόσο βλάκες και πρόβατα φαίνονται όταν περιμένουν στην ουρά, ή πόσο ενοχλητικοί και αγενείς είναι αυτοί που φωνάζουν μιλώντας στο κινητό στην μέση της ουράς, και ποσό άδικο είναι που δούλευα τόσο σκληρά όλη μέρα, και πεθαίνω της πείνας, και είμαι κουρασμένος, και δεν μπορώ να πάω σπίτι μου να φάω και να χαλαρώσω γιατί με εμποδίζουν όλοι αυτοί οι ηλίθιοι.&lt;/p&gt;

&lt;p&gt;Αλλιώς, αν η εργοστασιακή μου ρύθμιση ήταν πιο πολύ προς το κοινωνικά ευαίσθητο, θα μπορούσα να περάσω τον χρόνο του μποτιλιαρίσματος τσαντισμένος και αηδιασμένος με τα τεράστια τζιπ, που κλείνουν το δρόμο και καίνε αβέρτα καύσιμα στα τεραστια ρεζερβουάρ τους, και να κάτσω να σκεφτώ οτι ο τύπος με τα πατριωτικά ή θρησκετικά αυτοκόλλητα στο πίσω τζάμι, είναι συνήθως ο ίδιος τύπος που οδηγεί το πιο ρυπογόνο όχημα, άσε που είναι άσχημος και οδηγεί επιθετικά, ενώ μιλάει στο κινητό και σε κόβει για να βγει 20 ανούσια μέτρα πιο μπροστά στο μποτιλιάρισμα. Και μπορώ να σκεφτώ οτι τα παιδιά των παιδιών μας θα μας απεχθάνονται γιατί σπαταλήσαμε τα καύσιμα και καταστρέψαμε το κλίμα του πλανήτη, και πόσο κακομαθημένοι και χαζοί και αηδιαστικοί είμαστε, και σε τι σκατοκατάσταση έχουμε μπλέξει...&lt;/p&gt;

&lt;p&gt;Μπορώ να επιλέξω να σκεφτώ έτσι, και αυτό είναι εντάξει, πολλοί από εμάς κάνουν αυτή την επιλογή. Από την άλλη, αυτός ο τρόπος σκέψης είναι τόσο αυτόματος και έρχεται τόσο φυσικά που δεν χρειάζεται καν να επιλέξεις. Αυτός ο τρόπος σκέψης είναι η κανονική μου ρύθμιση. Είναι ο αυτόματος, υποσυνείδητος τρόπος που βιώνω τα βαρετά, ενοχλητικά κομμάτια της ενήλικης ζωής, όταν λειτουργώ με την αυτόματη, υποσυνείδητη πεποίθηση οτι είμαι το κέντρο του σύμπαντος και οι άμεσες ανάγκες και συναισθήματά μου πρέπει να καθορίζουν τις προτεραιότητες όλου του κόσμου. Το θέμα είναι οτι υπάρχουν προφανώς διαφορετικοί τρόποι σκέψης όσον αφορά αυτές τις καταστάσεις. Μέσα στην κίνηση, τα αυτοκίνητα είναι κολλημένα... δεν αποκλείεται κάποιοι από αυτούς με τα μεγάλα τζιπ να έχουν εμπλακεί στα τραγικά ατυχήματα και τώρα να τους είναι τόσο δύσκολο να οδηγήσουν που ο ψυχολόγος τους τους σύστησε να πάρουν ένα μεγάλο τζιπ ώστε να νιώθουν πιο ασφαλείς στον δρόμο. Ή το αυτοκίνητο που μου έκοψε τον δρόμο το οδηγεί κάποιος που το παιδί του έχει χτυπήσει ή είναι άρρωστο και το πάει στο νοσοκομείο, οπότε η δικιά του βιασύνη είναι πολύ πιο σημαντική από την δικιά μου, και τελικά εγώ είμαι το εμπόδιο και όχι αυτός.&lt;/p&gt;

&lt;p&gt;Και πάλι να πω οτι δεν προσπαθώ να ηθικολογήσω, ή να σας πώ οτι &quot;θα πρέπει&quot; να σκέφτεστε με αυτόν τον τρόπο, ή οτι απαιτήται να είναι αυτά τα &quot;αντανακλαστικά&quot; σας, γιατί είναι δύσκολο, απαιτεί θέληση και πνευματική προσπάθεια, και αν είστε σαν κι εμένα, κάποιες φορές δεν θα μπορέσετε να το κάνετε, ή απλά δεν θα θέλετε να το κάνετε. Τις πιό πολλές φορές όμως, αν έχετε αρκετή διάυγεια για να επιλέξετε, μπορείτε να επιλέξετε να δείτε με άλλο μάτι την χοντρή κυρία με το απλανές βλέμμα και το υπερβολικό μέικ-απ που μόλις μάλωσε το παιδάκι της στην γραμμή για το ταμείο: ίσως να μην είναι συνήθως έτσι, ίσως να έχει μείνει άγρυπνη τρια συνεχόμενα βράδια κρατώντας το χέρι του άντρα τις που πεθαίνει απο καρκίνο των οστών, ή ίσως να είναι η υπάλληλος που βοήθησε τον σύζυγο σας να λύσει το εφιαλτικό γραφειοκρατικό μπέρδεμα που είχε στην εφορία κάνοντας του μια μικρή διευκόλυνση. Φυσικά, τίποτα από όλα αυτά είναι ιδιαίτερα πιθανόν, αλλά από την άλλη δεν είναι και αδύνατον -- εξαρτάται από το πώς θα το σκεφτείτε. Αν είστε αυτομάτως σίγουροι για το ποιά είναι η πραγματικότητα, και για το ποιός και τί είναι σημαντικό, αν θέλετε να λειτουργείτε στην &quot;εργοσταστιακή&quot; σας ρύθμιση, τότε, όπως κι εγώ, δεν θα αναλογιστήτε τις περιπτώσεις που δεν είναι ενοχλητικές και σπαστικές. Αλλά αν έχετε μάθει πώς να σκέφτεστε, και πώς να επικεντρώνετε την προσοχή σας, τότε θα ξέρετε ότι υπάρχουν διάφορες πιθανότητες. Θα μπορέσετε να βιώσετε τις φάσεις με τον πολύ κόσμο που κάνουν φασαρία, σας καθυστερούν, τις εφιαλτικές καταναλωτικές φάσεις, ώς κάτι που όχι μόνο έχει νόημα, αλλά είναι και ιερό, και που έχει ανάψει με την ίδια φωτιά που άναψε τα άστρα: συμπόνοια, αγάπη και η υπόγεια ενότητα που συνδέει τα πάντα. Όχι οτι οι μυστικισμοί είναι απαραίτητα αλήθεια: η μόνη Αλήθεια με &quot;Α&quot; κεφαλαίο είναι οτι εσύ αποφασίζεις πώς θα προσπαθήσεις να το δεις. Μπορείς να επιλέξεις συνειδητά τί έχει νόημα και τί όχι. Μπορείς να αποφασίσεις τί να προσκυνήσεις.&lt;/p&gt;

&lt;p&gt;Γιατί νά και κάτι άλλο που είναι αλήθεια. Στην καθημερινότητα της ενήλικης ζώης, δεν υπάρχει αθεΐα. Δεν γίνεται να μην λατρεύεις. Όλοι προσκυνάνε κάτι. Το ερώτημα είναι τι επιλέγουμε. Και ένας καλός λόγος για να επιλέξεις κάποιον θεό ή κάποιο πνευματικό πράγμα προς λατρεία -- είτε είναι ο Ιησούς ή ο Αλλάχ, είτε ο Γιαχβέ, ή η μητριαρχική θεά των παγανιστών μάγων, ή οι Τέσσερεις Αγαθές Αλήθειες ή κάποιες απαράβατες ηθικές αρχές -- είναι ότι σχεδόν οτιδήποτε άλλο θα σε φάει ζωντανό. Αν λατρεύεις τα λεφτά και τα υλικά αγαθά -- αν εκεί καταφεύγεις για να δώσεις νόημα στη ζωή σου -- δεν θα έχεις ποτέ αρκετά. Ποτέ δεν θα νιώσεις οτι είναι αρκετά, έτσι είναι. Αν λατρεύεις το σώμα σου και την ομορφία σου και την θελκτικότητα σου, θα νιώθεις πάντα άσχημος, και όταν σε πάρουν τα χρόνια και αρχίσεις να σπας, θα πεθάνεις χίλιες φορές πριν τελικά σε &quot;φυτέψουν&quot;. Σε κάποιο επίπεδο αυτά τα ξέρουμε όλοι ήδη, έχουν κωδικοποιηθεί σε μύθους, παροιμίες, κοινοτυπίες, ρητά και παραβολές: η ραχοκοκαλειά κάθε καλής ιστορίας. Το δύσκολο είναι να κρατήσεις αυτές τις αλήθειες στην καθημερινή σου αντίληψη. Αν λατρεύεις την εξουσία θα νιώθεις αδύναμος και φοβισμένος και θα αποζητάς παραπάνω εξουσία πάνω στους άλλους για να καταπραΰνεις τον φόβο σου. Αν λατρεύεις το μυαλό σου θα νιώθεις χαζός και θα νομίζεις οτι τους έχεις ξεγελάσει όλους για το ότι είσαι έξυπνος, και θα ανησυχείς οτι θα το ανακαλύψουν.&lt;/p&gt;

&lt;p&gt;Το ύπουλο πράγμα σχετικά με αυτές τις μορφές λατρείας δεν είναι οτι είναι ανήθικες ή αμαρτωλές -- είναι οτι είναι υποσυνείδητες. Είναι το είδος λατρείας στο οποίο μπαίνεις σταδιακά, μέρα με τη μέρα, και γίνεσαι όλο και πιο επιλεκτικός για το τί αντιλαμβάνεσαι και το πώς μετράς την αξία των πραγμάτων, χωρίς ποτέ να συνειδητοποιείς τι κάνεις. Και ο κόσμος δεν θα σε αποτρέψει απο το να λειτουργήσεις στις &quot;εργοστασιακές&quot; σου ρυθμίσεις, επειδή ο κόσμος των ανδρών και του χρήματος και της εξουσίας, λειτουργεί μια χαρά με καύσιμο τον φόβο και την περιφρόνηση και την ματαίωση και λαχτάρα και την λατρεία του εαυτού. Ο πολιτισμός μας έχει εκμεταλλευτεί αυτές τις δυνάμεις με τρόπους που παράγουν τεράστια κέρδη, άνεση και προσωπική ελευθερία. Την ελευθερία να είμαστε κυρίαρχοι ενός μικρού βασίλειου μέσα στο κεφάλι μας, μόνοι, στο κέντρο όλης της πλάσης. Αυτού του είδους η ελευθερία έχει να πει πολλά, αλλά υπάρχουν και άλλα είδη, και το πιο πολύτιμο είδος ελευθερίας δεν θα ακούσετε να το συζητούν πολύ στον κόσμο της ανταγωνιστικότητας, των επιτευγμάτων και της αυτοπροβολής. Το μόνο πραγματικά σημαντικό είδος ελευθερίας απαιτεί προσοχή, συνειδητότητα, πειθαρχία, προσπάθεια, και την ικανότητα να νοιάζεσαι πραγματικά για άλλους ανθρώπους και να θυσιάζεσαι γι'αυτούς, ξανά και ξανά, με χιλιάδες τρόπους κάθε μέρα. Αυτή είναι η πραγματική ελευθερία. Η εναλλακτική είναι η έλλειψη συνειδητότητας, η &quot;εργοστασιακή&quot; ρύθμιση, να τρέχεις και να μη φτάνεις, και η συνεχής βασανιστική αίσθηση οτι έχεις χάσει κάτι που αγγίζει το άπειρο.&lt;/p&gt;

&lt;p&gt;Ξέρω οτι όλα αυτά μάλλον δεν φαντάζουν και πολύ ευχάριστα ή εύκολα και μάλλον δεν εμπνέουν πολύ. Απ'όσο ξέρω, αυτή είναι η αλήθεια, αν αφαιρέσεις τις ρητορικές μαλακίες. Προφανώς εσείς σκεφτείτε ότι θέλετε. Αλλά σας παρακαλώ μην το αγνοήστε σα να είναι ηθικολογικό κύρηγμα. Τίποτα απο αυτά που είπα δεν αφορά την ηθική, ή την θρησκεια, ή δογματισμούς ή μεγάλα ερωτήματα για την μετά θάνατον ζωή. Η Αλήθεια με &quot;Α&quot; κεφαλαίο αφορά την ζωή &lt;em&gt;πριν&lt;/em&gt; το θάνατο. Αφορά το να φτάσεις τα 30 σου ή και ίσως τα 50 σου, χώρις να καταλήξεις να θες να τινάξεις τα μυαλά σου στον αέρα. Έχει να κάνει με την απλή αντίληψη -- την αντίληψη ενός πράγματος που είναι αληθινό και βασικό, και τόσο καλά κρυμένο μπροστά στα μάτια μας που πρέπει συνέχεια να υπενθυμίζουμε στους εαυτούς μας οτι &quot;αυτό είναι νερό, αυτό είναι νερό.&quot;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Perl sort tutorial</title>
   <link href="http://www.stathis.co.uk/perl-sort-tutorial"/>
   <updated>2007-07-23T00:00:00-04:00</updated>
   <id>id:/perl-sort-tutorial</id>
   <content type="html">&lt;p&gt;Perl's &lt;code&gt;sort&lt;/code&gt; function is very useful in its simplest form, but it can become very powerful quickly if you learn how to use the extra functionality that it provides. Here we look at the simplest cases of sorting, then we go on to examine ways to perform custom sorting, and finally we look at an example that uses sort on a more complex data structrure.&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;Different parts of this article assume different levels of expertise, but in order to understand everything, you need to know about arrays and references. Also, it would be nice (but not essential) to have encountered the &lt;code&gt;join&lt;/code&gt; function before.&lt;/p&gt;

&lt;p&gt;Also, see the &lt;a href=&quot;http://perldoc.perl.org/functions/sort.html&quot;&gt;official documentation&lt;/a&gt; for sort.&lt;/p&gt;

&lt;h2&gt;The Simplest Case&lt;/h2&gt;

&lt;p&gt;The simplest case of sort would be something like that:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Which produces the following output:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;1, 2, 2, 4, 6, 65, 93
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Note that Perl will sort a list in the &quot;natural order&quot; of the data, so if you have a list that contains both numbers and strings, it will be sorted in alphanumeric order:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;pear&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;four&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;apple&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Produces:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;3, 7, apple, four, pear
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;A common misconception about sort has to do with the fact that the function does not have any effect on the original list. &lt;code&gt;sort&lt;/code&gt; does not sort the original list, instead it takes the elements of a list, sorts them and returns them as a new list. So, the following does nothing:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;...and you probably meant to say that:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Custom Sorting&lt;/h2&gt;

&lt;p&gt;The default behaviour of sort is to sort numbers and strings in ascending order. This not always desirable, sometimes we would like to order things in descending order. Also, we might want to override the default behaviour of sorting in the most &quot;natural&quot; way: we may want to sort a numerical list in an aplhanumerical manner (to look at the numbers as text).&lt;/p&gt;

&lt;p&gt;The behaviour of &lt;code&gt;sort&lt;/code&gt; can be modified by providing a, usually short, block of Perl code before the list. This is how a descending sort would look like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Produces:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;93, 65, 6, 4, 2, 2, 1
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The block of code that customises the sorting is &lt;code&gt;{$b &amp;lt;=&amp;gt; $a}&lt;/code&gt;. The two variables &lt;code&gt;$a&lt;/code&gt; and &lt;code&gt;$b&lt;/code&gt; are not declared elsewhere in our program, they are both internal variables declared by sort and they have a special meaning: they represent the two elements from list &lt;code&gt;@theList&lt;/code&gt; that are compared in pairs by sort to determine how to order the list. The order of the two variables in this block of code is significant: &lt;code&gt;$b&lt;/code&gt; and &lt;code&gt;$a&lt;/code&gt; comes after and that causes the sorting to happen in descending order. The &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; operator causes the comparison to happen numerically: &lt;code&gt;$a&lt;/code&gt; and &lt;code&gt;$b&lt;/code&gt; are compared as numbers.&lt;/p&gt;

&lt;p&gt;Here is an example of descending aplhanumerical (string) sorting. The string comparison &lt;code&gt;cmp&lt;/code&gt; operator sould be used instead:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;pear&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;four&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;apple&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;pear, four, apple, 7, 3
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;To get a better feel of the differences between numerical and aplhanumeric sorting, look what happens when you sort numbers as if they were strings (in ascending order this time):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;205&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;1, 100, 2, 2, 2000, 205, 4, 6, 65, 93
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Yes, it looks crazy, but aplhanumerically, the string '205' comes before the string '4' because it starts with the character '2' which is a 'smaller' than character '4'.&lt;/p&gt;

&lt;p&gt;Also, you can process the passed elements &lt;code&gt;$a&lt;/code&gt; and &lt;code&gt;$b&lt;/code&gt; before sorting them. This would prove useful for sorting a list of strings by ignoring the case of the strings involved by converting to lowercase (&lt;code&gt;lc()&lt;/code&gt;) before the comparison:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;lc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;lc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Finally, &lt;code&gt;$a&lt;/code&gt; and &lt;code&gt;$b&lt;/code&gt; can be used as lookups to another data structure. Here is an example of sorting the keys of a hash according to the values these keys are pointing to:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;%h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;d&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&amp;#39;e&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;@sortedKeys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@sortedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;e, c, a, b, d
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The sorting behaviour can also be overidden by a named subroutine rather than an anonymous block of code (OK, 'anonymous subroutine' for the pedantics among you). This is useful for reusing the same comparison logic, and if you give reasonable names to your sorting subroutines, it can also lead to very readable code:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;backwards&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;qw( z g b aa c )&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backwards&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@sortedKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;z, g, c, b, aa
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Dissecting custom sort&lt;/h2&gt;

&lt;p&gt;Before we continue, we have to take a closer look at the mechanism of customising sort. The block of code that is used to compare the elements, is a Perl expression that is required to evaluate to -1, 0 or 1. This is very similar to how the &lt;code&gt;cmp&lt;/code&gt; and &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; operators work. According to the Perl manual:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Binary &quot;cmp&quot; returns -1, 0, or 1 depending on whether the left argument is stringwise less than, equal to, or greater than the right argument.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Binary &quot;&amp;lt;=&gt;&quot; returns -1, 0, or 1 depending on whether the left argument is numerically less than, equal to, or greater than the right argument.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This essentially means that &lt;code&gt;(10 &amp;lt;=&amp;gt; 2)&lt;/code&gt; evaluates to 1, &lt;code&gt;(4 &amp;lt;=&amp;gt; 4)&lt;/code&gt; evaluates to 0, and &lt;code&gt;(5 &amp;lt;=&amp;gt; 7)&lt;/code&gt; evaluates to -1. The same applies to strings.&lt;/p&gt;

&lt;p&gt;This inherent compatibility of sort and the &lt;code&gt;cmp&lt;/code&gt; and &lt;code&gt;&amp;lt;=&amp;gt;&lt;/code&gt; operators means that usually the code block that customises &lt;code&gt;sort&lt;/code&gt; is just one comparison using one of the two operators, but actually the block can be any Perl expression that evaluates to -1, 0 or 1.&lt;/p&gt;

&lt;p&gt;For example, suppose that we have a list where the elements are made up of a letter followed by a digit, and we would like to sort by digit, and in the cases where the digits are equal we would like to sort by the prefixing letter:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;qw( f2 b1 o9 a1 c2 g9 d8 )&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;         &lt;span class=&quot;nb&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt;         &lt;span class=&quot;nb&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;6&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theSortedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;a1, b1, c2, f2, d8, g9, o9
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In this example, the comparison logic is implemented in lines 3, 4 and 5. On line 3, the second characters (the numbers) of each element are extracted using the substr function, and they are compared numerically. If the two numbers are found to be different, line 3 and in fact the whole block of code evaluates to -1 or 1, and the comparison is complete. Because of the or (&lt;code&gt;||&lt;/code&gt;) operator on line 4, the comparison continues only if the two numbers are equal, in which case line 3 evaluates to 0. In this case, line 5 is evaluated, which extracts the first characters of the each of the two elements and proceeds to compare them alphanumerically. This example demostrates that any sorting logic can be implemented as long as the result of the comparison is returned as -1, 0 or 1.&lt;/p&gt;

&lt;h2&gt;Sorting an array of arrays&lt;/h2&gt;

&lt;p&gt;Suppose you have the following array or arrays:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;aa&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;ye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;hoho&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;aa&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;tq&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;aa&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Conceptually, this array is equivalent to the following table:&lt;/p&gt;

&lt;table style=&quot;width:15em&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; class=&quot;centered&quot;&gt;
&lt;tbody&gt;&lt;tr class=&quot;row1&quot;&gt;&lt;td&gt;aa&lt;/td&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row2&quot;&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;dd&lt;/td&gt;&lt;td&gt;ye&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row1&quot;&gt;&lt;td&gt;dd&lt;/td&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;hoho&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row2&quot;&gt;&lt;td&gt;dd&lt;/td&gt;&lt;td&gt;aa&lt;/td&gt;&lt;td&gt;tq&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row1&quot;&gt;&lt;td&gt;aa&lt;/td&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;a&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;p&gt;We would like to sort the array of arrays according to all the columns of the above table, giving priority to the first column, then looking at the second column and finally the third. This kind of sorting can be achieved with the following script:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#!/usr/bin/perl -w&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Data::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dumper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;      
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;aa&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;ye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;hoho&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;dd&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;aa&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;tq&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;aa&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;cc&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;      
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@sorted_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableSorter&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@$table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;  
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dumper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@sorted_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;  
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;tableSorter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;($$)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column1comparison&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$column1comparison&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt;         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column1comparison&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt;     
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column2comparison&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$column2comparison&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt;         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$column2comparison&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29&lt;/span&gt;  
&lt;span class=&quot;lineno&quot;&gt;30&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;On line 14 we sort using the &lt;code&gt;tableSorter&lt;/code&gt; subroutine which implements our comparison logic. Note that the prototype of this function has to be &lt;code&gt;$$&lt;/code&gt; (line 18). The two elements are passed to this subroutine by sort on line 19, and these are no others than &lt;code&gt;$a&lt;/code&gt; and &lt;code&gt;$b&lt;/code&gt;, the special variables we discussed before. In this particular case the elements are references to the rows of our table. The first comparison is performed on lines 21 to 24 and if the sub-elements from column 1, the subroutine proceeds to use columnn 2 and then column 3 for subsequent comparisons.&lt;/p&gt;

&lt;p&gt;The module &lt;code&gt;Data::Dumper&lt;/code&gt; is being used here (line 16) to produce a summary of the resulting sorted data structure, and it produces the following output:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$VAR1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;aa&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;cc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$VAR2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;aa&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;cc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$VAR3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;cc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;dd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;ye&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$VAR4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;dd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;aa&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;tq&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$VAR5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;dd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;cc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;&amp;#39;hoho&amp;#39;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Which is conceptually equivalent to the following correctly sorted table:&lt;/p&gt;

&lt;table style=&quot;width:15em&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; class=&quot;centered&quot;&gt;
&lt;tbody&gt;&lt;tr class=&quot;row1&quot;&gt;&lt;td&gt;aa&lt;/td&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;a&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row2&quot;&gt;&lt;td&gt;aa&lt;/td&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;b&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row1&quot;&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;dd&lt;/td&gt;&lt;td&gt;ye&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row2&quot;&gt;&lt;td&gt;dd&lt;/td&gt;&lt;td&gt;aa&lt;/td&gt;&lt;td&gt;tq&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;row1&quot;&gt;&lt;td&gt;dd&lt;/td&gt;&lt;td&gt;cc&lt;/td&gt;&lt;td&gt;hoho&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;p&gt;Now, let's see if we can express the same logic, using less and more concise code. Lines 21 to 31 of the above listing, can be summarised as:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;...and if would like to be extremely brief, we can skip the use of a named function altogether, and do everything on one line by replacing line 14:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@sorted_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tableSorter&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@$table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;...with:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;k&quot;&gt;my&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@sorted_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;cmp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@$table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Where is the return statement?&lt;/h2&gt;

&lt;p&gt;One final clarification about sorter subroutines: Why does the above &lt;code&gt;tableSorter&lt;/code&gt; subroutine need a &lt;code&gt;return&lt;/code&gt; statement, while the anonymous sorter block of code (also a subroutine) does not require a &lt;code&gt;return&lt;/code&gt;? They both must return a value, so why the different syntax?&lt;/p&gt;

&lt;p&gt;The syntax is in fact different, but it means exactly the same. There are two ways to return a value from a subroutine in Perl: you can either do it explicitly using a return statement, or, if there is no return statement, the value of the last statement of the subroutine is used as the return value. So the following subroutines are exactly equivalent:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;k&quot;&gt;sub &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;my&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The last statement of the second subroutine is &lt;code&gt;$a + $b&lt;/code&gt; and this is what is returned, irrespective of the presence of a return statement. The following sort statement uses a custom subroutine which returns the value of &lt;code&gt;$b &amp;lt;=&amp;gt; $a&lt;/code&gt;, since &lt;code&gt;$b &amp;lt;=&amp;gt; $a&lt;/code&gt; is the last (and only) statement of the anonymous subroutine:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The following statement is exactly equivalent (but longer):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;perl&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;@theList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;So the answer is that the syntax is different, but semantically the same: it makes no difference at all. We just tend to use the shorthand that omits the &lt;code&gt;return&lt;/code&gt; statement in the case of the anonymous sorter subroutine because it makes the sort line shorter and it fits the overall brevity. On the other hand, when you write full named subroutines, the most common way to return a value is by using the return statement.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As with almost every aspect of Perl, the &lt;code&gt;sort&lt;/code&gt; function can be used in various degrees of complexity. With &lt;code&gt;sort&lt;/code&gt; you can start small by using it in its most simple form, customise it a bit to suit your needs (for descending sorts etc), or go all the way to implement a sorting logic for more complex data structures.&lt;/p&gt;

&lt;p&gt;Some points to remember: Don't forget to &lt;strong&gt;do&lt;/strong&gt; something with the sorted list (e.g. store it somewhere), because sort itself does not affect the original list. Lists are sorted in the &lt;strong&gt;&quot;natural&quot; order of data&lt;/strong&gt;, unless this behaviour is overridden by you. Custom sorter subroutines &lt;strong&gt;have&lt;/strong&gt; to have the &lt;code&gt;$$&lt;/code&gt; prototype and they &lt;strong&gt;have&lt;/strong&gt; to return -1, 0 or 1.&lt;/p&gt;

&lt;p&gt;Good luck with sorting!&lt;/p&gt;
</content>
 </entry>
 

</feed>

