<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Perlblogs &#187; oop</title>
	<atom:link href="http://perlblogs.com/category/oop/feed/" rel="self" type="application/rss+xml" />
	<link>http://perlblogs.com</link>
	<description>Posts from selected Perl bloggers</description>
	<lastBuildDate>Mon, 06 Feb 2012 20:47:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>When You Lack Cheap and Easy Polymorphism</title>
		<link>http://www.modernperlbooks.com/mt/2011/05/when-you-lack-cheap-and-easy-polymorphism.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/05/when-you-lack-cheap-and-easy-polymorphism.html#comments</comments>
		<pubDate>Wed, 04 May 2011 17:42:36 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[languagedesign]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[Parrot]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[The quality and cost of your language's abstractions can affect the applicability of those abstractions. Consider Parrot and its intrinsic data structure, the PMC. The design of PMCs resembles Perl 5 SVs in a philosophical sense, if not a direct...]]></description>
			<content:encoded><![CDATA[
        <p>The quality and cost of your language's abstractions can affect the
applicability of those abstractions. Consider <a
href="http://www.parrot.org/">Parrot</a> and its intrinsic data structure, the
PMC. The design of PMCs resembles <a
href="http://perldoc.perl.org/perlguts.html#Working-with-SVs">Perl 5 SVs</a> in
a philosophical sense, if not a direct working relationship. The guiding design
principle is "A PMC should be able to support a basic set of core operations
common to all core PMCs".</p>

<p>Parrot's core PMCs have dozens of these operations, such as getting and
setting integer, numeric, and string values. They support a clone operation, an
invocation operation, an instantiation operation, and more. While some of these
operations make little sense (invoking an Integer PMC throws an exception for
obvious reasons), every PMC has to support them sufficiently that attempting to
perform that operation should not cause the VM to crash.</p>

<p>Parrot's core PMCs are big wads of C code. All of these operations in
Parrot's core PMCs are C functions gathered in a large table of function
pointers. Every PMC type has one of these tables. Adding a new core operation
to Parrot means adding a new function to every PMC table. Every new function
added to the PMC table thus adds to the memory and startup costs of Parrot
overall. Similarly, adding a new PMC type&mdash;even a specialization of an
existing type&mdash;increases the memory and startup costs of Parrot overall
because a new type needs an entirely new and distinct function pointer
table.</p>

<p>These are implementation details quite solveable with some clever
programming, but the most interesting point in my mind is how these
implementation details have influenced the development of Parrot and Parrot
languages. In particular, there's a subtle (and likely correct) belief in the
project that adding a new PMC is an expensive operation in terms of Parrot's
footprint <em>and</em> the management of its source code.</p>

<p>That's true to some extent, which is a shame, because Parrot's suitability
as a VM for interoperable languages comes in no small part from the flexibility
of the PMC system.</p>

<p>The cost of the belief in the heavy cost of new PMCs is that the core of
Parrot takes advantage of far less polymorphism than it should. Consider the
difference between a named function, an anonymous function, a method, a
closure, a continuation, an exception handler, a binding to a shared library
function, and a lazy thunk (perhaps a generator). You can invoke all of those
items. You can pass in zero or more arguments. They can each return zero or
more values. Yet they each perform very different mechanisms of control
flow.</p>

<p>An ideal Parrot design would have separate PMC types for each logical type.
A boring old named function which takes no parameters could avoid parameter
passing code altogether, while the binding to a shared library function likely
needs to marshall data to and from the appropriate ABI. A generator should be
fast and lightweight, while an exception handler may have to manipulate control
flow in interesting ways to resume an exception or at least resume at the
appropriate place in control flow based on which exceptions it can handle and
which it must decline.</p>

<p>Yet Parrot <em>doesn't</em> have multiple specialized PMC types representing  all (or even most) of the necessary variants of invokable PMCs. It only has a handful. Those precious few would benefit from the judicial and pervasive application of the pattern <a href="http://c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism">Replace Conditional With Polymorphism</a>.</p>

<p>Unfortunately, PMCs are far more expensive than they should be, and so it's
cheaper to make the existing PMCs far more complex (and subsequently far more
expensive on the individual level, not only the type level) than they should
be. If PMC <em>types</em> were cheap, individual PMCs could be smaller and
smarter and the entire system itself could have much stronger pressure toward
simplicity.</p>

<p>Then again, writing an object system in C using native C data structures and
dispatch mechanisms and language patterns governs what you can and can't
accomplish cheaply and easily. One of the goals of the <a
href="http://trac.parrot.org/parrot/wiki/Lorito">Parrot Lorito project</a> is
to reduce the tight coupling of Parrot's internals with C so as to make
necessary changes in Parrot sufficiently inexpensive.</p>

<p>(Any metaobject system in, for example, Perl 5 would do well to consider these lessons.)</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/05/04/when-you-lack-cheap-and-easy-polymorphism/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When You Lack Cheap and Easy Polymorphism</title>
		<link>http://www.modernperlbooks.com/mt/2011/05/when-you-lack-cheap-and-easy-polymorphism.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/05/when-you-lack-cheap-and-easy-polymorphism.html#comments</comments>
		<pubDate>Wed, 04 May 2011 17:42:36 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[languagedesign]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[Parrot]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[The quality and cost of your language's abstractions can affect the applicability of those abstractions. Consider Parrot and its intrinsic data structure, the PMC. The design of PMCs resembles Perl 5 SVs in a philosophical sense, if not a direct...]]></description>
			<content:encoded><![CDATA[
        <p>The quality and cost of your language's abstractions can affect the
applicability of those abstractions. Consider <a
href="http://www.parrot.org/">Parrot</a> and its intrinsic data structure, the
PMC. The design of PMCs resembles <a
href="http://perldoc.perl.org/perlguts.html#Working-with-SVs">Perl 5 SVs</a> in
a philosophical sense, if not a direct working relationship. The guiding design
principle is "A PMC should be able to support a basic set of core operations
common to all core PMCs".</p>

<p>Parrot's core PMCs have dozens of these operations, such as getting and
setting integer, numeric, and string values. They support a clone operation, an
invocation operation, an instantiation operation, and more. While some of these
operations make little sense (invoking an Integer PMC throws an exception for
obvious reasons), every PMC has to support them sufficiently that attempting to
perform that operation should not cause the VM to crash.</p>

<p>Parrot's core PMCs are big wads of C code. All of these operations in
Parrot's core PMCs are C functions gathered in a large table of function
pointers. Every PMC type has one of these tables. Adding a new core operation
to Parrot means adding a new function to every PMC table. Every new function
added to the PMC table thus adds to the memory and startup costs of Parrot
overall. Similarly, adding a new PMC type&mdash;even a specialization of an
existing type&mdash;increases the memory and startup costs of Parrot overall
because a new type needs an entirely new and distinct function pointer
table.</p>

<p>These are implementation details quite solveable with some clever
programming, but the most interesting point in my mind is how these
implementation details have influenced the development of Parrot and Parrot
languages. In particular, there's a subtle (and likely correct) belief in the
project that adding a new PMC is an expensive operation in terms of Parrot's
footprint <em>and</em> the management of its source code.</p>

<p>That's true to some extent, which is a shame, because Parrot's suitability
as a VM for interoperable languages comes in no small part from the flexibility
of the PMC system.</p>

<p>The cost of the belief in the heavy cost of new PMCs is that the core of
Parrot takes advantage of far less polymorphism than it should. Consider the
difference between a named function, an anonymous function, a method, a
closure, a continuation, an exception handler, a binding to a shared library
function, and a lazy thunk (perhaps a generator). You can invoke all of those
items. You can pass in zero or more arguments. They can each return zero or
more values. Yet they each perform very different mechanisms of control
flow.</p>

<p>An ideal Parrot design would have separate PMC types for each logical type.
A boring old named function which takes no parameters could avoid parameter
passing code altogether, while the binding to a shared library function likely
needs to marshall data to and from the appropriate ABI. A generator should be
fast and lightweight, while an exception handler may have to manipulate control
flow in interesting ways to resume an exception or at least resume at the
appropriate place in control flow based on which exceptions it can handle and
which it must decline.</p>

<p>Yet Parrot <em>doesn't</em> have multiple specialized PMC types representing  all (or even most) of the necessary variants of invokable PMCs. It only has a handful. Those precious few would benefit from the judicial and pervasive application of the pattern <a href="http://c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism">Replace Conditional With Polymorphism</a>.</p>

<p>Unfortunately, PMCs are far more expensive than they should be, and so it's
cheaper to make the existing PMCs far more complex (and subsequently far more
expensive on the individual level, not only the type level) than they should
be. If PMC <em>types</em> were cheap, individual PMCs could be smaller and
smarter and the entire system itself could have much stronger pressure toward
simplicity.</p>

<p>Then again, writing an object system in C using native C data structures and
dispatch mechanisms and language patterns governs what you can and can't
accomplish cheaply and easily. One of the goals of the <a
href="http://trac.parrot.org/parrot/wiki/Lorito">Parrot Lorito project</a> is
to reduce the tight coupling of Parrot's internals with C so as to make
necessary changes in Parrot sufficiently inexpensive.</p>

<p>(Any metaobject system in, for example, Perl 5 would do well to consider these lessons.)</p>
        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/05/04/when-you-lack-cheap-and-easy-polymorphism-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beans versus Immutable Objects</title>
		<link>http://www.modernperlbooks.com/mt/2011/04/beans-versus-immutable-objects.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/04/beans-versus-immutable-objects.html#comments</comments>
		<pubDate>Tue, 05 Apr 2011 16:31:00 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[perl6]]></category>
		<category><![CDATA[typing]]></category>
		<category><![CDATA[webprogramming]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Moose revealed itself as Good Code to me when I realized that it encourages Good Design. If you follow the example code and use the API it exposes in a natural way, you tend to write well-organized and reasonably safe...]]></description>
			<content:encoded><![CDATA[
        <p><a href="http://moose.perl.org/">Moose</a> revealed itself as Good Code to me when I realized that it encourages Good Design. If you follow the example code and use the API it exposes in a natural way, you tend to write well-organized and reasonably safe code (where "safe" means "you paint yourself into fewer corners").</p>

<p>That's the sign of a very good library or framework: the common things are
easy and they resulting code is easy to understand, maintain, and extend.</p>

<p>Moose has a very nice feature of reducing the surface area of the APIs you create with it. You can declare a class with several attributes but only expose a few public getters or setters. The ability to use lazy initialization of attributes&mdash;as well as default values&mdash;allows the calculation of dependent attributes as needed.</p>

<p>Best yet, if you can arrange your classes in such a way as to provide their
necessary attribute values when you call their constructors, you can treat your
objects from the outside as immutable, and you're halfway toward inversion of
control, if that's useful to you.</p>

<p>(Read more about Moose and immutability and the value of these features and
designs in the <a
href="http://onyxneon.com/books/modern_perl/index.html">Modern Perl book</a>,
available in several freely redistributable electronic forms.)</p>

<p>Think of all of this as not coloring outside the lines. While good art is
aware of the structure and limitations of its chosen form and breaks those
conventions when it makes for better art, good software is primarily a
conversation mechanism where perhaps you don't want to try to outdo Pynchon or
DeLillo or Wallace. Perhaps.</p>

<p>Contrast this mechanism of working with objects with the bean style as
expressed in parts of the Java world: a class has several private attributes.
Each of those attributes has public getters and setters which follow a standard
naming convention. Objects interact with other objects by their conformance to
a protocol and discovery and use of those getters and setters enabled by the
magic genericity of reflection.</p>

<p>(<a href="http://c2.com/cgi/wiki?DuckTyping">Did anyone else hear a duck
quack</a>?)</p>

<p>For the convenience of allowing a dependency injection such as Spring or a
web framework inspired by J2EE to manage some of the boilerplate of managing
object instantiation or object lifespan or even mapping object data to and from
strings for web or web request display, you not only give up the
<em>creation</em> of your objects, but you expose their internal attributes
behind a thin (and, be honest, autogenerated by your IDE when it pops up a
warning!) layer of accessor method.</p>

<p>There <em>is</em> value in the loose and ad hoc adherence to a protocol of
practice...</p>

<p>... but for a language which claims great maintainability benefits from
forcing the use of static, manifest typing, you may encounter a fair few
perplexing errors if you don't get the CamelCase type of your bean property
just so. (Remember, reflection!)</p>

<p>While sometimes I do wish Perl 5 were stricter about types and signatures&mdash;certainly I look forward to using Perl 6's gradual typing for more projects&mdash;I have more sense of safety with the Perl approach, where we don't assume our language is completely safe by itself. We're a little more paranoid, and&mdash;at least in this case&mdash;I believe it leads to better designs.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/04/05/beans-versus-immutable-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Method Keyword, take two</title>
		<link>http://www.modernperlbooks.com/mt/2011/01/the-method-keyword-take-two.html</link>
		<comments>http://www.modernperlbooks.com/mt/2011/01/the-method-keyword-take-two.html#comments</comments>
		<pubDate>Tue, 01 Feb 2011 00:07:47 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[modernperl]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I've published a second version of a patch to add a method keyword to Perl 5. The main difference in this patch is building up the optree to perform my $self = shift; instead of stuffing that code into the...]]></description>
			<content:encoded><![CDATA[
        <p>I've published a second version of <a href="http://www.modernperlbooks.com/mt/2011/01/what-else-a-method-keyword-could-do.html">a patch to add a <code>method</code> keyword to Perl 5</a>. The main difference in this patch is building up the optree to perform <code>my $self = shift;</code> instead of stuffing that code into the lexer at the appropriate place:</p>

<pre><code>methbody : '{' remember addimplicitshift stmtseq '}'
            {
                if (PL_parser-&gt;copline &gt; (line_t)IVAL($1))
                  PL_parser-&gt;copline = (line_t)IVAL($1);
              $$ = block_end($3, op_append_list(OP_LINESEQ, $3, $4));
              TOKEN_GETMAD($2,$$,'{');
              TOKEN_GETMAD($4,$$,'}');
            }
    ;

addimplicitshift :
    { OP *selfsv      = newOP(OP_PADSV, 0);
      OP *rv2av       = newUNOP(OP_RV2AV, 0, newGVOP(OP_GV, 0, PL_defgv));
      OP *shift       = newUNOP(OP_SHIFT, 0, rv2av);

      selfsv-&gt;op_targ = (I32)Perl_allocmy(aTHX_ STR_WITH_LEN("$self"), 0);
      $$              = newSTATEOP(0, NULL,
                            newASSIGNOP(OPf_STACKED, selfsv, 0, shift));
     }
    ;</code></pre>

<p>The second production is most interesting. It does the work of creating the
Perl 5 optree you can see from running:</p>

<pre><code>$ <strong>perl -MO=Concise,meth -e 'sub meth { my $self = shift; }'</strong>
main::meth:
7  &lt;1&gt; leavesub[1 ref] K/REFC,1 -&gt;(end)
-     &lt;@&gt; lineseq KP -&gt;7
1        &lt;;&gt; nextstate(main 1 -e:1) v -&gt;2
6        &lt;2&gt; sassign sKS/2 -&gt;7
4           &lt;1&gt; shift sK/1 -&gt;5
3              &lt;1&gt; rv2av[t2] sKRM/1 -&gt;4
2                 &lt;$&gt; gv(*_) s -&gt;3
5           &lt;0&gt; padsv[$self:1,2] sRM*/LVINTRO -&gt;6</code></pre>

<p>You don't have to understand all of that, but you can see that this is
obviously a tree structure. <code>addimplicitshift</code> creates the branch
staring at <code>nextstate</code> (op 1) with a sibling <code>sassign</code>
(op 6). Other productions have already set up the body of the sub and its
lexical scope, so the call to <code>Perl_allocmy</code> only has to give the
name of a new lexical (<code>$self</code>). Its return value is the location of
the created variable in the lexical storage pad, so that the opcode to access
the value of <code>$self</code> can retrieve it correctly.</p>

<p>With that lexical created before the parser parses the literal body of the method from the source code, any other references to <code>$self</code> refer to the lexical implicitly created thanks to the <code>method</code> keyword such that:</p>

<pre><code>use feature 'method';

method oops
{
    my $self = shift;
}</code></pre>

<p>... produces a warning:</p>

<pre><code>"my" variable $self masks earlier declaration in same scope</code></pre>

<p>I suspect there's a reasonably easy way to make the <code>method</code> keyword work nicely with projects such as <a href="http://search.cpan.org/perldoc?MooseX::Declare">MooseX::Declare</a> in code such as:</p>

<pre><code>use 5.014;
use MooseX::Declare;

method register(Str $name, Int $age) { ... }</code></pre>

<p>... but despite <a
href="http://www.modernperlbooks.com/mt/2011/01/what-else-a-method-keyword-could-do.html">the
advantages of a <code>method</code> keyword in Perl 5</a>, I've done about as
much coding on this as I want to do without more support that it might
eventually go into Perl 5.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2011/02/01/the-method-keyword-take-two/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mechanism versus Policy</title>
		<link>http://www.modernperlbooks.com/mt/2010/08/mechanism-versus-policy.html</link>
		<comments>http://www.modernperlbooks.com/mt/2010/08/mechanism-versus-policy.html#comments</comments>
		<pubDate>Mon, 23 Aug 2010 21:32:18 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[languagedesign]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[perl6]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[First, read Tyler Curtis's Age discrimination in Perl 6 using subsets and multiple dispatch. You can do everything in that post manually in Perl 5. (You're better off using a module such as MooseX::MultiMethods to handle the plumbing for you,...]]></description>
			<content:encoded><![CDATA[
        <p>First, read Tyler Curtis's <a href="http://blogs.perl.org/users/tyler_curtis/2010/08/age-discrimination-in-perl-6-using-subsets-and-multiple-dispatch.html">Age discrimination in Perl 6 using subsets and multiple dispatch</a>.</p>

<p>You can do everything in that post manually in Perl 5.  (You're better off
using a module such as <a
href="http://search.cpan.org/perldoc?MooseX::MultiMethods">MooseX::MultiMethods</a>
to handle the plumbing for you, but the point stands.)  That's the fallacy of
the Turing tarpit and the Blub programmer: everything is <em>possible</em>, but
language support makes certain constructs easy and obvious, and easy and
obvious code tends to exist.</p>

<p>If you think about Tyler's post that way, you can squint and see a general language design principle at work.  Let me belabor the point somewhat more.  Consider how to declare a new class in Perl 5.  You have multiple possibilities.  A class is merely a namespace, so:</p>

<pre><code>package My::Class { ... }</code></pre>

<p>That's well and good, and it works.  Now do it at runtime:</p>

<pre><code>eval "package $classname { ... }";</code></pre>

<p>Again, that works.  Yet if you consider the <a href="http://search.cpan.org/perldoc?Class::MOP">Class::MOP</a> approach, you can start to see the flaw:</p>

<pre><code>my $class = Class::MOP::Class->create( $classname );</code></pre>

<p>I admit the flaw isn't staggeringly obvious until you need to add methods to the class.  Again, it's not <em>awful</em> in standard Perl 5:</p>

<pre><code>sub My::Class::method { ... }</code></pre>

<p>... or at runtime:</p>

<pre><code>{
    no strict 'refs';
    *{ $classname . '::' . $methname } = $method_ref;
}</code></pre>

<p>... but how ugly when compared to:</p>

<pre><code>$class->add_method( $methname, $method_ref );</code></pre>

<p>The difference is the design principle at work: specify policy, not
mechanism.  In other words, the problem with the standard Perl 5 approach is
that the <em>how</em> of how you store a subroutine in a package overshadows
the <em>intent</em> of the approach.  What's important is not symbolic
references to typeglob slots in packages which represent classes.  What's
important is adding a method to a class.</p>

<p>The same rule applies when specifying type constraints on function parameters or multidispatch candidates or even declaring classes themselves:</p>

<pre><code>class My::Class
{
    method awesome_method { ... }
}</code></pre>

<p>... because even as much as I know how to implement a language on top of a virtual machine (or how to compile a language to native code), at the point where I <em>read</em> this code, much less write it, I don't care about the mechanism.  I care about defining the policy.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2010/08/23/mechanism-versus-policy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I Did Wrong (Test::MockObject)</title>
		<link>http://www.modernperlbooks.com/mt/2010/08/what-i-did-wrong-testmockobject.html</link>
		<comments>http://www.modernperlbooks.com/mt/2010/08/what-i-did-wrong-testmockobject.html#comments</comments>
		<pubDate>Tue, 17 Aug 2010 01:49:55 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[mockobjects]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[perlprogramming]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I admit it, I avoid languages such as Java because they make it so difficult to write useful libraries such as Test::MockObject. When you're writing lots of test cases and flipping back and forth between code and test code and...]]></description>
			<content:encoded><![CDATA[
        <p>I admit it, I avoid languages such as Java because they make it so difficult to write useful libraries such as <a href="http://search.cpan.org/perldoc?Test::MockObject">Test::MockObject</a>.  When you're writing lots of test cases and flipping back and forth between code and test code and refactoring every time you make a test pass, the more ceremony and boilerplate you have to move around, the more friction you feel and the less work you can get done easily.</p>

<p>I wrote T::MO several years ago when I noticed a pattern in test code I'd written.  I wanted to isolate a couple of cases of behavior to test all of the code paths within specific functions and methods.  Invariably I took advantage of Perl's dynamism to construct objects which adhered to a specific protocol of behavior but which were under my direct control.</p>

<p>Think of it this way.  You want to test the error handling code for a database abstraction layer.  If the network connection goes away or if the remote process crashes, you want to retain the data and perform the appropriate logging and recovery.</p>

<p>How do you test that?  You force a failure.  No, you don't hire an intern to yank the network cable during your tests.  You mock up the code which raises the "Wow, it's suddenly quiet in here!" exception.</p>

<p>This is where I wrote T::MO wrong.  Instead of mocking <em>just one piece</em> of the underlying plumbing, T::MO encourages people to mock the entire system, from the faucets down to the sewer system.  You do get more control over the process, but you can lose yourself in a sea of sweaty little details.</p>

<p>T::MO <em>can be</em> an invaluable tool.  Sometimes it's exactly what you need, especially when you have to clean up a pile of legacy code written without good design taste.  Even so, I wish I'd written <a href="http://search.cpan.org/perldoc?Test::MockObject::Extends">Test::MockObject::Extends</a> first to encourage people to mock only <em>part</em> of the behavior of an object.  If your code is anywhere close to well-factored, you should be able to splice in the specific behavior you need, scalpel precise, and have confidence that the rest of the code, the real code you run when you run the code for real, behaves appropriately.</p>

<p>The more you need to mock, the more coupled (and, generally, the poorer) your design.  The less you do mock, the better your tests.</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2010/08/17/what-i-did-wrong-testmockobject/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Luck and the Class Struct API</title>
		<link>http://www.modernperlbooks.com/mt/2010/07/luck-and-the-class-struct-api.html</link>
		<comments>http://www.modernperlbooks.com/mt/2010/07/luck-and-the-class-struct-api.html#comments</comments>
		<pubDate>Fri, 02 Jul 2010 20:01:01 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[apis]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[oo]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Class::Struct has been a core module for ages. (Previously it was Class::Template, but a great renaming occurred 13 years ago.) If you've never seen it before, it might remind you a little bit of Moose: package Cat; use Class::Struct; struct(...]]></description>
			<content:encoded><![CDATA[
        <p><a href="http://search.cpan.org/perldoc?Class::Struct">Class::Struct</a> has been a core module for ages.  (Previously it was <a href="http://search.cpan.org/perldoc?Class::Template">Class::Template</a>, but a great renaming occurred 13 years ago.)  If you've never seen it before, it might remind you a little bit of <a href="http://moose.perl.org/">Moose</a>:</p>

<pre><code>package Cat;

use Class::Struct;

struct( name =&gt; '$', age =&gt; '$', diet =&gt; '$' );</code></pre>

<p>You don't get all of the benefits of Moose, but you do get attributes and accessors.  You also get a default constructor.</p>

<p>Of course, the default constructor reads something like:</p>

<pre><code>{
    package Cat;
    use Carp;

    sub new
    {
        my ($class, %init) = @_;
        <strong>$class = __PACKAGE__ unless @_;</strong>
        ...
    }

    ...
}</code></pre>

<p>If that emboldened line is curious to you, it's curious to me too.  I saw a note in one of the test files somewhere suggesting that the purpose of this was to allow you to write:</p>

<pre><code>package Cat;

my $cat = new();</code></pre>

<p>I don't know why you'd do that, however.  In what kind of object design does
it make sense to create objects of a class from within that class?  (That seems
like a violation of responsibilities to me.)  You can also write:</p>

<pre><code>package NotCat;

my $cat = Cat::new();</code></pre>

<p>... though that's exceedingly fragile.  For one thing, it implies that you could also write <code>RobotCat::new()</code>&mdash;assuming that <code>RobotCat</code> extends <code>Cat</code>, but avoiding method dispatch for calling a constructor means that <code>RobotCat</code> had better provide its own <code>new()</code> which behaves as a function as well as a method.  (Even if you somehow convinced the subclass to inherit the superclass's function through some sort of exporting scheme, the hardcoded <code>__PACKAGE__</code> would hurt.)</p>

<p>Hardcoding a method dispatch as a function dispatch means that the maintainers of <code>Cat</code> are not free to change <em>how</em> <code>Cat</code> provides its constructor, much for the same reason.</p>

<p>Woe unto you if there's an inherited <code>AUTOLOAD</code> somewhere.</p>

<p>I realize that in 1994 or 1995, people who wrote OO code in Perl 5 might
have had familiarity with OO in C++ (where this syntax makes a little more
sense) or, perhaps, Java where the indirect constructor call (the <code>my Cat
$cat = new Cat;</code> is prevalent), but the benefit of hindsight is that
experienced Perl 5 programmers can look back on this API a decade later and
cringe at its potential for misuse.</p>

<p>If you're lucky, everything will go right&mdash;but what kind of a defensive programmer relies on <em>luck</em> when designing an API?</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2010/07/02/luck-and-the-class-struct-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Are Objects Black Blocks or Toolkits?</title>
		<link>http://www.modernperlbooks.com/mt/2010/05/are-objects-black-blocks-or-toolkits.html</link>
		<comments>http://www.modernperlbooks.com/mt/2010/05/are-objects-black-blocks-or-toolkits.html#comments</comments>
		<pubDate>Mon, 10 May 2010 22:12:51 +0000</pubDate>
		<dc:creator>chromatic</dc:creator>
				<category><![CDATA[cpan]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[lwp]]></category>
		<category><![CDATA[modernperl]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl5]]></category>
		<category><![CDATA[perlprogramming]]></category>
		<category><![CDATA[roles]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I'm working on a small project today. Part of that project requires fetching syndication feeds and enqueueing further work if those feeds have new items. That means detecting whether those feeds have new items, and it also means polling the...]]></description>
			<content:encoded><![CDATA[
        <p>I'm working on a small project today.  Part of that project requires fetching syndication feeds and enqueueing further work if those feeds have new items.  That means detecting whether those feeds have new items, and it also means polling the sites with those feeds frequently.</p>

<p>These are simple, well-understood problems, with well-understood
solutions.</p>

<p>I don't want to poll sites more frequently than they allow, so I'm happy to
use <a href="http://search.cpan.org/perldoc?LWP::RobotUA">LWP::RobotUA</a> to
fetch the feeds, as it respects the <a
href="http://www.robotstxt.org/">robots.txt</a> protocol for well-behaved
spiders.</p>

<p>I also want to skip processing if the feeds remain the same between fetches, so I want to use <a href="http://search.cpan.org/perldoc?LWP::UserAgent::WithCache">LWP::UserAgent::WithCache</a>, which checks HTTP headers such as <code>Last-Modified</code>/<code>If-Modified-Since</code> and <code>ETag</code>/<code>If-None-Match</code> for modifications.</p>

<p>Unfortunately, both are subclasses of <a href="http://search.cpan.org/perldoc?LWP::UserAgent">LWP::UserAgent</a>, and both expect to be at the same level of a complex inheritance hierarchy which forms all of LWP in Perl.</p>

<p>Here is the object lesson for people desigining software.  If you intend other people to reuse your software as components, such that you can't predict how other people will use it, remove as many unnecessarily hard-coded dependencies as possible.</p>

<p>If I were to redesign this part of LWP, I'd make the caching behavior and the robots.txt-respecting behavior into separate behaviors, perhaps runtime roles.  I'd rewrite the <a href="http://search.cpan.org/perldoc?LWP::UserAgent">LWP::UserAgent</a> constructor to use a plugin system, where instantiators could provide an optional (and ordered) list of behaviors with which to decorate the <code>$ua</code> object.  Obviously the behavior I need is first to check the cached copy and then check the <em>robots.txt</em> rules and then use normal HTTP access, but why hard-code these behaviors?</p>

<p>There are plenty of mechanisms (CLOS method modifiers, the Decorator pattern, dependency injection) to work around this problem, but for now my solution is to subclass <code>LWP::UserAgent::WithCache</code>, override its constructor, and manually inherit from <code>LWP::RobotUA</code>.</p>

<p>(For all of the faults of Java's IO model, it handles this problem well.  Its defaults are awful, and it exposes too much complexity, but the Decorator pattern works effectively.  PerlIO works in a similar fashion with much better defaults.  This HTTP fetching problem is in the same category; note how a similar model could handle proxying, compressed output, anonymizers, and filtering with ease.)</p>

        
    ]]></content:encoded>
			<wfw:commentRss>http://perlblogs.com/2010/05/11/are-objects-black-blocks-or-toolkits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

