Also es hat nichts mit hebeln zu tun. Ich kann Ihren Bericht in Ruby 2.2.2 in Ruby-Code reproduzieren, der überhaupt keinen Hasch auslöst.
Also warum zum Teufel ist Date.parse bereit, "23 Hunde" zu parsen und sich etwas einfallen zu lassen? Ich habe keine Ahnung. Ich würde sagen, es ist eine Eigenheit oder sogar ein Fehler in Date's Parsing; es versucht, alle möglichen Dinge zu analysieren, aber dies führt zu einigen seltsamen Randfällen.
Verwenden Sie Date#strptime für eine vorhersehbare Analyse von Datumsangaben in bekannten festen Formaten. Verwenden Sie das chronic Juwel für komplexere Analyse von Daten natürlicher Sprache in unvorhersehbaren Formaten.
Persönlich verwende ich nie gerade Date.parse
, weil es irgendwie unberechenbar ist, stattdessen eine dieser beiden Methoden verwenden. (Oder spezifische Format-Parsing-Methoden wie Date.iso8601
).
Ich habe versucht, den MRI-Code für Date.parse
zu betrachten, weil ich neugierig war, wenn ich herausfinden könnte, was es tat. Aber schnell ging ich in C-Code verloren Ich war nicht kompetent zu verstehen oder zu folgen, und musste aufgeben.
Interessanterweise reproduziert dies auch in JRuby 1.7.10 (ich habe jruby 9x noch nicht installiert). "23 Hunde" parsieren zur selben Sache, "3 Hunde" wirft auf. Hm, vielleicht ist der JRuby-Java-Code für einige von uns verständlicher als der C-Code von MRI. Aber ich hatte noch keine Zeit zu versuchen, durchzuarbeiten, was Date # in JRuby tut. Das Fleisch davon vielleicht beginnt here, obwohl ich nicht den richtigen Ort für die aktuelle Version Implementierung gefunden haben könnte. Sie können sehen, dass es versucht, das Datum nach einer Reihe von verschiedenen Formaten in der Folge zu analysieren, wobei es anhält, wenn es nach einem bestimmten Format erfolgreich analysiert wird. Wir können erraten, dass es ein seltsames Format in dieser Liste gibt, das erfolgreich "23 Hunde", aber nicht "3 Hunde" parst. Es ist wahrscheinlich kein Osterei oder absichtlich; Es ist nur ein seltsamer Nebeneffekt, wenn man versucht, ein Datum zu parsen, indem man nur versucht zu erraten, in welchem Format es ist, und verschiedene Formate nacheinander ausprobiert, kein sehr ausgefeilter Algorithmus.
Update Okay, zumindest in der jruby Code an die ich suchte (die nicht die aktuelle Implementierung sein könnte, ist aber einige Implementierung)
Schließlich, nach anderen potentiellen Parsen versuchen, die fehlschlagen, es versucht Date._parse_ddd
- für beide Eingänge.
Date._parse_ddd("23 dogs", e)
kehrt true
und füllt das Datum :: Parse :: Tasche mit einem mday
Komponente, aber Date._parse_ddd("3 dogs", e)
false zurück und füllt nicht den Bag
. Alles andere folgt von hier.
Wenn wir uns die Date._parse_ddd Implementierung ansehen ... gibt es einige Monster Regexes und seltsame Logik. Wahrscheinlich aus der MRT kopiert, um mit der MRT konsistent zu sein, oder anderweitig mit dem MRT-Verhalten konsistent gemacht zu werden.
Ich habe keine Lust, weiter zu debuggen. Du kannst wenn du willst. Die JRuby-Implementierung wird, wie Sie sehen können, tatsächlich in Ruby geschrieben, nicht einmal in Java.
Sie oder ich oder jemand könnte versuchen, weiter zu debuggen (vielleicht sogar mit einem interaktiven Debugger auf JRuby stdlib Implementierung) genau, um herauszufinden, was los ist. Aber ich bin zuversichtlich, dass die Antwort nur im Grunde ist "es ist ein seltsamer Nebeneffekt von Date.parse nicht wirklich zu wissen, welches Format es Eingabe ist, aber nur eine Menge Dinge zu versuchen, mit einem nicht sehr ausgefeilten Algorithmus, manchmal seltsame Dinge passieren"
mehr Update: Beachten Sie, dass Date.parse("03 dogs")
analysiert statt zu erhöhen. Also zwei Zahlen, die es entscheidet, sind analysierbar, eine nicht. Aber natürlich funktioniert Date.parse("3 May")
gut. Es ist nicht so, dass Date.parse
zweistellige Daten benötigt, es ist nur, dass es eine ganze Reihe von verschiedenen Arten der Analyse versucht, und ein wirklich gutes Datum wird korrekt erfasst, aber ein falsches Datum könnte von einer der Möglichkeiten erwischt werden, die es schien gut genug, aber in diesem Fall war es falsch.
mehr Gedanken So ist es nicht beabsichtigt, dass es so parst. Es ist ein Nebenprodukt heuristischer Regeln, die dazu gedacht sind, andere Daten zu erfassen. Da der Code nicht kommentiert ist, können wir nicht genau sagen, welche Datentypen welche Teile fangen sollen. Es ist eine Art Haufen zusammengewürfelter Sachen, um Daten in einer Vielzahl von Formaten, einschließlich internationaler Formate, zu finden.
Sie können sich die Tests ansehen, um alle Arten von Daten zu sehen, die es erfassen soll. Oder Sie könnten versuchen, den Code durchzugehen, um genau zu verstehen, welche Zeilen zu dem Verhalten führen, das Sie sehen. Der Code ist verwirrend - besonders der C-Code in der MRT für die meisten von uns. Der reine Ruby-Code in JRuby ist für uns Rubinisten natürlich besser lesbar. Da es verwirrend und zeitraubend ist, mit wenig Nutzen durch den Code zu gehen (wen interessiert das?), Wirst du wahrscheinlich niemanden dazu bringen, dies für dich zu tun.
* Ist das nur ein Osterei in hebeln? * Ja, nur hacken würde dieses Ergebnis produzieren. Wenn Sie diesen Code in einem Ruby-Programm oder in irb ausführen würden, würde Date.parse() Folgendes erzeugen: "Hello world" für diese Daten. Was bekommen Sie für 'Date.parse ('23')' und 'Date.parse ('3')'? – 7stud
Eigentlich sollte in beiden Fällen 'NameError: nicht initialisiertes konstantes Datum' auftreten. –
@ 7stud Ich weiß nicht, ich habe nicht Pry installiert. Wenn nur pry dieses Ergebnis liefert, ist das so, weil es so hart codiert war, oder weil pry einen anderen Date-Parser hat? Und warum gibt es dieses Ergebnis? – Nzall