Eixir元编程

编程入门 行业动态 更新时间:2024-10-05 09:33:21
Eixir元编程 - 在宏编译时定义编译时可用的宏(Eixir metaprogramming - defining macro available at compile time from within macro)

我正在研究Elixir元编程,我正在制作一个允许我定义REST资源的macro 。 界面如下:

defmodule Router do use Resources resource "cars" resource "animals" end

我使用Module模块定义了一个模块属性,但我无法使用以下代码:

defmodule Resource do defmacro __using__(_opts) do quote do Module.put_attribute __MODULE__, :stack, [1, 2, 3] defmacro resource(name) do stack = Module.get_attribute __MODULE__, :stack Module.put_attribute __MODULE__, :stack, [name|stack] end end end end

以下内容无法编译:

defmodule Domain do use Resource resource "foo" def run do IO.inspect @stack end end

如果我删除资源行,它会正确打印[1, 2, 3] 。

resource/1宏在run/0可见。

我怎样才能让Router中的代码工作,以便调用资源“xxx”将“xxx”推送到@stack模块属性的堆栈?

I am studying Elixir metaprogramming and I am toying around with making a macro that allows me to define REST resources. The interface would be like this:

defmodule Router do use Resources resource "cars" resource "animals" end

I got as far as defining a module attribute using the Module module, but I can't get the following to work:

defmodule Resource do defmacro __using__(_opts) do quote do Module.put_attribute __MODULE__, :stack, [1, 2, 3] defmacro resource(name) do stack = Module.get_attribute __MODULE__, :stack Module.put_attribute __MODULE__, :stack, [name|stack] end end end end

The following does not compile:

defmodule Domain do use Resource resource "foo" def run do IO.inspect @stack end end

If I remove the resource line, it prints [1, 2, 3] correctly.

The resource/1 macro is visible from run/0.

How could I get the code in Router to work, so that calling resource "xxx" pushes "xxx" to the stack on the @stack module attribute?

最满意答案

您需要单独定义第二个Macro ,而不是在__using__宏中。 您可以使用第一个宏import Resource并定义初始@stack ,这样您就可以在Module中使用resource宏。

您也不需要调用Module.get_attribute和Module.put_attribute ,只需在任何地方使用@stack 。

尝试这个:

defmodule Resource do defmacro __using__(_opts) do quote do import Resource @stack [1,2,3] end end defmacro resource(name) do quote do @stack [unquote(name) | @stack] end end end

调用Domain.run现在应该给你["foo", 1, 2, 3] 。 您还应该阅读有关在Elixir中构建自己的域特定语言的官方指南。

You need to define the second Macro separately, not within the __using__ macro. You can use the first macro to import Resource and define the initial @stack, so you can then use the resource macro in your Module.

You also don't need to call Module.get_attribute and Module.put_attribute, and just use @stack everywhere.

Try this:

defmodule Resource do defmacro __using__(_opts) do quote do import Resource @stack [1,2,3] end end defmacro resource(name) do quote do @stack [unquote(name) | @stack] end end end

Calling Domain.run should now give you ["foo", 1, 2, 3]. You should also go over the Official guide on building your own Domain Specific Languages in Elixir.

更多推荐

本文发布于:2023-08-07 12:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1464081.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Eixir

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!