Loop variable not accessible inside object definition

I have an array “a” that I want to loop over and create TimePeriod objects from:

for (s in a) {                                                                                                                                                                            
  object TimePeriod "tp-" + s {
    includes = [ "24x7" ]
    excludes = [ "no-tp" + s ]
                                                                                                                                                                                      
    display_name = "Downtime in " + s
    prefer_includes = false
  }
}

The error I’m getting is this:

critical/config: Error: Error while evaluating expression: Tried to access undefined script variable 's' Location: in timeperiods.conf: 56:34-56:37 timeperiods.conf(54): display_name = "Downtime in " + s timeperiods.conf(55): includes = [ "24x7" ] timeperiods.conf(56): excludes = [ "no-tp-" + s ] ^^^^ timeperiods.conf(57): prefer_includes = false timeperiods.conf(58): }

So “s” is known in the object name but not inside the object definition block. Is this expected? Could I solve it with namespaces somehow?

Hi,

that’s a problem with scopes. The variable s is available in the for loop scope, but not within the object’s scope.

for (s in a) {
  //loop scope

  object TimePeriod "tp-" + s {
    //object scope, does not inherit parent scope
  }
}

In order to solve this, you need to use closures and bind the variable into the current scope.

for (s in a) {                                                                                                                                                                            
  object TimePeriod "tp-" + s use (s) { //after this bracket, the object scope differs from the loop scope
    includes = [ "24x7" ]
    excludes = [ "no-tp" + s ]
                                                                                                                                                                                      
    display_name = "Downtime in " + s
    prefer_includes = false
  }
}

We do that in our example config in the Vagrant boxes too :wink:

Cheers,
Michael

Thanks for your help! It’s working now.