Apparently cannot call function within Apply For-rule

What is wrong with this code? I am observing an error “Invalid field access (for value of type ‘Service’): ‘listen’” at the point where I’d expect my function listen() to be called:

function port(s) {
        return s.substr(s.len() - s.reverse().find(":"))
}
function listen(s) {
        return s.substr(0, s.len() - s.reverse().find(":") - 1)
}
apply Service "https6" for (http in host.vars.https6) {
  vars.http_address = listen(http)
  vars.http_port = port(http)
  # ...
  assign where host.vars.https6 && host.zone == "master"
}

UPDATE I am getting one step further when surrounding the expressions with two curly braces, however now a new error appears as “Argument is not a callable object”. My functions listen() and port are by now defined in a global zone.

The code as shown above is probably missing use(port,listen) between https6) and {. Or between "https6" and for, I’m not sure.

I’ve tried it, but nops, this apparently does not work. The Language Reference shows examples where use() appears inside a lambda expression or a function definition only, and both seem different from the context at hand.

Ah! Then you need also to change:

function port(s) {

to

var port = function(s) {

Same for listen.

I’ve meanwhile found that things apparently work fine if I place the function definitions inside a namespace (e.g. util) like so:

namespace util {
        function port(s) {
                return s.substr(s.len() - s.reverse().find(":"))
        }
        function listen(s) {
                return s.substr(0, s.len() - s.reverse().find(":") - 1)
        }
}
apply Service "https6" for (http in host.vars.https6) {
  vars.http_address = util.listen(http)
  vars.http_port = util.port(http)
  # ...
  assign where host.vars.https6 && host.zone == "master"
}
1 Like