I thought this made sense, but apparently I am mistaken: define copyfile($owner = root, $group = root, $repo = "config", $mode, $source = $name, $purge = false, $backup = false, $recurse = false, $server = $servername) { file { $name: mode => $mode, owner => $owner, group => $group, backup => $backup, recurse => $recurse, purge => $purge, source => "puppet://$server/$repo/$source" } } I thought that if I didn''t specify $source, it would be set to $name and life would be good. According to the YAML file, it is being replaced with the empty string. This is 0.22.2. Is it just that the value is not available yet at that point in argument binding, or is this just unreasonable? I am going to try another method, but was curious whether this ought to work at all. Thanks, Mark -- Mark D. Nagel, CCIE #3177 <mnagel@willingminds.com> Principal Consultant, Willing Minds LLC (http://www.willingminds.com) cell: 949-279-5817, desk: 714-630-4772, fax: 949-623-9854
On Mar 26, 2007, at 7:27 PM, Mark D. Nagel wrote:> I thought this made sense, but apparently I am mistaken: > > define copyfile($owner = root, $group = root, $repo = "config", > $mode, $source = $name, $purge = false, $backup = > false, > $recurse = false, $server = $servername) { > file { $name: > mode => $mode, > owner => $owner, > group => $group, > backup => $backup, > recurse => $recurse, > purge => $purge, > source => "puppet://$server/$repo/$source" > } > } > > I thought that if I didn''t specify $source, it would be set to > $name and > life would be good. According to the YAML file, it is being replaced > with the empty string. This is 0.22.2. Is it just that the value is > not available yet at that point in argument binding, or is this just > unreasonable? I am going to try another method, but was curious > whether > this ought to work at all.This wouldn''t work in any language that I know of. ''$name'' is only valid within the definition, not when the definition is being defined. Have the default be ''false'', and override it if it''s still false within the definition. -- Smoking is one of the leading causes of statistics. -- Fletcher Knebel --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
Luke Kanies wrote:> This wouldn''t work in any language that I know of. ''$name'' is only > valid within the definition, not when the definition is being defined. > > Have the default be ''false'', and override it if it''s still false > within the definition. > >Yup, that''s what I did. Not sure about that statement though -- my original interpretation was similar to a Perl closure. My intuition was that the $name variable would be available to use within the define, which it is (as a compile-time value), just not as an implicit parameter value. As I suspected, it is a binding time issue and the method you suggest works just fine. I think the fact that it is represented as $name just like other variables contributes to this -- maybe it should have a different look and feel... Thanks, Mark
On Mar 26, 2007, at 11:04 PM, Mark D. Nagel wrote:> I think the fact that it is represented as > $name just like other variables contributes to this -- maybe it should > have a different look and feel...It started out the other way (parameters did not have ''$''), and the community pushed toward the current state. I''m basically ambivalent. -- Hoare''s Law of Large Problems: Inside every large problem is a small problem struggling to get out. --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Tuesday 27 March 2007 06:42, Luke Kanies wrote:> On Mar 26, 2007, at 11:04 PM, Mark D. Nagel wrote: > > I think the fact that it is represented as > > $name just like other variables contributes to this -- maybe it should > > have a different look and feel... > > It started out the other way (parameters did not have ''$''), and the > community pushed toward the current state. > > I''m basically ambivalent.I''d rather see $name bound earlier, so you can use it as initializer. Don''t know whether it wouldn''t confuse even more, but myself already ran into this particular problem. Regards, David - -- - - hallo... wie gehts heute? - - *hust* gut *rotz* *keuch* - - gott sei dank kommunizieren wir über ein septisches medium ;) -- Matthias Leeb, Uni f. angewandte Kunst, 2005-02-15 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFGCM12/Pp1N6Uzh0URAnPuAJ4n1iqb0Zwny3jAHdsNnsmnyb7xgwCgkX9I 3ZOjS5ZcXy2lo6h7/11NNy0=1Ru9 -----END PGP SIGNATURE-----
On Mar 27, 2007, at 2:53 AM, David Schmitt wrote:> > I''d rather see $name bound earlier, so you can use it as > initializer. Don''t > know whether it wouldn''t confuse even more, but myself already ran > into this > particular problem.I think the closest I''d be willing to get to this would be to have a ''||='' assignment operator, so that you could easily replace defaults, although this would require some shenanigans because I don''t allow variables to be changed once they''re set. I think binding $name would be even more confusing, because no other language anywhere does this. -- You only have to be open minded if you''re wrong. --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
David Lutterkort
2007-Mar-27 18:32 UTC
Re: using $name in default assignment within define?
On Tue, 2007-03-27 at 10:56 -0500, Luke Kanies wrote:> I think binding $name would be even more confusing, because no other > language anywhere does this.I am not sure what the reight answer in this case is, but this is legal at least in ruby: def f(a=1, b=2*a) puts "a: #{a} b:#{b}" end In Lisp speak, it''s the difference between let and let*, i.e. a question of when the binding of a formal parameter to its actual value is visible. Current puppet implementation does something like 1. Determine values of formal params in calling scope and create new scope with those values 2. Bind name in the new scope 3. Add the new scope as a child of the calling scope 4. Evaluate body of define To make name available to default values in formal params, the order would have to be changed some: 1. Create new empty scope 2. Add new scope as child of calling scope 3. Bind name in the new scope 4. Determine values of formal params (from left to right) and bind in the new scope; evaluation happens against the new scope (and its parents) 5. Evaluate body of define Of course, this is all a bit theoretical, and I don''t have a patch for any of this ;) David
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Tuesday 27 March 2007 17:56, Luke Kanies wrote:> On Mar 27, 2007, at 2:53 AM, David Schmitt wrote: > > I''d rather see $name bound earlier, so you can use it as > > initializer. Don''t > > know whether it wouldn''t confuse even more, but myself already ran > > into this > > particular problem. > > I think the closest I''d be willing to get to this would be to have a > ''||='' assignment operator, so that you could easily replace defaults, > although this would require some shenanigans because I don''t allow > variables to be changed once they''re set.Here a practical example from the apache defs: $apache2_port_real = $apache2_port ? { '''' => 80, default => $apache2_port } An easy alternative would be something like the COALESCE function from SQL. It chooses the first non-NULL value from a list: $apache2_port_real = coalesce($apache2_port, 80)> I think binding $name would be even more confusing, because no other > language anywhere does this.I fear so too. Regards, David - -- - - hallo... wie gehts heute? - - *hust* gut *rotz* *keuch* - - gott sei dank kommunizieren wir über ein septisches medium ;) -- Matthias Leeb, Uni f. angewandte Kunst, 2005-02-15 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFGCjAN/Pp1N6Uzh0URAsHYAJ0SVPlYsr6V2bmVtNmCGjbe5w9ZQwCfRLEy ZHu2t3JKX/DrjB4+2811gKI=qqJn -----END PGP SIGNATURE-----
David Schmitt wrote:> > > > I think binding $name would be even more confusing, because no other > > language anywhere does this. > > I fear so too. >OK, so in Perl this is a common idiom (ok, maybe not common, but an idiom anyway): sub make_closure { my $name = shift; return sub { print $name, "\n"; }; } make_closure("c1")->(); make_closure("c2")->(); The results of each would be to print the value of ''$name'' at the time the closure was created, which would be ''c1'' and ''c2'', respectively. In the case of Puppet, I have what looks like a variable, but it is not available uniformly in the component definition. I can access it in the body of the component with the value set at the time of definition, but I cannot do so within the parameter section (component header). Clearly, it is not really a run time variable, it is a compile time variable, but the fact that it is not available in the component header but is available in the component body is really what I was originally confused about. I''m satisfied with the in-body construct I ended up with, but I refute the idea that this is not something other languages support. If you consider ''$name'' as a C macro (which it kinda sorta is), then the macro expansion should be available both in the component header as well as within the component body. Regards, Mark -- Mark D. Nagel, CCIE #3177 <mnagel@willingminds.com> Principal Consultant, Willing Minds LLC (http://www.willingminds.com) cell: 949-279-5817, desk: 714-630-4772, fax: 949-623-9854