With the future parser enabling selectors to used in the case of another selector it's possible to use selectors to specialize on multiple facts or other values very concisely.
$puppet_conf_file_path = $::osfamily ? {
'Debian' => $::operatingsystem ? {
'Ubuntu' => '/pretending/ubuntu/is/special/here'/puppet/puppet.conf',
default => '/pretending/debian/in/general/is/special/in/a/different/way/here/puppet/puppet.conf',
default => '/etc/puppet/puppet.conf'
}
But sometimes setting a default value is not the desired behavior for unmatched cases. Sometimes, like in a params class, you'd rather just fail the whole puppet run when an unmatched case is hit.
class puppet::params(
# In this case we are only specializing based on one parameter
$conf_file_path = $::osfamily ? {
'Debian' => '/etc/puppet/puppet.conf',
default => fail("osfamily ${::osfamily} is not supported by this module"),
},
#in this case we are specializing based on multiple parameters
$vardir = $::osfamily ? {
'Debian' => $operatingsystem ? {
'Debian' => '/var/lib/puppet',
default => fail("operatingsystem ${::operatingsystem} is not supported by this module"),
},
default => fail("osfamily ${::osfamily} is not supported by this module"),
},
){}
This almost works with the future parser. Except that puppet errors out on the cases that hit the fail call because the fail function doesn't return an rvalue.
Making it possible to use fail in selectors would make this pattern very versatile and could greatly simplify params classes. You can set the parameters in all valid cases and throw errors with messages that are tailored to the exact context without having to repeat logic or variable names. This pattern also lets you see for sure at a glance that a parameter is being set (or that the run will fail) which is harder to see when doing the same thing with conds since you have to examine all the case blocks.
The easier way to make this work would probably be to make fail return a value (maybe the error message that would be shown). But it doesn't make sense to me that fail should check if it's expected to yield an rvalue since fail completely changes the flow of execution and will would never make it to returning a value anyways, so making the change there makes more sense to me.