On Thursday, April 3, 2014 10:31:40 AM UTC-5, David Portabella wrote:
>
> *> **Agree with John that you want to completely avoid using the 
> parameterized style declaration of classes. Better to use 
> 'include'  statements and set all of your params in Hiera. *
>
> That's an interesting discussion, 
> but that's not the point of this post.
>
> the point of this post, as I understand it from my colleague,
> is that there is a bug in puppet.
>
> on the very least, if that is not a bug, 
> puppet should complain with a clear error message of the type "Error: 
> class 'c1' mixes include-like and resource-like declarations",
>


But in fact that's not the problem.  The language reference 
notwithstanding, you CAN mix one resource-like declaration and one or more 
statement-like declarations of the same class.  Doing so introduces an 
evaluation-order dependency (the resource-like declaration must be 
evaluated first), and therefore it is unwise, but it is not in itself an 
error.

In case it did not catch your eye, I repeat: *evaluation-order dependency*.  
These are the bane of every manifest set, and you should strive to avoid 
them in any form.  I cannot emphasize that enough.  Resource-like class 
declarations are a particularly common form of evaluation-order dependency, 
but others include use of the defined() and ensure_resource() functions, 
both of which have lately been topics of conversation around here.

 

> instead of the incomprehensible error message: "Error: Duplicate 
> declaration: Class[C1] is already declared; cannot redeclare at 
> /vagrant/files/aa.pp:4".
>
>

And yet that "incomprehensible" message exactly describes the problem.  If 
there is a comprehension issue here then it revolves around the semantics 
of class declarations -- which are indeed more complicated than they might 
at first seem -- not around that message.  If you understand class 
declaration semantics then the message is quite clear.  If you don't, then 
no error message emitted in that situation could be clear.

 

>
> About this note:
>
>
> http://docs.puppetlabs.com/puppet/latest/reference/lang_classes.html#declaring-classes
> *Include-Like vs. Resource-Like*
> *Puppet has two main ways to declare classes: include-like and 
> resource-like.*
> *Note: These two behaviors should not be mixed for a given class. Puppet’s 
> behavior when declaring or assigning a class with both styles is undefined, 
> and will sometimes work and sometimes cause compilation failures.*
>
>
> I think that the *result* of class { java: } and include java are 
> semantically equivalent.
> I cannot think of any conceptual reason why these two behaviours could not 
> be mixed for a given class.
> Do you have any conceptual reason of why that can be a problem?
>


The result of those two declarations is semantically equivalent, *provided 
that* no declaration of class 'java' has yet been evaluated, which depends 
on evaluation order and on what other declarations are present in the 
manifest set.  That proviso is exactly the reason for the quoted 
recommendation.

Note also that the current language reference includes a best-practices 
statement that says, in part, "*Most* users in *most* situations should use 
include-like declarations and set parameter values in their external data" 
(emphasis in the original).  That has not always been there, but I fully 
agree -- even down to the "most".  For the particular case of class 
declarations that don't specify any parameters, that can be strengthened to 
ALL users in ALL situations.

 

>
> I can only think that this is a technical problem in the puppet 
> implementation, that could be fixed.
> what prevents puppet to allow mixing these two behaviours for a given 
> class?
> (a part from a refactoring of the code...)
>
>

You are right that Puppet could put in special-case handling for 
resource-like class declarations that don't specify any parameters to treat 
them as fully equivalent to 'include' statements, but I'm not persuaded 
that doing so would be better.  For that increase in code complexity, you 
would just make the issue more obscure.  Then, the question would be "why 
does it work if I don't specify any parameters, but break with a 'duplicate 
declaration' error when I add one?"  You not only keep the resource-like 
vs. statement-like issue, but you also get inconsistency within 
resource-like declarations.

Moreover, special-case handling like that would also allow you to write

class { 'foo': }
class { 'foo': }

whereas it is always an error to write

anything_but_class { 'foo': }
anything_but_class { 'foo': }

Therefore, despite the constraints on resource-like class declarations (for 
which I, and now PL, generally recommend avoiding their use), I think their 
current implementation is as good as we can hope to have.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/fa653c44-0cb3-4d88-a555-137195289352%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to