puppet

Is there any operator like `or` but which returns the first truthy value?


Is there any operator like or but which returns the first truthy value rather than true?

Unfortunately the or operator in Puppet does not work like its Ruby counterpart.

false or 1
=> 1

In Puppet the or-operator either evaluates to literal true or literal false.

fail(false or 1)
Error while evaluating a Function Call, true

I want to use this Ruby-like or-operator to select between a value or a default value in the default value assignment of an argument like

Stdlib::IP::Address::V4::CIDR $my_ip = $settings[$system_server_index or 0][external_ip_w_cidr],

One could construct it as an if-statement, but that becomes overly verbose.

Stdlib::IP::Address::V4::CIDR $my_ip = $settings[if $system_server_index { $system_server_index } else { 0 }][external_ip_w_cidr]

The built in function any shares the same unfortunate literal-convertyness that the or-operator does.


Solution

  • With the given limitation that the solution should be as short as possible a selector expression also misses the mark like the if-expression based solution. But through #puppet on Libera I got two good alternatives.

    The first one from kjetilho is built on Puppets lest function is a bit shakespearian and only works with a single variable and only distinguishes between undef and not undef.

    $system_server_index.lest || {0}
    

    The second one from binford2k uses a function from stdlib called pick which is written for this express purpose and indeed works like Ruby's or operator.

    pick($system_server_index, 0)
    

    Both fit snugly into the whole expression with, in my opinion, the pick implementation winning out on both brevity, clarity and flexibility if you have stdlib available.

    Stdlib::IP::Address::V4::CIDR $my_ip = $settings[$system_server_index.lest || {0})][external_ip_w_cidr],
    Stdlib::IP::Address::V4::CIDR $my_ip = $settings[pick($system_server_index, 0)][external_ip_w_cidr],