Justin Lloyd
2011-Nov-15 21:42 UTC
[Puppet Users] Editing a variable defined in the same scope
I tried the following (names changed to protect the innocent and guilty): class myclass ( $param ) { $myvar = [ "foo", "bar" ] if $param == "special" { $myvar += [ "blah" ] } } and got the message "...Cannot append, variable myvar is defined in this scope...". According to the docs, variables cannot be modified in the same scope because of the declarative nature of Puppet<http://docs.puppetlabs.com/guides/language_guide.html> . However, if I change the plus-signment statment to $myclass::myvar += [ "blah" ] it works fine. Can someone explain this aspect of scoping? (Or is this possibly a bug...?) Justin -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Christopher Wood
2011-Nov-15 23:05 UTC
Re: [Puppet Users] Editing a variable defined in the same scope
On Tue, Nov 15, 2011 at 01:42:24PM -0800, Justin Lloyd wrote:> I tried the following (names changed to protect the innocent and guilty): > > class myclass ( $param ) { > > ��� $myvar = [ "foo", "bar" ] > > ��� if $param == "special" { > ������� $myvar += [ "blah" ] > ��� } > > } > > and got the message "...Cannot append, variable myvar is defined in this > scope...". According to the docs, [1]variables cannot be modified in the > same scope because of the declarative nature of Puppet. > > However, if I change the plus-signment statment to > > $myclass::myvar += [ "blah" ] > > it works fine. Can someone explain this aspect of scoping? (Or is this > possibly a bug...?) > > JustinSimpler example, but I get "bar\n" in both files: $ cat /tmp/scope1.pp class myclass { $myvar = [ "foo\n", "bar\n" ] file { "/tmp/a1": content => $myvar } $myclass::myvar += [ "blah" ] file { "/tmp/a2": content => $myclass::myvar, } } class { myclass: } $ puppet apply /tmp/scope1.pp notice: /Stage[main]/Myclass/File[/tmp/a2]/ensure: defined content as ''{md5}d3b07384d113edec49eaa6238ad5ff00'' notice: /Stage[main]/Myclass/File[/tmp/a1]/ensure: defined content as ''{md5}d3b07384d113edec49eaa6238ad5ff00'' $ cat /tmp/a1 bar $ cat /tmp/a2 bar Maybe it''s not emitting an error, but I can''t get $myclass::myvar with a different value. Not that I know so much about what''s going on.> -- > You received this message because you are subscribed to the Google Groups > "Puppet Users" group. > To post to this group, send email to puppet-users@googlegroups.com. > To unsubscribe from this group, send email to > puppet-users+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/puppet-users?hl=en. > > References > > Visible links > 1. http://docs.puppetlabs.com/guides/language_guide.html-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Nov-16 14:22 UTC
[Puppet Users] Re: Editing a variable defined in the same scope
On Nov 15, 3:42 pm, Justin Lloyd <jstn...@gmail.com> wrote:> I tried the following (names changed to protect the innocent and guilty): > > class myclass ( $param ) { > > $myvar = [ "foo", "bar" ] > > if $param == "special" { > $myvar += [ "blah" ] > } > > } > > and got the message "...Cannot append, variable myvar is defined in this > scope...". According to the docs, variables cannot be modified in the same > scope because of the declarative nature of > Puppet<http://docs.puppetlabs.com/guides/language_guide.html> > . > > However, if I change the plus-signment statment to > > $myclass::myvar += [ "blah" ] > > it works fine. Can someone explain this aspect of scoping? (Or is this > possibly a bug...?)Do check whether you are seeing the behavior Christopher reports. It is a Puppet axiom that you cannot modify the value of any variable once it is set. Even += doesn''t really do that: that''s why the appended values are not seen outside the scope where the += is performed. I recommend you just come up with another way to do what you want. In fact, I recommend you avoid += even in situations where it works. Here''s one way: class myclass ( $param ) { if $param == "special" { $myvar = [ "foo", "bar", "blah" ] } else { $myvar = [ "foo", "bar" ] } } There are also a couple of ways you could concatenate arrays in Puppet. If you want to do that a lot then I''d write a custom function, but for the odd one-off you could hack together something using inline_template() and split(). John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Justin Lloyd
2011-Nov-17 17:23 UTC
Re: [Puppet Users] Re: Editing a variable defined in the same scope
Thanks for the feedback. I do see the same behavior and I no longer need to do this but I am confused by your suggestion to not use += even though it''s a valid Puppet capability. My simplified example was actually based on a parameterized activemq class. In my MCollective server''s node definition I''d have class { "activemq": application => "mcollective" } while in another regex-based node definition, based on requirements of a team I help support (called Transform for short), I''d have class { "activemq": application => "transform" } Then in the activemq class I wanted to specify the list of packages to install for activemq, leaving out the java package since the Transform systems would already have java installed separately. Hence I''d have a single list of packages with a += if $application == "transform". The +was to avoid repetition of package names. You mention hacking something together with inline_template and split (which I''ve used in other situations), but I was shooting for a more elegant solution. Justin On Wed, Nov 16, 2011 at 6:22 AM, jcbollinger <John.Bollinger@stjude.org>wrote:> > > On Nov 15, 3:42 pm, Justin Lloyd <jstn...@gmail.com> wrote: > > I tried the following (names changed to protect the innocent and guilty): > > > > class myclass ( $param ) { > > > > $myvar = [ "foo", "bar" ] > > > > if $param == "special" { > > $myvar += [ "blah" ] > > } > > > > } > > > > and got the message "...Cannot append, variable myvar is defined in this > > scope...". According to the docs, variables cannot be modified in the > same > > scope because of the declarative nature of > > Puppet<http://docs.puppetlabs.com/guides/language_guide.html> > > . > > > > However, if I change the plus-signment statment to > > > > $myclass::myvar += [ "blah" ] > > > > it works fine. Can someone explain this aspect of scoping? (Or is this > > possibly a bug...?) > > > Do check whether you are seeing the behavior Christopher reports. > > It is a Puppet axiom that you cannot modify the value of any variable > once it is set. Even += doesn''t really do that: that''s why the > appended values are not seen outside the scope where the += is > performed. > > I recommend you just come up with another way to do what you want. In > fact, I recommend you avoid += even in situations where it works. > Here''s one way: > > class myclass ( $param ) { > if $param == "special" { > $myvar = [ "foo", "bar", "blah" ] > } else { > $myvar = [ "foo", "bar" ] > } > } > > There are also a couple of ways you could concatenate arrays in > Puppet. If you want to do that a lot then I''d write a custom > function, but for the odd one-off you could hack together something > using inline_template() and split(). > > > John > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Users" group. > To post to this group, send email to puppet-users@googlegroups.com. > To unsubscribe from this group, send email to > puppet-users+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/puppet-users?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Nov-17 22:41 UTC
[Puppet Users] Re: Editing a variable defined in the same scope
On Nov 17, 11:23 am, Justin Lloyd <jstn...@gmail.com> wrote:> Thanks for the feedback. I do see the same behavior and I no longer need to > do this but I am confused by your suggestion to not use += even though it''s > a valid Puppet capability.The C language has a standard feature referred to as ''trigraphs''. I have never heard any commentary about it that did not one way or another recommend avoiding it. And most people do. Similarly, the fact that Puppet supports += does not imply that it''s a good idea to use it. I recommend against it because it has a fairly high likelihood of misleading you about what it''s actually doing. Even once you master it, the same still applies to anyone else who needs to work on your manifests in the future.> My simplified example was actually based on a parameterized activemq class. > In my MCollective server''s node definition I''d have > > class { "activemq": application => "mcollective" } > > while in another regex-based node definition, based on requirements of a > team I help support (called Transform for short), I''d have > > class { "activemq": application => "transform" } > > Then in the activemq class I wanted to specify the list of packages to > install for activemq, leaving out the java package since the Transform > systems would already have java installed separately. Hence I''d have a > single list of packages with a += if $application == "transform". The +> was to avoid repetition of package names. You mention hacking something > together with inline_template and split (which I''ve used in other > situations), but I was shooting for a more elegant solution.I also suggested writing an array concatenation custom function. I''d consider that more elegant than hacking up an array concatenation via inline_template() and split(), not least because it would be reusable. Or you could just specify the complete list of packages for each case, and assign one or the other via an appropriate conditional. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.