Frage

Cross-Gepostet von PerlMonks:

Ich muss etwas grob, alten Code bei $ Arbeit aufzuräumen, und bevor ich versuchen, ein neues Modul machen ich würde gerne eine bestehende verwenden, wenn jemand etwas weiß angemessen.

Zur Laufzeit mir eine Datei bin Parsen, um zu bestimmen, was die Verarbeitung mich auf einer Reihe von Daten zu tun.

Wenn ich ein Modul schreiben wäre, würde ich versuchen, es zu tun allgemeiner (nicht-DBI-spezifisch), aber meine genauen Anwendungsfall ist dies:

Ich las eine SQL-Datei, die Abfrage zu ermitteln gegen die Datenbank auszuführen. Ich Parsen Kommentare an der Spitze und bestimmt, dass

     
  • Spalte A braucht eine s zu haben /// angewendet,
  •  
  • Spalte B Bedürfnisse umgewandelt werden wie ein Datum von bestimmtem Format zu suchen,
  •  
  • Spalte C wird eine Art tr ///.
  •  
  • Zusätzlich können die Dinge verkettet werden, so dass Spalte D Macht s ///, dann sagen, wenn es nicht mehr als 1 oder 2 ist, setzen Sie sich auf 3.

Also, wenn aus dem db holt das Programm gilt, die verschiedenen (möglicherweise gestapelt) Transformationen, bevor die Daten zurück.

Derzeit ist der Code eine disgustingly große und schwierige Reihe von if-Klauseln scheußlich schwer verarbeiten Arrays von Anweisungen zu lesen oder zu erhalten.

Also, was ich mir vor, vielleicht ein Objekt, das diese Zeilen wird analysiert (Belichten und zusätzlich eine funktionelle Schnittstelle), stapelt die Liste der Prozessoren bis zu bewerben, dann in der Lage sein, es auf einem bestandenes Stück von Daten auszuführen.

Optional könnte es eine Name / Kategorie Option sein, so dass ein Objekt dynamisch Prozessoren stapeln verwendet werden könnte, nur für die angegebenen Namen / Kategorie / Spalte.

Ein traditionell konstruiertes Beispiel:

$obj = $module->new();  
$obj->parse("-- greeting:gsub: /hi/hello"); # don't say "hi"  
$obj->parse("-- numbers:gsub: /\D//"); # digits only  
$obj->parse("-- numbers:exchange: 1,2,3 one,two,three"); # then spell out the numbers  
$obj->parse("-- when:date: %Y-%m-%d 08:00:00"); # format like a date, force to 8am  
$obj->stack(action => 'gsub', name => 'when', format => '/1995/1996/'); # my company does not recognize the year 1995.  

$cleaned = $obj->apply({greeting => "good morning", numbers => "t2", when => "2010116"});  

Jeder Prozessor (gsub, Datum, exchange) würde ein separates Unterprogramm sein. Plugins können definiert werden, mehr mit Namen hinzuzufügen.

$obj->define("chew", \&CookieMonster::chew);  
$obj->parse("column:chew: 3x"); # chew the column 3 times  

