<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Diab Jerius</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/diab_jerius/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/diab_jerius/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/diab_jerius//956</id>
    <updated>2013-04-01T19:21:30Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>Perl and Perl Module Administration in the Modern Era</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/diab_jerius/2013/04/perl-and-perl-module-administration-in-the-modern-era.html" />
    <id>tag:blogs.perl.org,2013:/users/diab_jerius//956.4488</id>

    <published>2013-04-01T18:03:04Z</published>
    <updated>2013-04-01T19:21:30Z</updated>

    <summary>I recently gave a talk on perlbrew, cpanminus, and local::lib at $work. I&apos;ve uploaded the talk to Speaker Deck...</summary>
    <author>
        <name>Diab Jerius</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/diab_jerius/">
        <![CDATA[<p>I recently gave a talk on <a href="https://metacpan.org/module/perlbrew"><code>perlbrew</code></a>, <a href="https://metacpan.org/module/App::cpanminus"><code>cpanminus</code></a>,
and <a href="https://metacpan.org/module/local::lib"><code>local::lib</code></a> at $work.  I've uploaded the talk to <a href="https://speakerdeck.com/djerius/perl-and-perl-module-administration-in-the-modern-era">Speaker Deck</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>Building pluggable backends with Moo</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/diab_jerius/2013/02/exploring-pluggable-backends-in-moo.html" />
    <id>tag:blogs.perl.org,2013:/users/diab_jerius//956.4332</id>

    <published>2013-02-15T19:25:21Z</published>
    <updated>2013-02-17T21:55:23Z</updated>

    <summary>I&apos;ve been working through the design and implementation (using Moo) of a module (IPC::PrettyPipe) which implements some backend functionality via plugins. The nature of the module isn&apos;t that important; suffice it to say that there&apos;s a rendering backend and an...</summary>
    <author>
        <name>Diab Jerius</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/diab_jerius/">
        <![CDATA[<p>I've been working through the design and implementation (using
<a href="https://metacpan.org/module/Moo">Moo</a>) of a module (IPC::PrettyPipe)
which implements some backend functionality via plugins.  The
nature of the module isn't that important; suffice it to say that
there's a rendering backend and an execution backend.</p>

<p>I've previously implemented pluggable backends using
<a href="https://metacpan.org/module/Module::Pluggable">Module::Pluggable</a> and
kin, but since I'm using Moo for this module I thought I'd investigate
how its capabilities enabled (or constrained) pluggability.</p>
]]>
        <![CDATA[<p>(A point of note: Since in Moo class construction is done after the
compilation stage, technically one could do all sorts of sly things,
but I'd like to avoid too much sausage making.  When I write
"runtime", I mean after classes have been constructed.)</p>

<p>The main guiding principles for this module are</p>

<ul>
<li><p><em>Ease of use</em>: I'd like this to be accessible to the casual
user. There shouldn't be a lot of setup or boilerplate code.  The
user shouldn't need to know what's under the hood or that it's
implemented in Moo.  I'd like to avoid forcing the user to create
classes.</p></li>
<li><p><em>Loose coupling</em>: The rendering and execution functionality should
be easily customized.  For example, I'd like to be able to use a
variety of the execution pipeline modules on CPAN (such as
<a href="https://metacpan.org/module/IPC::Run">IPC::Run</a>,
<a href="https://metacpan.org/module/IPC::Run">IPC::Pipeline</a>,
<a href="https://metacpan.org/module/IPC::Exe">IPC::Exe</a>).  I'll have to
write simple adaptors for those, but the IPC::PrettyPipe interface
should make it easy to choose between them.</p></li>
</ul>

<p>More technical requirements are:</p>

<ul>
<li><p>Backends must be selectable at runtime.</p></li>
<li><p>The user should be able to choose a backend both during and after
the construction of an IPC::PrettyPipe object.</p></li>
<li><p>The user must be able to change a backend after one has been
selected.</p></li>
<li><p>There must be access to the backends to leverage any unique
functionality. While IPC::PrettyPipe will provide an interface to
common functionality, if a backend has special capabilities, it
should be possible to access them.</p></li>
</ul>

<p>What follows is a brief examination of the different approaches I
explored.</p>

<h2>Roles</h2>

<p>Roles seem like a natural approach as they transparently</p>

<ul>
<li>provide direct access to the IPC::PrettyPipe object by the backend
routines;</li>
<li>merge unique backend functionality into the object;</li>
</ul>

<p>For example, in addition to the <code>run</code> method, IPC::Run provides the
<code>start</code>, <code>pump</code>, and <code>finish</code> methods for interacting with the
pipeline while it is running.  The adaptor for IPC::Run could compose
those methods into the derived class.  If there are any extra
attributes used to customize the backend's behavior, these are
composed in as well.</p>

<p>Roles are typically applied during class construction, but they can
also be applied dynamically at runtime.  Once a role is composed into
a class or object, it can't be changed, so it's not possible to meet
the requirement to change a backend.  It's still interesting to see
how they impact the implementation, as that behavior is often not
required.</p>

<h3>"Static" Composition</h3>

<p>Static composition forces selection of the backends during class
construction, so it doesn't meet the runtime selection criteria.  It
does however provide a baseline to compare against for implementation
and interface complexity.</p>

<p>Here, IPC::PrettyPipe is used as a base class and the render and
execution functionality are composed into the derived class:</p>

<pre><code>package MyPipe;
use Moo;
extends 'IPC::PrettyPipe';

# add the renderer
with 'IPC::PrettyPipe::Render::Template::Tiny';

# add the execution backend
with 'IPC::PrettyPipe::Execute::IPC::Run';
</code></pre>

<h3>Dynamic Class Composition</h3>

<p><a href="https://metacpan.org/module/Moo::Role">Moo::Role</a> (via
<a href="https://metacpan.org/module/Role::Tiny">Role::Tiny</a>) provides the
ability to dynamically create composed classes:</p>

<pre><code>use Moo::Role ();

my $class = Moo::Role-&gt;create_class_with_roles( 'IPC::PrettyPipe',
    'IPC::PrettyPipe::Render::Template::Tiny',
    'IPC::PrettyPipe::Execute::IPC::Run' );
</code></pre>

<p>thus allowing runtime selection of the backends.  Without some
interface sugar this is too complex of an API to expose.  It's
just as easy to compose into an object and provide a natural
interface to it, which is what the next section discusses.</p>

<h3>Dynamic Object Composition</h3>

<p>Role::Tiny allows one to compose a role into an existing object. This
has the same drawback as dynamic class composition, but the benefit is
that it's easy to implement selection of roles via methods, leading to
a more traditional API:</p>

<pre><code>my $pipe = IPC::PrettyPipe-&gt;new;
$pipe-&gt;renderer( 'Template::Tiny' );
$pipe-&gt;executor( 'IPC::Run' );
</code></pre>

<p>This is implemented in the base class as:</p>

<pre><code>use Moo::Role ();
use Module::Path qw[ module_path ];
use Module::Runtime qw[ compose_module_name ];

sub renderer { $_[0]-&gt;_backend_compose( Render =&gt; $_[1] }
sub executor { $_[0]-&gt;_backend_compose( Execute =&gt; $_[1] }

# generic dynamic backend composition
sub _backend_compose {

    my ( $self, $type, $req ) = @_;

    my $module = compose_module_name( "IPC::PrettyPipe::$type", $req );

    croak( "unknown $type ($req =&gt; $module)\n" )
      unless defined module_path( $module );

    Moo::Role-&gt;apply_roles_to_object( $self, $module );

    return;
}
</code></pre>

<p>For the sake of clarity the above implementation doesn't allow
specifying backends during object construction; here's the code
which provides that functionality:</p>

<pre><code>has _executor =&gt; (
    is =&gt; 'rwp',
    predicate =&gt; 1,
    init_arg =&gt; 'executor',
    trigger =&gt; sub { $_[0]-&gt;_backend_compose( Execute =&gt; $_[1] },
);

sub executor { $_[0]-&gt;_set__executor( $_[1] )
               if defined $_[1] &amp;&amp; ! $_[0]-&gt;_has_executor }
</code></pre>

<p>I'm using the trigger to ensure that composition is localized to a
single spot in the code.  (The double underscore in <code>_set__executor</code>
is because Moo retains the leading underscore in <code>_executor</code> when it
creates the private writer.)</p>

<p>So now, this is possible:</p>

<pre><code>my $pipe = IPC::PrettyPipe-&gt;new( renderer =&gt; 'Template::Tiny',
                                 executor  =&gt; 'IPC::Run'
                               );
</code></pre>

<p>There's still no means of <em>changing</em> the backends, but the
implementation and exposed interface are quite clean.</p>

<h2>Method Delegation</h2>

<p>Moving the backends into their own objects provides some
flexibility by allowing them to be changed on the fly, but makes
exposing any unique functionality more complex.</p>

<p>A complete separation of backend objects from the pipeline object
might look like this:</p>

<pre><code>my $pipe = IPC::PrettyPipe-&gt;new;

my $renderer = IPC::PrettyPipe::Render::Template::Tiny-&gt;new();
my $executor = IPC::PrettyPipe::Execute::IPC::Run-&gt;new();

$renderer-&gt;render( $pipe );
</code></pre>

<p>That's horrible, but very flexible.  A cleaner approach would be for
the IPC::PrettyPipe object to contain the backend objects, and use
method delegatation to invoke the appropriate methods on the contained
backend objects.</p>

<p>IPC::PrettyPipe would provide methods to specify the backends, just
as in the dynamic object composition pattern:</p>

<pre><code>my $pipe = IPC::PrettyPipe-&gt;new;

my $renderer =
    IPC::PrettyPipe::Render::Template::Tiny-&gt;new( pipe =&gt; $pipe );
my $executor =
    IPC::PrettyPipe::Execute::IPC::Run-&gt;new( pipe =&gt; $pipe );

$pipe-&gt;renderer( $renderer );
$pipe-&gt;executor( $executor );
</code></pre>

<p>Here the IPC::PrettyPipe object is passed to the backend constructors;
this is necessary if native Moo method delegation is used (more on
that later).</p>

<p>To cut down on the boilerplate, the interface should also allow
specification of just the class:</p>

<pre><code>my $pipe = IPC::PrettyPipe-&gt;new;

$pipe-&gt;renderer( 'Template::Tiny' );
$pipe-&gt;executor( 'IPC::Run' );
</code></pre>

<p>It's also a requirement that the backends be specifiable during
 object construction:</p>

<pre><code>my $pipe = IPC::PrettyPipe-&gt;new( renderer =&gt; 'Template::Tiny',
                                 executor =&gt; 'IPC::Run' );
</code></pre>

<p>Finally, the backend object (however it's created) must be directly
retrievable so that any unique functionality is exposed:</p>

<pre><code>my $renderer = $pipe-&gt;renderer;
</code></pre>

<p>The combination of the dual nature of the backend specifications and
the requirement for specification during and after object construction
added more complexity than I'd initially expected, as will be seen
in the following discussion.</p>

<h3>Attribute Coercion</h3>

<p>Attribute coercion seems the perfect solution to handle the dual
nature of the backend specification. The coercion code is run whenever
the attribute is set.</p>

<pre><code>use Safe::Isa;

has executor =&gt; (
    is =&gt; 'rw',

    coerce =&gt; sub {
        # create the object if the attribute can't run()
        $_[0]-&gt;$_can( 'run' )
             ? $_[0]
             : _backend_factory( Execute =&gt; $_[0] ) },

    handles =&gt; [ 'run' ],
    lazy =&gt; 1,
    default =&gt; sub { 'IPC::Run' }
);
</code></pre>

<p>where <code>_backend_factory</code> is a generic factory for backends (see the Appendix).</p>

<p>Unfortunately, this code won't work.  Backend objects constructed by
the coercion routine know <em>nothing</em> about the pipeline object:</p>

<ol>
<li>delegated methods aren't passed <em>any</em> extra parameters to the
delegated object;</li>
<li>The coercion coderef isn't passed a handle to the object, so can't
pass it to the backend constructor.</li>
</ol>

<p>I could explicitly create delegating methods to work around the first
behavior:</p>

<pre><code>sub run { $_[0]-&gt;executor-&gt;run( $_[0] ) }
</code></pre>

<p>but that destroys the elegance of the built in method delegation.</p>

<p>Additionally, it doesn't help with the situation where a backend
object needs access to the pipeline object during its construction.</p>

<h3>Triggers are a wonderful thing</h3>

<p>The mechanism which constructs the backend object must</p>

<ol>
<li>get a reference to the IPC::Pipeline object; and</li>
<li>get called whenever the attribute is changed</li>
</ol>

<p>That would seem to be a trigger.  The trigger would decide whether an
object needs to be constructed, and if so, would update the attribute
with the object.  <code>_backend_factory</code> is now a method which passes
along the <code>IPC::PrettyPipe</code> object to the backend object's
constructor:</p>

<pre><code>has executor =&gt; (
    is       =&gt; 'rw',
    trigger =&gt; sub {
                my ( $self, $val ) = @_;
                $self-&gt;executor( $self-&gt;_backend_factory( Execute =&gt; $val ) )
                    unless $val-&gt;$_can( 'run' );
    },
    handles =&gt; [ 'run' ],
    lazy =&gt; 1,
    default =&gt; sub { $_[0]-&gt;_backend_factory( Execute =&gt; 'IPC::Run' ) },
);
</code></pre>

<p>By their nature triggers are called whenever the attribute is set, so
if we set the attribute in a trigger we descend into infinite
recursion hell as the accessor calls the trigger which calls the
accessor which calls the trigger...</p>

<p>(Technically this particular example won't, as <code>_backend_factory</code> will
return an object which passes the <code>$_can('run')</code> test so that the next
call to the trigger will return without setting the attribute.  But it
is not necessarily a design pattern I'd generalize.)</p>

<p>There's still some code duplication:  with current Moo (1.000007)
setting an attribute value via its default subroutine does not invoke
a trigger, so the default for <code>executor</code> has to call
<code>_backend_factory</code>.  It'd be nicer if I could specify</p>

<pre><code>default =&gt; sub { 'IPC::Run' }
</code></pre>

<p>Note that the backend object is now created when the <code>executor</code>
attribute is read <em>or written</em>.  I'd prefer it to be only when
read, but this approach doesn't allow that.</p>

<h3>A Trigger with a proxied attribute</h3>

<p>Continuing in this vein, to avoid possible run-away recursion one
could make the <code>executor</code> attribute a proxy for a hidden attribute
which does the work:</p>

<pre><code>has executor =&gt; (
    is       =&gt; 'rw',
    trigger  =&gt; sub {
            my ( $self, $backend ) = @_;
            my $executor = $backend-&gt;$_can( 'run' )
                         ? $backend
                         : $self-&gt;_backend_factory( Execute =&gt; $backend );
            $self-&gt;_set__executor( $executor );
        },
);

has _executor =&gt; (
    is =&gt; 'rwp',
    init_arg =&gt; undef,
    handles =&gt; [ 'run' ],
    lazy =&gt; 1,
    default =&gt; sub { $_[0]-&gt;_backend_factory( Execute =&gt; 'IPC::Run' ) },
);
</code></pre>

<p>All internal code would use <code>_executor</code>.  This has the same
pseudo-lazy quality of object construction as the previous example,
and still has the duplicated calls to <code>_backend_factory</code>.  This is
safe from infinite recursion, but unfortunately it's now impossible to
guarantee retrieval of the actual backend object.</p>

<p>If the <code>executor</code> attribute is never set, the <code>_executor</code> attribute
will get a default value, but that isn't passed back to the <code>executor</code>
attribute.  And if <code>executor</code> was passed a module name, its accessor
returns that name, not the actual backend object generated by the
trigger.  The key here is that the value in <code>_executor</code> is always
correct.  We just need to retrieve it.</p>

<p>One way of doing this is to write a custom accessor routine which
knows to read from the  <code>_executor</code> attribute and write to the <code>executor</code>
attribute:</p>

<pre><code>has executor =&gt; (
    is       =&gt; 'rw',
    reader   =&gt; '_get_executor',
    writer   =&gt; '_set_executor',
    trigger  =&gt; sub {
            my ( $self, $backend ) = @_;
            my $executor = $backend-&gt;$_can( 'run' )
                         ? $backend
                         : $self-&gt;_backend_factory( Execute =&gt; $backend );
            $self-&gt;_set__executor( $executor );
        },
    default =&gt; sub { $_[0]-&gt;_backend_factory( Execute =&gt; 'IPC::Run' ) },
);

# doesn't work in Moo 1.000007
sub executor {
    my $self = shift;
    return   @_  ? $self-&gt;_set_executor( @_ )
                 : $self-&gt;_executor;
}

has _executor =&gt; (
    is =&gt; 'rwp',
    init_arg =&gt; undef,
    handles =&gt; [ 'run' ],
    lazy =&gt; 1,
    default =&gt; sub { $_[0]-&gt;_get_executor },
);
</code></pre>

<p>Unfortunately the above code doesn't actually work under current
(1.000007) Moo, as the custom <code>executor</code> accessor will be overwritten
by the standard one provided by Moo (because it is created at run time
while the custom one is created at compile time).  This is being
addressed by the Moo developers.</p>

<p>A workaround is possible: explicitly specify the phases during which
the attribute and custom accessor are created so that the custom one
is not overridden:</p>

<pre><code>BEGIN {
    has executor ...
}
INIT {
    no warnings 'redefine';
    sub executor{ ... }
}
</code></pre>

<p>This works, but it's kludgy.</p>

<p>There's a also possible future problem.  If (ever) Moo invokes
triggers upon default value creation, there's a possibility of
internal crosstalk when the <code>run</code> method is called if <code>executor</code> is
not explicitly set.  In that case the call stack looks like this:</p>

<pre><code>proxy run()
_executor.default
executor.default
executor.trigger
_set__executor
</code></pre>

<p><code>_executor</code>'s default value constructor eventually calls its
own setter.  This may not be a problem. Or it might.</p>

<h3>Two attributes are better than one, unless there are three</h3>

<p>The above approach shows that using two attributes provides the
separation required to circumvent possible infinite recursion.
However, exposing either of them directly to the user require excess
machinery to control their behavior.</p>

<p>In the next iteration both attributes are private. One attribute holds
the user's backend specification, the other holds the actual backend
object.  The object is created on-the-fly from the specification.
When the specification changes, it triggers the clearer on the
attribute holding the object, so that the next time that attribute is
accessed the backend object it is recreated from the specification.</p>

<p>To create the semblence of a single attribute the private
specification attribute is initialized via the <code>executor</code> keyword
to the constructor, and a custom <code>executor()</code> "accessor" was written to
dispatch to the appropriate attribute for reading or writing.</p>

<pre><code>has _executor_arg =&gt; (
    is       =&gt; 'rw',
    init_arg =&gt; 'executor',
    default  =&gt; sub { 'IPC::Run' },
    trigger  =&gt; sub { $_[0]-&gt;_clear_executor },
);

has _executor =&gt; (
    is      =&gt; 'rw',
    handles =&gt; ['run'],
    lazy    =&gt; 1,
    clearer =&gt; 1,
    default =&gt; sub {

        my $backend = $_[0]-&gt;_executor_arg;

        return $backend-&gt;$_can( 'run' )
               ? $backend
               : $_[0]-&gt;_backend_factory( Execute =&gt; $backend );
    },
);


sub executor {
    my $self = shift;

    $self-&gt;_executor_arg( @_ )
      if @_;

    return $self-&gt;_executor;
}
</code></pre>

<p>No duplicated code, no worries about tricky code paths.  Not as
concise as I'd have liked it.  The backend object is still built upon
reading or writing.</p>

<h3>Attribute Accessor Modification</h3>

<p>One final approach is based upon the realization that the attribute
doesn't need to be coerced immediately that it is set.  This can be
done using a single attribute by wrapping its accessor to perform
coercion at access time.</p>

<pre><code>has executor =&gt; (
    is      =&gt; 'rw',
    handles  =&gt; ['run'],
    lazy    =&gt; 1,
    default =&gt; sub { $_[0]-&gt;_backend_factory( Execute =&gt; 'IPC::Run' ) },
);

around 'executor' =&gt; sub {

    my ( $orig, $self ) = ( shift, shift );
    my $attr = $orig-&gt;( $self, @_ );
    unless ( $attr-&gt;$_can( 'run' ) ) {

        $attr = $orig-&gt;( $self,
                         $self-&gt;_backend_factory( Execute =&gt; $attr ) );
    }
    return $attr;

};
</code></pre>

<p>The attribute default sub still has to call <code>_backend_factory</code> because
the accessor is not invoked if the delegated <code>run</code> routine is called
and no attribute value was specified.</p>

<p>The drawback with this approach that you get hit with the overhead of
the coercion check with each retrieval of the attribute; with the
other approaches it was only when the attribute is set.</p>

<h2>Conclusion</h2>

<p>In the end I settled upon using the approach with two private
attributes and the custom accessor binding them.  I like the
simplicity of the trigger/single attribute approach, but I'm worried
about code maintenance and the subtlety of ensuring there's no
infinite recursion.</p>

<p>The implementations were more complex than I originally thought
necessary for what seems to me to be fairly simple requirements.</p>

<p>There are a few aspects of the Moo object model that drove things in
that direction.</p>

<ul>
<li><p>If the coercion routine had passed along the object, I think most of
the complexity would have disappeared.  While there's no guarantee
that the object will be in a useable state if the coercion routine is
invoked during object construction, the reference to the object is
still useful as an opaque handle.</p></li>
<li><p>If one could disable triggering within a trigger handler (much as in
a signal handler), that would have greatly weakened the argument for
attribute proxying.</p></li>
<li><p>attribute setting via the default method doesn't set off the trigger
handler.  There may be a reason behind this behavior (or it might
just have been overlooked).</p></li>
<li><p>Moo doesn't seem to use attribute accessors internally (for speed I
imagine), so modified or overridden ones don't always get called
when the attribute is accessed.</p></li>
</ul>

<p>If run-time flexibility weren't important, I think that role
composition wins hands down.</p>

<p>I'm intrigued by the possibility of abstracting the code so that one
could use either the rather more elegant role composition or method
delegation.</p>

<h2>Appendix</h2>

<p>For completeness, here's the final implementation of <code>_backend_factory</code>:</p>

<pre><code>use Module::Load qw[ load ];
use Module::Path qw[ module_path ];
use Module::Runtime qw[ compose_module_name ];

sub _backend_factory {

    my ( $self, $type, $req ) = ( shift, shift, shift );

    my $module = compose_module_name( "IPC::PrettyPipe::$type", $req );

    croak( "unknown $type ($req =&gt; $module)\n" )
      unless defined module_path( $module );

    load $module;

    return $module-&gt;new( pipe =&gt; $self, @_ );
}
</code></pre>
]]>
    </content>
</entry>

</feed>
