Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call an anonymous function with a local variable as parameter

I have a function that creates an object (in this case, a Hammerspoon Notify object), and I would like to pass this object as the parameter to an anonymous function that is itself an argument to a function call.

That's a very convoluted explanation, but I think an example makes it pretty clear.

function main()
    local n = hs.notify(...)
    print(n)          -- `hs.notify: Title (0x7fbd2b5318f8)`
    hs.timer.doAfter(1, function(n)
        print(n)      -- nil
        n:withdraw()  -- error: attempt to index a nil value (local 'n')
    end)
end

The output of this is that n prints fine the first time (hs.notify: Title (0x7fbd2b5318f8)), but is nil the second time, inside the anonymous function, and it throws an error: attempt to index a nil value (local 'n').

This sort of makes sense, because I'm never really passing it in. Is there a way to pass it in? The signature of the hs.timer.doAfter call is: hs.timer.doAfter(sec, fn) -> timer (http://www.hammerspoon.org/docs/hs.timer.html#doAfter)

like image 311
Mikayla Avatar asked Jul 16 '16 02:07

Mikayla


People also ask

Can anonymous function be passed as a parameter?

An anonymous function is a function with no name which can be used once they're created. The anonymous function can be used in passing as a parameter to another function or in the immediate execution of a function.

Can an anonymous function be assigned to a variable?

An anonymous function in javascript is not accessible after its initial creation. Therefore, we need to assign it to a variable, so that we can use its value later. They are always invoked (called) using the variable name. Also, we create anonymous functions in JavaScript, where we want to use functions as values.

How do you use variables in anonymous functions?

$var=function ($arg1, $arg2) { return $val; }; There is no function name between the function keyword and the opening parenthesis. There is a semicolon after the function definition because anonymous function definitions are expressions. Function is assigned to a variable, and called later using the variable's name.


1 Answers

The definition of the anonymous function includes the declaration of an argument named n, which hides the n variable from the outer scope. The function declaration is creating a new local variable that is nil unless an argument is actually passed into the function, but the timer function that calls your anonymous function isn't expecting to pass anything in, so the function-local n stays nil.

You can fix it by simply removing the argument declaration from the anonymous function, but keep the usage of n within the function. Then it will capture the n variable from the outer scope, which has the value returned from hs.notify(...).

function main()
    local n = hs.notify(...)
    print(n)          -- `hs.notify: Title (0x7fbd2b5318f8)`
    hs.timer.doAfter(1, function() -- <== no argument
        print(n)      -- nil
        n:withdraw()  -- error: attempt to index a nil value (local 'n')
    end)
end
like image 162
Kurt Hutchinson Avatar answered Oct 07 '22 13:10

Kurt Hutchinson