Jérôme Loyet
2012-Sep-29 13:10 UTC
[Puppet Users] custom function, setvar and variable scoping
Hello, I''m trying to make a set of functions to simulate an array with which I would be able to append value in the same scope. The first function is called "array_append" which take 2 arguments: the variable name and the value to append. The function then iterates through variables "#{name}_#{i}" (with incrementing i from 0) until the variable does not exists and then set the value of this variable. This way I''m using one variable for each element of my array and I can simulate a real array from the puppet DSL. Here''s the function I''ve made: module Puppet::Parser::Functions newfunction(:array_append) do |args| i = 0 i += 1 while lookupvar("#{args[0]}_#{i}") puts "I''ve set #{args[0]}_#{i} to #{args[1]}" setvar("#{args[0]}_#{i}", args[1]) end end If I''m calling this function from a manifest it works as expected: test.pp array_append("toto", "prout0") array_append("toto", "prout1") array_append("toto", "prout2") #puppet agent test.pp I''ve set toto_0 to prout0 I''ve set toto_1 to prout1 I''ve set toto_2 to prout2 Finished catalog run in 0.02 seconds But if I want to set a global variable it does not work anymore and I''ve errors. It seams that test2.pp: array_append("::toto", "prout0") array_append("::toto", "prout1") array_append("::toto", "prout2") #puppet agent test2.pp I''ve set ::toto_0 to prout0 I''ve set ::toto_0 to prout1 Error: Cannot reassign variable ::toto_0 at /root/puppet/manifests/test.pp:9 on node www1.egasys.com Error: Cannot reassign variable ::toto_0 at /root/puppet/manifests/test.pp:9 on node www1.egasys.com Then if I''m calling array_append from a module defined resource: test3.pp network::route::add_net {"42.42.42.0/24": gw => "192.168.0.1"} network::route::add_net {"54.54.54.0/24": gw => "192.168.0.1"} modules/network/manifests/route/add_net.pp define network::route::add_net($gw) { array_append("::routes_net", {name => $name, gw => $gw}) } #puppet agent test3.pp I''ve set ::routes_net_0 to name42.42.42.0/24gw192.168.0.1 I''ve set ::routes_net_0 to name54.54.54.0/24gw192.168.0.1 this time: no errors but setvar is not working: it''s like setvar does nothing I can''t understand why case #2 and #3 are not working and if it''s a normal behaviour or a bug. if you have any ideas ? thx for your help ++ Jerome -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/A1UbbmkIMyQJ. 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
2012-Oct-01 13:25 UTC
[Puppet Users] Re: custom function, setvar and variable scoping
On Saturday, September 29, 2012 8:10:43 AM UTC-5, Jérôme Loyet wrote:> > Hello, > > I''m trying to make a set of functions to simulate an array with which I > would be able to append value in the same scope. > > The first function is called "array_append" which take 2 arguments: the > variable name and the value to append. The function then iterates through > variables "#{name}_#{i}" (with incrementing i from 0) until the variable > does not exists and then set the value of this variable. This way I''m using > one variable for each element of my array and I can simulate a real array > from the puppet DSL. > > Here''s the function I''ve made: > > module Puppet::Parser::Functions > newfunction(:array_append) do |args| > i = 0 > i += 1 while lookupvar("#{args[0]}_#{i}") > puts "I''ve set #{args[0]}_#{i} to #{args[1]}" > setvar("#{args[0]}_#{i}", args[1]) > end > end > > > If I''m calling this function from a manifest it works as expected: > test.pp > > array_append("toto", "prout0") > array_append("toto", "prout1") > array_append("toto", "prout2") > > > #puppet agent test.pp > > I''ve set toto_0 to prout0 > I''ve set toto_1 to prout1 > I''ve set toto_2 to prout2 > Finished catalog run in 0.02 seconds > > > But if I want to set a global variable it does not work anymore and I''ve > errors. It seams that > > test2.pp: > > array_append("::toto", "prout0") > array_append("::toto", "prout1") > array_append("::toto", "prout2") > > > #puppet agent test2.pp > > I''ve set ::toto_0 to prout0 > I''ve set ::toto_0 to prout1 > Error: Cannot reassign variable ::toto_0 at > /root/puppet/manifests/test.pp:9 on node www1.egasys.com > Error: Cannot reassign variable ::toto_0 at > /root/puppet/manifests/test.pp:9 on node www1.egasys.com > > > Then if I''m calling array_append from a module defined resource: > > test3.pp > > network::route::add_net {"42.42.42.0/24": gw => "192.168.0.1"} > network::route::add_net {"54.54.54.0/24": gw => "192.168.0.1"} > > > modules/network/manifests/route/add_net.pp > > define network::route::add_net($gw) { > array_append("::routes_net", {name => $name, gw => $gw}) > } > > > #puppet agent test3.pp > I''ve set ::routes_net_0 to name42.42.42.0/24gw192.168.0.1 > I''ve set ::routes_net_0 to name54.54.54.0/24gw192.168.0.1 > > this time: no errors but setvar is not working: it''s like setvar does > nothing > > I can''t understand why case #2 and #3 are not working and if it''s a normal > behaviour or a bug. > > if you have any ideas ? > >My guess would be that setvar() is attempting to use the full string you supplied as a simple variable name, instead of resolving it as a qualified name. That would make sense because setvar() probably itself resolves to or wraps scope.setvar(), where ''scope'' is the scope object representing the current namespace scope. It may be possible to find and use the scope object for the scope you want, but it would be all-around better to avoid attempting to modify a different scope than the one in which the function call appears. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/pPO5OOihX90J. 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.