On Apr 12, 12:45 am, Dan Bode <d...@puppetlabs.com> wrote:
> On Mon, Apr 11, 2011 at 9:25 PM, John Warburton <jwarbur...@gmail.com>wrote:
>
> > OK, I'll bite
>
> > In the newly published Style Guide (
> >http://docs.puppetlabs.com/guides/style_guide.html), right at the end it
> > says
>
> >     Modules should avoid the use of extlookup() in favor of ENCs or other
> > alternatives
>
> For clarity, this should read:
>
> in favor of ENCs in combination with parameterized classes
>
> But there is no reason as to why.
>
>
>
> that is partly my fault.
>
> <the following is my opinion, and may or may not express the opinions of
> PuppetLabs, although I can be pretty persuasive :) >
>
> Extlookup provided some necessary pre-2.6.x functionality, namely, a sane
> way to get around dynamic scoping.
>
> given the option between parameterized class combined with an ENC vs.
> extlookup, I choose parameterized classes+ENC. The reason is readability and
> encapsulation.


I seem to be the person here to most vocally express reservations
about parameterized classes in general, but am I really the only one
who isn't buying in?  I do understand that Puppet Labs put
considerable effort into developing the feature, and that they now
tout it as one of the key improvements in 2.6, and that it furthermore
serves as the foundation for run stages.  But none of that makes it
technically superior in its current form.

Among parameterized classes' problems are

1) parameterized classes can be included only once, unlike
unparameterized ones.  This tends to require modules to have an
hierarchical structure, which isn't very suitable in many
circumstances.  (More on that below.)  It does, however, sort of
address

2) parameterized classes present the opportunity to include the same
class with different parameters in different places.  It's quite
reasonable that doing so constitutes an error, but it is unfortunate
that the DSL provides the opportunity to commit such an error in the
first place.  On the other hand,

3) parameterized classes not only permit, but tend to require this:

> With param classes, you can build a layered architecture of classes that
> pass data to each other through their explicit interfaces.

Talk about losing encapsulation!  Every parameter a class exposes
constitutes a reduction in the encapsulation it provides.  That's even
more the case when classes expose parameters solely to pass them on to
other classes they include.  That sort of parameter forwarding is
likely to become necessary because the only sane way to manage an
architecture wherein parameterized classes include other parameterized
classes is to structure it hierarchically.  A hierarchical manifest
architecture isn't particularly suitable, however, because real system
configurations aren't hierarchical.

The Style Guide seems to poo-poo that last problem when it says
"classes which require other classes should not directly declare them
and should instead allow the system to fail if they are not declared
by some other means."  (Or at least I think that's what it's doing --
I find the Guide's usage of the term "declare" to be a bit
ambiguous.)  Really, the Guide's recommendation here is a practical
necessity, not a stylistic issue, once you're committed to a hierarchy
of parameterized classes.  But why is it presented as if it were a
good approach?  It creates points of failure that shouldn't be needed,
and it constitutes another encapsulation violation wherever it
applies.  Furthermore,

4) parameterized classes make configurations harder to maintain
because changes to a class's parameterization require corresponding
changes wherever that class is included.  This is a symptom of the
loss of encapsulation inherent in parameterization (3, above), but I
call it out specifically because it's more concrete.  Additionally,

5) parameterized classes, and especially the term "parameter passing"
have a bit of code smell in declarative Puppet DSL.  I'm satisfied
that the implementation is appropriately declarative, but the concept
evidently influences people toward thinking along imperative lines,
which typically doesn't fit well with Puppet, and which is already a
big enough trap for the unwary.


As I understand it, the main objectives of parameterized classes are
(a) to provide an alternative to dynamically-scoped variables for
influencing classes, and (b) to better document classes' data
dependencies.  Indeed, the feature does achieve those objectives.  I
tend to discount the documentation aspect, however, for I don't find
class parameters adequate without ordinary text documentation, whereas
text documentation can be adequate without parameterization.  As for
feeding data to classes, parameters certainly aren't the only way, and
with all their disadvantages, they usually aren't the best way.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to