For a long time, a little loop in the compiler has called evaluate_definitions after the current scope is evaluated (https://github.com/puppetlabs/puppet/blob/8a82d7d7c4d8254177e93a392607385755095cf4/lib/puppet/parser/compiler.rb#L609-L625).
This means that declaration evaluation is breadth-first instead of depth-first. However when writing manifests one often sees the pattern of if defined(Some['resource']) which depends on parse order to work. Using defined() with definitions that declare definitions such as `some::sub {'hi': }
; if defined(Some::Sub::Define['aoeu'])` when combined with the breadth-first evaluation described violates parse order, as the defined resource will not exist until after the function call as their evaluation is delayed until the end of the current scope.
If defined resources were evaluated at parse time instead of being delayed until evaluate_definitions then parse order would be maintained.
Also, I believe that this is different than collectors as collectors affect resources across the entire catalog, whereas defined resources are only evaluated a single time and will not generate additional resources on further evaluation.
|