I’m learning Elixir/OTP and am stumped by a certain behaviour. I’m declaring an anonymous function in a module, then when I attempt to call that function from another module, I get an UndefinedFunctionError error. I can alias the anonymous function’s module, but cannot even import the function using the syntax import Module, only: [anon_func]. Please see the code below. What gives?
Module that defines anonymous function: defmodule Servy.PowerNapper do power_nap = fn -> time = :rand.uniform(10_000) :timer.sleep(time) time end end
and the caller module
`
defmodule Servy.PowerNapperClient do
alias Servy.PowerNapper
Nope, that’s not what that does. power_nap is a local variable inside of the do block but it doesn’t stick around after the module is compiled and it isn’t visible outside.
Also, an linguistic nitpick: an “anonymous function” would be a function without a name - but the intent of the code you posted is to name the function PowerNapper.power_nap!
What specifically were you hoping to get with this approach, compared to doing a standard def power_nap do in Servy.PowerNapper?
Related:
defmodule Servy.PowerNapperClient do
alias Servy.PowerNapper
parent = self()
spawn(fn -> send(parent, {:slept, PowerNapper.power_nap.()}) end)
self() here will be the Elixir compiler! The receive will happen while PowerNapperClient is being compiled.
Nope, that’s not what that does. power_nap is a local variable inside of the do block but it doesn’t stick around after the module is compiled and it isn’t visible outside.
Thanks, this clicked! It wasn’t a function definition.
Edit: Yes it was a function definition, assigned to a variable. Kinda like... a closure? I just needed an excuse to flex these newly-acquired triple backticks.
… an “anonymous function” would be a function without a name - but the intent of the code you posted is to name the function…"
Yep, I did think about this! An anon function would not be named. That is indeed a misnomer.
This is sample code from the course I’m taking. Please see the attached screen shot. However, separating the calling code into its own module was my idea.