Reputation: 73
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)
Upvotes: 5
Views: 2502
Reputation: 3069
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
Upvotes: 9