custom function, setvar and variable scoping

308 views
Skip to first unread message

Jérôme Loyet

unread,
Sep 29, 2012, 9:10:43 AM9/29/12
to puppet...@googlegroups.com
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

jcbollinger

unread,
Oct 1, 2012, 9:25:24 AM10/1/12
to puppet...@googlegroups.com

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

Reply all
Reply to author
Forward
0 new messages