gpt4 book ai didi

elixir - 如何在宏创建的方法中创建数组的未绑定(bind)变量部分(方法参数)

转载 作者:行者123 更新时间:2023-12-02 11:40:55 25 4
gpt4 key购买 nike

在phoenix应用程序中,我正在尝试像这样实现授权

#= Bouncers.Bouncer.check_entry(conn, %MyApp.User{})
#=> true

defmodule Bouncers.Bouncer do
alias Bouncers.Areas

def check_entry(conn, resource) do
verify(resource, conn.path_info)
end

defp verify(resource, path) do
try do
Areas.verify(resource, path)
rescue
_ -> false
end
end

end

defmodule Bouncers.Doors do

defmacro bouncer_for(model, allowed_routes) do
for route <- allowed_routes do
quote bind_quoted: [route: route, resource: model] do
def verify(resource, route), do: true
end
end
end
end

defmodule Bouncers.Areas do
require Bouncers.Doors
import Bouncers.Doors

bouncer_for %MyApp.User{}, [
["api", "users"]
]
end

bouncer_for 为 Struct 和 path_info 数组创建多个 verify 方法

bouncer_for %MyApp.User{},  [
["api", "users"],
["api", "posts"]
]

将创建

def verify(%MyApp.User{}, ["api", "users"], do: true
def verify(%MyApp.User{}, ["api", "posts"], do: true

它适用于这些路径,但我被困在格式为["api", "users", _ ]的路径上,这会抛出一个关于未绑定(bind)变量的错误。我至少想要这样的东西,

bouncer_for %MyApp.User{},  [
["api", "users", "*"],
]

并将宏生成的方法的参数中的"*"替换为_。有什么指点吗?

最佳答案

您需要像这样定义宏:

defmodule Bouncers.Doors do
defmacro bouncer_for(model, allowed_routes) do
for route <- allowed_routes do
quote do
def verify(unquote(model), unquote(route)), do: true
end
end
end
end

然后它应该按预期工作。

原因是 bind_quoted 将尝试将绑定(bind)(即实际值)传递给宏,但是 ["api", "users", _] 本身不是有效值。它更像是一种模式,您可以使用 unquote 将其嵌入到动态生成的函数定义中。这就像您直接在定义中编写模式一样。为了说明这个问题,下面是一些大致相当于宏生成的定义的代码:

# using bind_quoted
@route ["api", "users", _] # invalid value, raises error
def verify(%MyApp.User{}, @route), do: true

# using unquote
def verify(%MyApp.User{}, ["api", "users", _]), do: true

关于elixir - 如何在宏创建的方法中创建数组的未绑定(bind)变量部分(方法参数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33820580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com