On 2014-05-08 18:24, Andy Parker wrote:
On Tue, Aug 5, 2014 at 8:18 AM, Erik Dalén <erik.gustav.da...@gmail.com
<mailto:erik.gustav.da...@gmail.com>> wrote:

    On 5 August 2014 16:25, Reid Vandewiele <r...@puppetlabs.com
    <mailto:r...@puppetlabs.com>> wrote:

        On Mon, Aug 4, 2014 at 3:18 PM, Henrik Lindberg
        <henrik.lindb...@cloudsmith.com
        <mailto:henrik.lindb...@cloudsmith.com>> wrote:


            So, to summarize: The use of * => as an operator is not
            liked but the concept of being able to set attributes from a
            hash is. Unfortunately, it is not possible to directly allow
            an expression at the position in question, there must be a
            syntactical marker.

            As pointed out earlier, the * => was thought to read as
            "any_attribute => from_these_values", but I totally grok if
            people have an allergic reaction.

            We can do this though:

            file { default: ($hash) }

            This works because it is impossible to have an attribute
            name in parentheses.

            In use:

            file (
               default   : ($my_file_defaults + { mode => '0666' });
               '/tmp/foo': ;
               '/tmp/bar': ;
            }

            Is that better? No new operator, but you have to use
            parentheses around the expression.

            We can naturally also revert the functionality, but it seems
            it is liked conceptually.


            - henrik



        I think the parenthesis are far preferable over *=>. That isn't
        to say I like them - I don't particularly. But the functionality
        is desirable, and if it's a matter of a technical limitation
        then parenthesis are a Good Enough (TM) compromise from the more
        ideal direct use of a hash.


    I really prefer the use of  * => over the parenthesis. Especially if
    you need to merge things into the hash. For example look at this
    example:

    # using parenthesis hash style
    class foo (

    $servername = $::fqdn,
    $port = 80,
    $ssl = false,
    $extra_opts={},

    ) {
    apache::vhost { $servername: ($extra_opts + {


    port => $port,
    ssl => $ssl,
    })

    }
    }
    # using * =>
    class foo (

    $servername = $::fqdn,
    $port = 80,
    $ssl = false,
    $extra_opts={},

    ) {
    apache::vhost { $servername:

    port => $port,
    ssl => $ssl,
    * => $extra_opts,


    }

    }


The behavior that we worked out doesn't allow having the splat along
with the other parameters, the reason being that it isn't clear what is
meant by that. You had in your head that port and ssl are overridden by
extra_opts (possibly because they come first?), but another, completely
reasonable interpretation is that it is the other way around (port and
ssl override extra_opts because they are explicitly given. In order to
remove any of that confusion the current specification and
implementation doesn't allow mixing. That can, I think, be changed.

In the current implementation this would need to be:

apache::vhost { $servername:
   * => $extra_opts + { port => $port, ssl => $ssl }
}

    IMO the *=> is way more readable (as gist here if formatting is
    screwed up for you:
    https://gist.github.com/dalen/57b37b80a9ba1879b78c). This is quite
    similar to what I linked earlier that I am doing in
    
https://github.com/spotify/puppet-puppetexplorer/blob/master/manifests/init.pp#L89-L97
    So it is not just a contrived example.


My argument against using parenthesis is that parenthesis, are often
read as "seldom necessary grouping". I believe that most programmers
read them as usually only needed for fixing precedence problems, which
is really what is happening here but it doesn't look like it. Based on
that I can imagine that a common, and frustrating mistake would be:

   apache::vhost { $servername: $opts }

And then confusion and anger and bug reports.


Yeah, I think they are too subtle too (and hence the * =>).


One more proposal :-)

We could leave out the name part all together (i.e. drop the '*').

dalens' example would then look like this:

     apache::vhost { $servername:

     port => $port,
     ssl  => $ssl,
          => $extra_opts,

And if it is used for local defaults (or the only thing for a titled resource):

    file { default: => $hash }
    file { '/tmp/foo': => $hash }

This works best if it is restricted to being the only attribute operation for a title, but looks a bit odd when presented in a list where there are also named (i.e. name => expression) operations.

At least it is not a new operator.

Is this better than * => or requiring parentheses ?

- henrik

--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

--
You received this message because you are subscribed to the Google Groups "Puppet 
Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/lrrobu%245b1%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to