Resolution: Won't Do
Affects Version/s: None
Fix Version/s: None
For advanced use cases when defining resources e.g. a resource that delegates to one or more other resources it is of great value
to be able to capture parameter key-values instead of having to wrap such in a Hash since that makes it impossible to use the new resource as a drop in replacement for what it delegates to without having to update all logic where the replacement should be used (see examples below in comments). (There are also other variations on this theme).
Add support for varargs/captures in user defined resources by allowing the same syntax that is used for functions to specify that extra parameters are captured into a variable. For functions this is an Array, and for "args by name" calls, this is a Hash.
In the body the variable $capture is always a Hash, it may be empty, or contain any keys the user has given. To restrict the keys, the user can type the parameter with a Hash[String, <wanted-data-type>, min, max], or a Struct. When using a Struct the keys can be pattern based (as defined in
PUP-5942) and it is thus possible to type different pattern based parameters to different types.
PUP-5942 for how to constraint the number of keys (from min required to max allowed).
The above definition of foo allows this:
- The same varargs support should also be added to EPP templates since they use "args by name".
- This should not be added to classes (there is no way to do data binding, and parameters are part of the class' API and they are externally addressable).
A concern has been raised that adding "varargs" support is less declarative, but that is only a matter of perception - something that is defined by a pattern is just as specified as a concrete specification when this is side effect free. What we cannot accept though is that the API of something changes depending on how it is used - this means that varargs support cannot be added to classes unless the expansion of the varargs hash into individual variables is made such that those variables are private to the class body thus making it impossible to refer to its individual matching parameters from outside of the class body. The captured hash itself could be made public. Support for varargs in classes is therefore not included in this ticket. If wanted a new ticket should be opened, and that ticket should depend on the ability to have private variables in class scopes.
Through roles and profiles, a pattern started to emerge where we write a wrapper define, for convenience, for better naming, both, or other reasons.
This is nice and convenient for the most simple of cases. If we need more options from apache::vhost, we have to extend our wrapper profile.
Similarly, if apache::vhost changes, and new admins want to use those new options, we (or they!) have to touch our convenience wrappers.
We could do a gruesome hack, such as:
but the additional indirection through $options is hard to follow, and with more complex wrappers it's also hard to know where our options start, and where their options end… what is a default, what's being overwritten, etc…
I propose we introduce a syntax which helps us create such, or even more powerful wrappers, analogous to clojure's &rest:
This passes fallbackresource down to the second apache::vhost.
It might be useful to filter for specific prefixes,
The idea here is that all parameters passed to a tc_and_apache_vhost that start with apache_ would be routed into the apache::vhost, and all parameters that start with tomcat_ would be routed to tomcat::instance.
I'm not sure yet, if they should be stripped of their prefix before being routed, or not.