On 2012-14-09 20:31, Eric Sorenson wrote:
Hi, there's an issue that came up recently in the 3.0RCs -- Big thanks to Erik 
Dalén for reporting it in #16221 -- that involves a behaviour change to part of 
the DSL. In a nutshell, this code:

     define foobar ($param='Hello world') {
       notice($param)
     }
     foobar { 'test': param => undef }

in 2.7, causes 'Hello world' in the notice. In 3.x, it's nothing. As I said in 
the bug, this seems more correct to me -- I've overriden the default with an 
explicit 'undef', taking off the default. The same thing goes for invoking 
parameterised classes with undef arguments, which is perhaps more ambiguous 
(example from matthaus):

     class toplevel (
        $maybe = false,
        $optional = undef ) {
        if ($maybe) {
           class { toplevel::secondlevel: optional => undef }
        }
     }

In order to make use of the default for the `optional` parameter in 
toplevel::secondlevel, you'd now need to either test in `toplevel` whether 
`$optional` was passed into it, or have toplevel::secondlevel use an 
`$optional_real` value inside it, similar to what's commonly done to append to 
defaults that are array values.

The closest thing to documentation around this suggests the new behaviour is what's 
intended 
<http://docs.puppetlabs.com/puppet/2.7/reference/lang_classes.html#overriding-resource-attributes>:

     You can remove an attribute’s previous value without setting a new one by 
overriding it with the special value undef:

       class base::freebsd inherits base::unix {
         File['/etc/passwd'] {
           group => undef,
         }
       }

So, I'm trying to determine whether this is a widespread pattern or an edge-case. Do you 
expect 'param=>undef' to be the same as not specifying param at all, or for the receiver 
to "see" the undef?

Eric Sorenson - [email protected]
PuppetConf'12 - 27-28 Sep in SF - http://bit.ly/pcsig12


When we discussed this earlier, I also felt that the new behavior was correct; settings something to undef erases the value, and if you want the default, simply do not set the value.

However, seeing the examples, and thinking about it - if the change is accepted it means it will be difficult to parameterize certain things - what if there are many optional settings and some intermediary logic takes a mix of parameters and needs to pass those on? Without the ability to "end up with the default", but still enable passing a value, there would need to be many different permutations selected with if statements - and that would not be pretty. Alternatively, have the same literal default values (which is not good as they would have to be kept in sync).

Ideally, for this situation, using a literal 'default' would make the code less confusing. I.e using the first example:

  define foobar ($param='Hello world') {
    notice($param)
  }
  foobar { 'test': param => default }

If this is implemented, it is possible to: set a new value, erase the value, or use the default value if one is present.

... this is however a bigger thing to implement. Meanwhile, it may be better to keep the somewhat mysterious behavior in 2.7.

Still feel that the behavior "undef erases the value" is a less surprising result.

Regards
- henrik

--
You received this message because you are subscribed to the Google Groups "Puppet 
Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to