簡體   English   中英

如何使用Elixir宏獲取模塊的完整生成代碼

[英]How to get the full generated code of a module using Elixir macros

以下是Phoenix應用程序示例的路由器模塊。 我想宏注入函數看到模塊的完整代碼。

我嘗試過像Macro.to_string (Macro.expand (Code.string_to_quoted! File.read!("web/router.ex")), __ENV__)但它沒有完全擴展宏。 我怎么能遞歸擴展每個宏,即pipelineplugscopepipe_throughget

謝謝

defmodule HelloPhoenix.Router do
  use HelloPhoenix.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
  end

end

正如您已經正確觀察到的那樣,您需要遞歸地使用Macro.expand/1來真正擴展所有宏級別。 有一個內置的工具來實現這個目標: Macro.prewalk/2 這應該讓你開始:

ast
|> Macro.prewalk(&Macro.expand(&1, __ENV__))
|> Macro.to_string
|> IO.puts

這段代碼會將一個波束文件反編譯回erlang。 我沒有針對基於插件的模塊運行它,所以我不知道結果會有多糟糕,但這會給你任何模塊的最終結果。

  def disassemble(beam_file) do
    beam_file = String.to_char_list(beam_file)
    {:ok,
      {_, [{:abstract_code, {_, ac}}]}} = :beam_lib.chunks(beam_file,
                                                           [:abstract_code])
    :io.fwrite('~s~n', [:erl_prettypr.format(:erl_syntax.form_list(ac))])
  end

原始來源,以及更多信息: http//erlang.org/doc/man/beam_lib.html

請注意,此方法采用[module] .beam的文件路徑

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM