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)
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.
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.
$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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With