Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Personally, I've settled on having one top-level module that looks at what is available (resp. what the programmer specifies), and a set of modules below that, which are the implementations for each "real" module:

package Future::HTTP; use strict; use Filter::signatures; no warnings 'experimental::signatures'; use feature 'signatures'; our $VERSION = '0.12'; our @loops; push @loops, ( ['IO/' => 'Future::HTTP::NetAsync' ], ['Mojo/' => 'Future::HTTP::Mojo' ], ['' => 'Future::HTTP::AnyEvent'], ['' => 'Future::HTTP::AnyEvent'], # POE support would be nice # LWP::UserAgent support would be nice # A threaded backend would also be nice but likely brings in other # interesting problems. How will we load this? We have two prerequ +isites # now, and HTTP::Tiny... #['' => 'Future::HTTP::Tiny::threaded' ], ['HTTP/Tiny/' => 'Future::HTTP::Tiny::Paranoid'], # The fallback, will always catch due to loading Future::HTTP ['Future/' => 'Future::HTTP::Tiny'], ); our $implementation; sub new($factoryclass, @args) { $implementation ||= $factoryclass->best_implementation(); # return a new instance $implementation->new(@args); } sub best_implementation( $class, @candidates ) { if(! @candidates) { @candidates = @loops; }; # Find the currently running/loaded event loop(s) #use Data::Dumper; #warn Dumper \%INC; #warn Dumper \@candidates; my @applicable_implementations = map { $_->[1] } grep { $INC{$_->[0]} } @candidates; # Check which one we can load: for my $impl (@applicable_implementations) { if( eval "require $impl; 1" ) { return $impl; }; }; };

This is likely overkill when the real meat is a subroutine of three or four lines and mostly parameter swapping, but I find the above approach easier, since each module can be conveniently tested.

Otherwise, I'll likely do the above except that best_implementation returns a reference to a subroutine:

sub do_imagemagick { require Image::Magick; Image::Magick->import(...); # ... } sub do_imager { require Imager; Imager->import(...); # ... }

In reply to Re: Best practice for a module which can use one of multiple image modules by Corion
in thread Best practice for a module which can use one of multiple image modules by Cody Fendant

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (3)
    As of 2020-09-23 22:36 GMT
    Find Nodes?
      Voting Booth?
      If at first I donít succeed, I Ö

      Results (132 votes). Check out past polls.