Wie normalisiert man Perl-Funktionsargumente für die Memo-Erstellung?

9

Wie kann ich eine Liste von Funktionsargumenten für einen String normalisieren, so dass zwei Argumentlisten in den gleichen String konvertiert werden, wenn sie effektiv äquivalent sind? Der Algorithmus sollte

  1. Vergleichen Sie eingebettete Hashes und Listen tief, anstatt durch Referenz
  2. Ignoriere die Hash-Tastenfolge
  3. Ignoriere den Unterschied zwischen 3 und "3"
  4. Erzeugen Sie eine relativ lesbare Zeichenfolge (nicht erforderlich, aber zum Debuggen nice-to-have)
  5. Führen Sie gut aus (XS über Perl bevorzugt)

Dies ist für Memo erforderlich, d. h. Zwischenspeichern des Ergebnisses der Funktion basierend auf ihren Argumenten.

Als Beispiel verwendet Memoize dies als Standardnormalizer, was die Nummern 1 und 3 nicht erfüllt:

%Vor%

Für eine Weile war mein Go-to-Normalizer

%Vor%

Allerdings behandelt es die Nummer 3 und die Zeichenfolge "3" anders darüber, wie der Skalar kürzlich verwendet wurde. Dies kann unterschiedliche Strings für im Wesentlichen äquivalente Argumentlisten erzeugen und den Memoisierungsvorteil reduzieren. (Die überwiegende Mehrheit der Funktionen wird nicht wissen oder kümmern, wenn sie 3 oder "3" erhalten.)

Aus Spaß habe ich eine Reihe von Serialisierern betrachtet, um zu sehen, welche zwischen 3 und "3" unterscheiden:

%Vor%

Von denen, die "gleich" melden, ist nicht sicher, wie man sie dazu bringt, die Reihenfolge der Hash-Schlüssel zu ignorieren.

Ich könnte die Argumentliste vorher durchgehen und alle Zahlen stringieren, aber das würde eine tiefe Kopie erfordern und würde # 5 verletzen.

Danke!

    
Jonathan Swartz 31.05.2012, 13:58
quelle

2 Antworten

2

So ziemlich jeder Serializer behandelt 3 und "3" anders, weil er nicht weiß, dass die Nummer und die Stringnummer für Sie gleich sind und diese Annahme für allgemeine Daten falsch ist. Sie müssen entweder die Eingabe oder die Ausgabe selbst normalisieren.

Für die Eingabe reicht ein Tiefenscan mit dem Ersetzen einer beliebigen Stringnummer mit dem Wert + 0 aus. Wenn Sie wissen, wo genau Zahlen eingegeben werden können, können Sie diesen Scan erheblich verkürzen.

Für die Ausgabe, einige einfache Zustandsmaschine oder sogar regexp (ja, ich weiß, dass die Ausgabe nicht regulär ist) wird höchstwahrscheinlich genug sein, um Zahlenstring nur Zahlen zu Zahlen zu strippen.

    
Oleg V. Volkov 31.05.2012, 14:12
quelle
2

YAML und seine Nachkommen sortieren Hash-Schlüssel standardmäßig. Setzen Sie $YAML::SortKeys = 2 , um bei tiefen Hashes sortiert zu werden.

Wenn Sie $YAML::Stringify auf einen echten Wert setzen und $YAML::XS::QuoteNumericStrings auf einen falschen Wert setzen, können Sie numerische Werte normalisieren. Die letzte Einstellung hebt einen String-Wert auf, der wie eine Zahl aussieht.

Sie können auch $Data::Dumper::Sortkeys = 1 verwenden, um die Ausgabeordnung mit Data::Dumper zu normalisieren. Wenn Sie $Data::Dumper::Useqq = 1 einstellen, werden Zeichenfolgen, die wie Zahlen aussehen, entfernt.

    
mob 31.05.2012 15:23
quelle

Tags und Links