Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-4946

Contain, include functions should be rvalue, return class reference(s)


    • Type: New Feature
    • Status: Closed
    • Priority: Normal
    • Resolution: Duplicate
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
    • Template:
    • Epic Link:
    • Sub-team:
    • Team:
      Platform Core
    • Story Points:
    • Sprint:
      Platform Core KANBAN
    • Release Notes:
      New Feature
    • Release Notes Summary:
      The functions {{contain}} and {{include}} now return class references to the contained or included classes. This is of value as it allows direct establishment of relationships which results in more succinct code (fewer lines needed).
    • QA Risk Assessment:
      No Action


      Feature Request

      Currently the include and contain functions are statements, and do not return a value.

      Specifically around the containment use case, it is desirable for these functions to return a reference to the class object(s) they create, for use with dependency chaining.

      If contain and include returned references to the class(s) they add to the catalog, the following could be accomplished:

      Desired Syntax

      contain('ntp::install') ->
      contain('ntp::config') ~>

      Pro: short, succinct. Dependencies are declared. Duplicate class declaration errors are avoided.

      Possible Con: functions have not returned referencable class/type objects before, so this might seem new/unexpected.


      Prior to the introduction of the contain function the Anchor Pattern was used to implement the following kind of dependency-ordered class declaration:

      anchor { 'ntp::begin': } ->
      class { 'ntp::install': } ->
      class { 'ntp::config': } ~>
      class { 'ntp::service': } ->
      anchor { 'ntp::end': }

      The contain function is intended to obviate the need to use the Anchor pattern. However, right now it's hard to achieve the level of apparent elegance of the above statement using contain. Here are several existing options:

      Option 1: Declare then contain

      class { 'ntp::install': } ->
      class { 'ntp::config': } ~>
      class { 'ntp::service': }
      contain 'ntp::install'
      contain 'ntp::config'
      contain 'ntp::service'

      Pro: you get containment, and you get dependency ordering.

      Con: you have to use twice as many lines of code as you have classes and it feels like something is being duplicated. Contain is also positioned as an after-effect, rather than as the declaration you want to make. It is necessary to use contain afterwards in this syntax to avoid duplicate class/resource declaration errors.

      Option 2: Contain then specify dependencies

      contain 'ntp::install'
      contain 'ntp::config'
      contain 'ntp::service'
      Class['ntp::install'] ->
      Class['ntp::config'] ~>

      Pro: you get containment, and you get dependency ordering. You also aren't using resource-like declarations, which means you can still include or contain the referenced classes elsewhere in the codebase without worrying about evaluation order.

      Con: you have to use twice as many lines of code as you have classes and it feels like something is being duplicated. The class reference syntax is often confusing to users though. For whatever reason many newer users do not initially understand the difference between this approach and Option 1, nor what benefit this provides.

      All of these options have more cognitive overhead than the desired syntax that this ticket captures as a feature request. It would be awesome to be able to simultaneously contain and specify dependencies for classes.


          Issue Links



              • Assignee:
                reid Reid Vandewiele
              • Votes:
                0 Vote for this issue
                3 Start watching this issue


                • Created:

                  Zendesk Support