On Friday, August 30, 2013 11:11:52 AM UTC-5, Andy Parker wrote:
>
>
> Here are the possibilities:
>
>   * resource like syntax for classes expresses containment:
>
>       class container { class { contained: parameter => value } }
>
>   * a function declares the class *and* expresses containment
>
>       class container { contain(contained, { parameter => value }) }
>
>   * a function expresses containment, but does not declare the class
>
>       class container { class { contained: parameter => value } 
> contain(contained) }
>
>   * a new "resource type" expresses containment
>
>      class container { contain { contained: parameter => value } }
>
>

For the record, when I suggested a function modeled on include() and 
require(), I meant that pretty directly.  My intention was that like the 
other two, the proposed function should declare the class *without any 
explicit parameters*, and simultaneously express the desired containment 
relationship.  If you want to contain a class declared via a 
parameterized-style declaration, then you simply use both:

class container {
  class { 'contained': parameter => value }
  contain 'contained'
}

That does not require any special provision, since multiple class 
declaration has always worked as long as any parameterized-style 
declaration of the given class is the first evaluated.  Thus, if you need 
only half containment then you could substitute the 'require' function for 
the 'contain' function -- that should work right now.

If you didn't want to express any explicit parameter bindings in the 
manifest then you could omit the parameterized-style declaration (just as 
you could do with require()):

class container {
  # Declares class 'contained', analogous to the
  # function of 'include' and 'require':
  contain 'contained'
}

Part of my premise here is that you cannot reasonably infer from a class 
declaration alone -- regardless of the form of the declaration -- whether 
its declaring class intends to contain the declared one.  There has to be 
something to distinguish the contained case from the non-contained one.  
The anchor pattern does exactly that, but it is verbose, unwieldy, and 
somewhat unintuitive.  A function such as I describe would be much simpler 
to understand and use.  Indeed, I'm having trouble conceiving of anything 
simpler that addresses all the use cases.


 
> The two functions could actually be written right now and distributed in a 
> module, they just need to make sure that when the class is added to the 
> catalog that it also adds an edge from the container to the contained class 
> (Patrick spiked this and verified that it works).
>
> Now, the reason that I think that the existing resource syntax is the 
> right way is that it already allows the class to appear in one place, which 
> is what we need for reasonable containment. This also gives classes 
> containment of the exact same form as resources (because they currently get 
> contained in their class), which is a good symmetry to have. In addition, 
> there has been talk about allowing duplicate resources in the catalog, 
> which will open up the whole containment question for resources (what does 
> it mean for the resource to be in two places?). To solve that we will 
> probably need some way of "declaring without containment" for resources, 
> and having classes and resources agree on how to "declare *with* 
> containment" will make any solution there transfer better to both classes 
> and resources.
>
>

Resource-like syntax does not prevent classes from being declared in 
multiple places.  It prevents parameter binding being expressed in multiple 
places among the relevant manifests, and therefore imposes an 
evaluation-order dependency, but no more than that.

Although overloading resource-like class declaration syntax with 
containment implications would make classes behave more like resources 
going forward,

   1. It will also apply those new semantics to existing manifests where 
   they do not currently apply.  Given the popularity of resource-like class 
   declaration syntax, the probability of breakage in the wild is essentially 
   unity.  Only the severity and prevalence of breakage are in question.
   2. As long as classes cannot be made to behave *exactly* like ordinary 
   resources -- and I don't think that's possible -- I don't think it really 
   helps to make them only somewhat more similar.  You trade off less user 
   surprise in one area for greater user surprise where they stumble across 
   the dissimilarities.  I think I have long since lost this particular 
   argument, but I cannot help repeating that I think it would be better to 
   explicitly distinguish classes from resources than to disguise their 
   functional differences behind a common syntax.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-dev.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to