【发布时间】:2019-11-03 09:05:38
【问题描述】:
来自this tutorial,我有一些优雅:
get("/old-path", Redirector, to: "/new-path")
get("/old-path/:id", Redirector, to: "/new-path?object=:id")
在我的router.ex.
但我现在有一个更复杂的情况,它要求我的重定向是动态的。我想去:
get("/other-old-path", Redirector, to: fn conn, options -> "/whatever-path" end)
并写在我的Redirector 模块上:
to = if is_function(to), do: to.(conn, Keyword.drop(options, :to)), else: to
我对我的代码很有信心,但是当我尝试执行它时,我收到了以下错误:
== Compilation error in file web/router.ex ==
** (ArgumentError) cannot escape #Function<5.71083082/2 in :elixir_compiler_10.__MODULE__/1>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
(elixir) src/elixir_quote.erl:122: :elixir_quote.argument_error/1
(elixir) src/elixir_quote.erl:259: :elixir_quote.do_quote/3
(elixir) src/elixir_quote.erl:310: :elixir_quote.do_escape/3
(phoenix) lib/phoenix/router/route.ex:136: Phoenix.Router.Route.build_dispatch/1
(phoenix) lib/phoenix/router/route.ex:73: Phoenix.Router.Route.exprs/1
(phoenix) lib/phoenix/router.ex:334: anonymous fn/1 in Phoenix.Router."MACRO-__before_compile__"/2
(elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/enum.ex:1327: Enum."-map/2-lists^map/1-0-"/2
(phoenix) expanding macro: Phoenix.Router.__before_compile__/1
web/router.ex:1: MyApp.Router (module)
(elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
谷歌搜索将我发送到this page,其中提到我无法做我想做的事。我读到这与quoted expressions 有关,所以我试图了解这有什么用,但仍然没有。
我尝试在控制台中函数的参数中的关键字列表中传递匿名函数并且它起作用了。
我猜它在这里中断是因为get 的行为更多的是元。
无论如何,我相信随着 Elixir 的深入工作,我会变得更加自在,总有一天我会清楚地明白为什么它不起作用(当然欢迎解释!),但到那时,我该怎么写我想做的事?
感觉我在做一些灵药难的事情,但显然是……
干杯
编辑:感谢您的回复。
我按照@justin-wood 的建议做了,但没有用:
get("/other-old-path", Redirector, to: &MyApp.Router.do_redirect/2)
在文件的底部
def do_redirect(conn, options), do: "/youpi"
但我得到一个可怕的错误:
== Compilation error in file web/router.ex ==
** (FunctionClauseError) no function clause matching in :v3_core.pattern/2
The following arguments were given to :v3_core.pattern/2:
# 1
{:fun, 0, {:function, {:atom, 0, Vae.Router}, {:atom, 0, :do_redirect}, {:integer, 0, 2}}}
# 2
{:core, 2, 0, {:redirector_path, 2}, ... [more uglyness]
【问题讨论】:
-
** (FunctionClauseError) no function clause matching in :v3_core.pattern/2是一个编译器错误。请打开一个带有最小案例的错误报告,包括 Elixir 和 Erlang/OTP 版本!谢谢。
标签: elixir metaprogramming phoenix-framework