So ist die offensichtliche erste Frage ist, weiß jemand von einem Modul gibt, die ich verwenden könnte? Das einzige, was bisher [mod: // Hash :: Trans] finden Ich war in der Lage, aber da ich würde bestimmen, welche Verarbeitung zur Laufzeit dynamisch zu tun Ich würde immer am Ende mit der "Komplex" Option und ich würde immer noch den Parser / Stapler zu bauen.

Ist jemand Kenntnis von ähnlichen Modulen oder sogar ein leicht übergeordneten Modul, dass ich möchte vielleicht / Wrap nutzen?

Wenn es für die Öffentlichkeit nichts generic aus ist (sicher ist mein nicht die einzige in der darkpan), hat jemand einen Rat für Dinge im Auge oder Schnittstelle Vorschläge zu halten oder auch andere mögliche Verwendungen neben munging die Rückkehr von Daten von DBI, Text :: CSV, etc.?

Wenn ich ein neues Modul am Ende zu schreiben, hat jemand Namespace Vorschläge? Ich denke, etwas unter Data :: ist wahrscheinlich angemessen ... das Wort „pluggable“ hält in den Sinn kommen, weil mein Anwendungsfall mich von PAM erinnert, aber ich habe wirklich keine gute Ideen ...

     
  • Data :: Processor :: Steckbare?
  •  
  • Data :: Mungen :: Konfigurierbare?
  •  
  • I :: Chew :: Daten?
War es hilfreich?

Lösung 3

Danke an alle für ihre Gedanken.

Die kurze Version: Nach dem Versuch, einige bestehende Module ich meine eigene endete anzupassen up abstrahiert: Sub :: Kette. Es braucht etwas Arbeit, aber das tut, was ich brauche so weit.

Die lange Version: (Ein Auszug aus dem POD)

= head1 RATIONALE

Dieses Modul begann als Data :: Trans :: Named, eine benannte Wrapper (wie Sub :: Kette :: Named) um Data :: Transformation (und speziell Data :: Trans :: Map).

Wie wurde das Modul fast fertig Ich erkannte ich sehr wenig wurde mit Data Transformation :: (und deren Dokumentation vorgeschlagen, dass Ich würde wahrscheinlich nicht will, die nur einen Teil verwenden, dass ich mich verwenden). Ich fand auch, dass der Ausgang war nicht immer das, was ich erwartet hatte. Ich entschied, dass es sinnvoll nach dem wahrscheinlichen Ziel schien Transformation von Data ::, und dieses Modul einfach erforderlich, anders sein.

Also habe ich versucht, mehr abstrakt zu denken und erkannte, dass das Wesen des Moduls wurde nicht gebunden Datentransformation, sondern lediglich die Folge von einfachen Subroutinenaufrufe.

ich dann gefunden und Sub angesehen :: Pipeline aber benötigt, um das gleiche verwenden benannte Unterprogramm mit verschiedenen Argumenten in einer einzigen Kette, so ist es einfacher schien mir mit dem Code-Stick hatte ich geschrieben und benennen Sie es einfach und abstrakt es ein bisschen weiter.

Ich sehe auch in Regel :: Motor der Entwicklung Anfang war zu der Zeit war ich auf der Suche. Jedoch, wie Data :: Transform, schien es komplizierter als das, was ich brauchte. Als ich diese Regel sah :: Motor wurde mit [die sehr guten] Moosen Ich beschloss, passieren, da ich auf einer Reihe von sehr alten Maschinen zu tun Arbeit mit alten distros und alten perls und gezwungen Ressourcen. Wieder ist es nur schien, als viel mehr zu sein, was ich gesucht hatte.

= cut

Wie für die "Parse" Methode in meiner ursprünglichen Idee / example, Ich habe nicht gefunden, was notwendig zu sein, und ist derzeit mit Syntax wie

$chain->append($sub, \@arguments, \%options)

Andere Tipps

Zuerst würde ich an Ort versuchen, so viel von der Formatierung wie möglich in den SQL-Abfragen, wenn möglich. Dinge wie das Datumsformat usw. auf jeden Fall in SQL behandelt werden sollen.

Out Spitze von meinem Kopf ein Modul die ich kenne und die für Ihre Zwecke verwendet werden könnte, ist Data :: FormValidator . Obwohl sich vor allem an die Validierung CGI-Parameter richtet, hat es die Funktionen, die Sie benötigen: Sie definiert sind, können Filter und Einschränkungen und Ketten sie auf verschiedene Weise. Das bedeutet nicht, gibt es keine andere Module für Sie Zweck, ich weiß es einfach nicht.

Oder Sie können etwas tun, was Sie schon angedeutet. Sie könnten eine Art Kommandoklassen und ketten sie an den verschiedenen Dateneingänge definieren. Ich würde tun, etwas in diese Richtung:

package MyDataProcessor;

use Moose;
has 'Transformations' => (
    traits => ['Array'],
    is => 'rw',
    isa => 'ArrayRef[MyTransformer]',
    handles => {
        add_transformer => 'push',
    }
);

has 'input' => (is => 'rw', isa => 'Str');

sub apply_transforms {  }


package MyRegexTransformer;

use Moose;

extends 'MyTransformer';

has 'Regex' => (is => 'rw', isa => 'Str');
has 'Replacement' => (is => 'rw', isa => 'Str');

sub transform {  }

# some other transformers
#

# somewhere else
#
#

my $processor = MyDataProcessor->new(input => 'Hello transform me');

my $tr = MyRegexTransformer->new(Regex => 'Hello', Replacement => 'Hi');

$processor->add_transformer($tr);

#...

$processor->apply_transforms;

Ich bin keine Kenntnis von Datentransformation CPAN-Module, also musste ich habe meine eigenen für Arbeit rollen. Es wurde deutlich kompliziert mehr als das, aber unter einem ähnlichen Prinzip betrieben wird; es war im Grunde eine Implementierung des armen Mannes von Informatica-Stil ETL sans die Phantasie GUI ... war die Konfiguration Perl-Hashes (Perl statt XML, da es mir erlaubt, bestimmte komplexe Regeln als Unterprogramm Referenzen zu implementieren).

Was Namespace, ich würde gehen für Data::Transform::*

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top