Regular Expressions: η «σκοτεινή μαγεία» του parsing.
Ακούγεται εντυπωσιακό, έτσι δεν είναι;
Στην πραγματικότητα, μερικές φορές θυμίζουν λιγότερο σκοτεινή μαγεία και περισσότερο ένα μυστηριώδες ξόρκι που λειτουργεί άψογα, μέχρι να εμφανιστεί ένα εντελώς συγκεκριμένο string και να τα χαλάσει όλα.
Εντάξει, ίσως υπερβάλλω λίγο. Ας σου πω όμως πώς κατέληξα σε αυτό το συμπέρασμα.
Η αρχή
Όπως ίσως γνωρίζεις ήδη, είμαι ο δημιουργός του StyleZero.
Το StyleZero διαθέτει τον δικό του parser, ο οποίος αρχικά είχε υλοποιηθεί με custom matching, χωρίς τη χρήση regular expressions.
Κάποια στιγμή διάβασα στο Facebook τη συμβουλή ενός έμπειρου developer, ο οποίος έλεγε ότι τα regex τού είχαν εξοικονομήσει πολλές ώρες δουλειάς.
Οπότε σκέφτηκα:
Γιατί όχι; Ας δούμε πώς θα πάει.
Η υλοποίηση
Το να γράψω ένα τεράστιο regular expression για ολόκληρο τον parser του StyleZero προφανώς δεν θα ήταν καλή ιδέα, οπότε χώρισα τη λογική σε επιμέρους μεταβλητές.
Το τελικό αποτέλεσμα δεν ήταν ακριβώς ευανάγνωστο, αλλά λειτουργούσε.
Χωρίς να πολυλογώ, κατάφερα να συγκεντρώσω σε μία μόνο συνάρτηση λογική που προηγουμένως ήταν μοιρασμένη σε αρκετά αρχεία.
Έδειχνε φανταστικό.
Όλα λειτουργούσαν άψογα, μέχρι που, κάποια στιγμή, σταμάτησαν.
Κλασικά πράγματα.
Τι συνέβη λοιπόν;
Ένας συνάδελφος που είχε ενθουσιαστεί με το StyleZero παρατήρησε ότι ορισμένα SVG έκαναν τον compiler να σταματά να λειτουργεί.
Δεν ήταν κάτι καταστροφικό, αφού είχε ήδη βρει ένα workaround. Παρ’ όλα αυτά, όταν κατάφερα να αναπαράγω το ίδιο πρόβλημα και σε άλλες περιπτώσεις, θέλησα να καταλάβω τι ακριβώς συνέβαινε.
Ύστερα από αρκετές δοκιμές και προσεκτική αφαίρεση τμημάτων από το template, ανακάλυψα ότι το StyleZero παρουσίαζε σφάλμα όταν συναντούσε μια αλφαριθμητική συμβολοσειρά μήκους 13 έως 16 χαρακτήρων.
Στην αρχή, μου φάνηκε αρκετά αστείο.
Από τη μία, ο parser μπορούσε να επεξεργαστεί τεράστια templates χωρίς κανένα πρόβλημα. Από την άλλη, ένα μικρό αρχείο που περιείχε κάτι σαν αυτό μπορούσε να τον σταματήσει:
234n905ct395945
Μετά από λίγη έρευνα, επιβεβαίωσα ότι το πρόβλημα προερχόταν από τα regular expressions.
Στη συνέχεια, αφιέρωσα τρεις ή τέσσερις αρκετά εντατικές ημέρες για να ξαναγράψω τον parser από την αρχή, ώστε να κυκλοφορήσει η έκδοση 9.2.1.
Τελικά, το πρόβλημα εξελίχθηκε σε μια καλή ευκαιρία βελτίωσης. Ο νέος parser είναι σημαντικά καλύτερος από τον προηγούμενο, τόσο ως προς τη δομή όσο και ως προς τη λειτουργία του.
Η συμβουλή μου
Τα regular expressions είναι ισχυρά εργαλεία, οπότε χρησιμοποίησέ τα, αλλά με προσοχή.
Είναι εξαιρετικά για μικρές και ξεκάθαρες εργασίες αναζήτησης ή αντιστοίχισης. Όταν όμως η λογική αρχίζει να γίνεται μεγάλη, περίπλοκη και δύσκολη στην εξήγηση, μια πιο συντηρήσιμη λύση μπορεί να σε γλιτώσει από μερικές ενδιαφέρουσες εκπλήξεις στο μέλλον.