Compilation error on anonymous function argument with multiple clauses
Dorgan:
Given an extension with these definitions:
@event_handler [
type:
{:spark_function_behaviour, ChannelHandler.Plugs.Handler,
{ChannelHandler.Plugs.Handler.Function, 2}},
required: true
]
@event %Spark.Dsl.Entity{
name: :event,
target: Event,
args: [:name],
describe: """
Handles an event matching exactly `name`.
## Examples
event "create_post" do
handler fn {payload, bindings}, socket ->
# ...
end
end
""",
entities: [plugs: [@plug]],
schema: [
name: [
type: :string,
required: true,
doc: """
The event to match.
"""
],
handler: @event_handler
]
}
And this usage:
handlers do
event "create" do
plug Plugs.CastInput
handler fn
{%{"id" => id}, bindings}, socket ->
{:reply, {:ok, "Dataset #{id} created for karta #{bindings.karta.id}"}, socket}
_, socket ->
{:noreply, socket}
end
end
end
I get this error:
== Compilation error in file lib/channels_web/channels/test_channel/dataset_handler.ex ==
** (ArgumentError) cannot inject attribute @spark_dsl_config into function/macro because cannot escape #Function<6.112779023/2 in :elixir_compiler_2.__MODULE__/1>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
(elixir 1.14.2) lib/kernel.ex:3543: Kernel.do_at/5
(elixir 1.14.2) expanding macro: Kernel.@/1
/home/dorgan/dev/channels/lib/channels_web/channels/test_channel/dataset_handler.ex:1: (file)
(spark 0.3.5) /home/dorgan/dev/channels/lib/channels_web/channels/test_channel/dataset_handler.ex:1: Spark.Dsl.__before_compile__/1
If I remove the second clause to the
fn
in the handler, then it works.
ZachDaniel:
I can already imagine why that’s happening. Will fix it tonight or tomorrow
Dorgan:
enjoy your vacation :)
Dorgan:
I see that in CodeHelpers spark only handles single clause anonymous functions, so it would be a matter of generating more clauses here https://github.com/ash-project/spark/blob/3f84eb5ac97fd61550113d00f126058a5370ad65/lib/spark/code_helpers.ex#L139-L162 I think
ZachDaniel:
Yep, exactly. We’d want to give it a name based on the hash of all clauses though, so that each definition has the same name
ZachDaniel:
It’s probably a pretty simple change all things considered. I can merge a PR if you make one 😀
Dorgan:
I’ll give it a shot!
Dorgan:
It seems we’re already taking an md5 hash of the full quoted expression so I just added more clauses: https://github.com/ash-project/spark/pull/18
ZachDaniel:
Looks perfect!
ZachDaniel:
And maybe not important, but I wouldn’t have expected the “unquote_splicing” to work since it would be putting commas after function defs
ZachDaniel:
Actually, one small thing
ZachDaniel:
Can you loop over the defs and make a list of quoted expressions instead?
ZachDaniel:
Actually, dunno if that will work… I guess yours is tested and works so maybe I’m getting at nothing 😂
Dorgan:
It seems to produce the correct ast:
ZachDaniel:
Let’s go with it then 👍
ZachDaniel:
Merged. Will cut a release later. Thanks for the PR!
Dorgan:
<:KyouAYAYA_MM:628639134008737794>