Issue #11331 has been updated by Henrik Lindberg.

Thought a bit more about this, and that it is also wanted to be able to perform 
other operations on collections. At the same time as the previously suggested 
syntax would be easy to implement, it also adds one keyword (`foreach`) - and 
if other similar operations are wanted (e.g. collect, exists, all, first, etc.) 
it becomes quite a problem.

Instead, I propose that foreach (and similar) are added as an expression on the 
form:
`expr . funcname { |parameters| statements }`

Thus, the earlier example would be written:
<pre>define firewall($users,$port) {
  $users.foreach { |$u|
    iptables::open { "$u:$port": user=>$u, port=>$port; }
  }
}
</pre>

This is better because it does not interfere with any existing syntax, and does 
not introduce any new keywords. A first implementation can be hard wired to 
only support the forach function, but opens up for exploring additional 
functions, user supplied functions etc. (There are quite a few issues to deal 
with if the mechanism is generalized).
----------------------------------------
Feature #11331: Add 'foreach' structure in manifests
https://projects.puppetlabs.com/issues/11331#change-81092

Author: Steve Shipway
Status: Needs Decision
Priority: High
Assignee: J.D. Welch
Category: language
Target version: 3.x
Affected Puppet version: 
Keywords: ux backlog
Branch: 


I doubt this would be simple to do, but it would be very useful to be able to 
do something like this:

    $variable = [ 'a', 'b', 'c' ]
    foreach $loop $variable {
      file { "/tmp/$loop": content=>"I am file $loop"; }
    }

While it is already possible to use an array as a namevar to get something 
similar, it doesnt allow you to have calculated parameters as well.

This would not be expected to break the declarative nature of puppet, though it 
would bring in a new variable scope in the loop.

Using a define with an array for the namevar would work provided the top level 
could not be called multiple times.

We want to have something like this:

    define firewall($users,$port) {
      iptables::open { $users: port=>$port; }
    }
    node foo {
      $webusers = [ 'fred', 'sid' ]
      $sshusers = [ 'fred', 'joe' ]
      firewall { port80: users=>$webusers, port=>80; }
      firewall { port22: users=>$sshusers, port=>22; }
    }

This example would fail because the iptables::open define is called with user 
'fred' two times (although with a different port parameter).  If we could 
instead have a foreach iteration then something like this would be useable:

    define firewall($users,$port) {
      foreach $users {
        iptables::open { "$loop:$port": user=>$loop, port=>$port; }
      }
    }

This would ensure a unique namevar for iptables::open.  We would also be able 
to do things like initialise an array of users with different metadata 
parameters (eg, their full names pulled form LDAP)



-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To post to this group, send email to puppet-bugs@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-bugs+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-bugs?hl=en.

Reply via email to