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.
