Thanks for the comment.

Background is that we have a Database class, with generally (everyday) used SQL, and additional specialised sub-classes containing domain specific SQL - i.e. SQL specific to some rarely used nook. Database instantiation is handled a long way off, and $db is passed around (a little like a baby needing burping!). It has lots of stuff built in like which server to connect to for a database, a pool of connection handles, whether to allow remote connections, other bits of context etc.

Suggestion 1: is kind-of what we had - but we stored $db on $self during instantiation. The problem is that other processing is going on, and we want various contexts to be able to interchangably use $db / $special_db / $even_more_special_db as database objects. This would mean that we would have to implement all the methods of $db (or use autoload)

Suggestion 2: is not a runner, as the $db instance is created a long way off, and many moons before we get passed it. Also, this doesnt work when in one context we want colour_specials and in another we want to switch to garden_specials which are orthogonal. (ie Database specials are siblings - they cant/dont inherit from each other)

In the end, we dug up our Head First Design Patterns, and implemented a Decorator, using AUTOLOAD to despatch methods not found on the specialised class. We end up with this sort of thing:

# each Database::XXX class decorates the database # arg passed during instantiation, and any methods it # doesnt recognise are passed through to the decorated # database. # All done by making the Database:XXX classes inherit # from our Decorator class. # This code illustrates how this looks to users # of the database classes. my $db = Database->new( database => 'sussex' ); # add colour managment sprocs to database my $colour_db = Database::Colour->new( db => $db ); # Database::Colour knows hues hue (implements Rainbows) $colour_db->generateRainbow(); ... checkFlowerColours( db => $colour_db ); sub checkFlowerColours { my %arg = @_; # in this context, we need to add some # garden compost to the colour enabled database my $garden_db = Database::Garden->new( db => $arg{db} ); # sameColour is from Database::Colour if ( $garden_db->sameColour( $garden_db->getLawnColour(), 'brown' +) { # action is from Database::Garden # but hosePipeBan is from Database('sussex') $garden_db->waterPlants() unless $garden_db->hasHosePipeBan(); } }

Yeah, I know its a skanky example, but you get the Decorator like pattern idea. And the decorated $db just has special funcs for the scope of the block where it is created. I will post a cut-down Decorator class if anyone is interested?


In reply to Re^2: limiting the scope of bless by jaa
in thread limiting the scope of bless by jaa

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.