Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
Keep It Simple, Stupid
 
PerlMonks  

Re^3: Altering the inheritance path of an object

by tobyink (Abbot)
on Sep 28, 2012 at 13:33 UTC ( #996219=note: print w/ replies, xml ) Need Help??


in reply to Re^2: Altering the inheritance path of an object
in thread Altering the inheritance path of an object

A project I'm working on now is a system for data transformation pipelines. Kind of like a makefile for data. So your pipeline might be something like:

  • Output the following tabular data as Excel:
    • Run the following query on the following database, resulting in tabular data.
      • SELECT person.name, ... FROM ...
      • Create a temporary database with these tables in it:
        • Create a table named "person" and load it with tabular data:
          • Parse this data as CSV:
            • Download data from http://example.com/people.csv
        • Create a table named "companies" and load it with tabular data:
          • Parse this data as tab-delimited data:
            • Download data from http://example.com/client-companies.tab

So you'd load up the pipeline, and tell the pipeline that you want the Excel file. And it thinks: OK, so I need to query this database, but first I need to build the database, how do I do that... I need to create it and load these tables... how do I do that... etc. You get the picture.

And in fact, some details of the pipeline are inferred during processing. We often don't want to hard-code file formats like CSV into the pipeline, but instead infer them from HTTP content-type headers and so forth.

It's still at a fairly early stage, but it's progressing quite nicely, and Moose roles are an important part of the implementation.

The reason being that at many stages in the process you need mix-and-match transformations. You need an object which accepts CSV and outputs Excel, or accepts tab-delimited data and outputs Excel, or accepts CSV and outputs an SQL table, or accepts an SQL table and outputs an HTML table.

OK, so each of these could be a class, but it's far easier to do as a role. When you come to a stage in processing, you instantiate a very generic object (which just has a few debugging methods, a unique identifier string, a link back to the pipeline object, etc) and compose it with the roles it needs to be able to handle (read CSV, write Excel).

The technique which you showed in your example is to make a subclass of Math::BigInt, and stuff the new methods into that. It's worth noting that actually, this is exactly how Moose role composition works internally - it creates a new class for you, and reblesses the object into that class. But it's all done on the fly at run-time, so you don't need to create modules for each class, choose names for them, etc. All that is abstracted away.

perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'


Comment on Re^3: Altering the inheritance path of an object
Download Code
Re^4: Altering the inheritance path of an object
by remiah (Hermit) on Sep 29, 2012 at 05:38 UTC

    update: my ascii drawing corrupt with threaded view. please have a look from single article view.

    Thanks for reply. This is too interesting for me.

    I used extends here, not with, like you always do. Roles, mixins are new to me.
    I guess this picture vaguely like this.

    
                     request from client
                 +------------------------->            pipeline
                            +------------------------------------------------------------------+
                            |                                                                  |
                            |                                                                  |
                            |                            r                                     |
                            |                    +-------------+                               |
                            |        +-----------+-+           v            +----+             |
                            |        |  master db  |        +--+--+              |             |
                            |        +-------------++--+    | csv |+--+          v             |
                            |                     r|  r|    +-----+   |       r r  r           |
                            |        +-------------|---|---------+    |r      r r  r r         |
                            |        |  tempral db |   |         |    |          +             |
        client              |        |             v   v         <----+          v             |
                            |        |         person    company |             generic object  |
                            |        +-------------+----+--+---+-+             with            |
                            |     r  +-------------|----|--|---|--+            various         |
                            |    +-----+ csv  <----+r   |  |   |  |            combination     |
                            |    |r  |                  |r |r  |r |            of roles        |
                            |    +-----> tab delimited <+  |   |  |              +             |
                            |    |r  |                     |   |  |              |             |
                            |    +-----> html     <--------+   |  |              |             |
                            |    |r  |                         |  |              |             |
                            |    +-----> excel    <------------+  |          <---+             |
                            |        +----------------------------+                            |
                  <-------+ |                                                                  |
                            |                                                                  |
    
    So, your generic object should know the dependencies of roles to use, plugging them , create the output. Dependencies varies from case by case, you have to use roles dynamically, with apply_all_roles.

    From client, it will just look like google api, tell the pipe line parameters needed with HTML header, or sending XML.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://996219]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2014-04-20 07:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls