【问题标题】:In Elixir, is there any way to get a module to list its functions?在 Elixir 中,有没有办法让模块列出其功能?
【发布时间】:2015-04-24 04:56:55
【问题描述】:

就像我们可以在 Ruby 中获取任何对象(或类)来列出其方法一样,Elixir 中是否有任何函数可以列出属于一个模块的所有函数?像String.functions 这样的东西(至少是远程的)(其中String 可以被任何其他模块名称替换)?

【问题讨论】:

    标签: elixir


    【解决方案1】:

    Elixir 中的每个模块都定义了一个 __info__ 函数,您可以调用该函数来获取有关该模块的信息。

    根据Elixir Docs, 1.6.6 e.g.,您可以通过:functions 获取模块包含的函数列表。

    Map.__info__(:functions)
    
    [delete: 2, drop: 2, equal?: 2, fetch: 2, fetch!: 2, from_struct: 1, get: 2,
     get: 3, has_key?: 2, keys: 1, merge: 2, merge: 3, new: 0, pop: 2, pop: 3,
     put: 3, put_new: 3, size: 1, split: 2, take: 2, to_list: 1, update: 4,
     update!: 3, values: 1]
    

    【讨论】:

    • 更新:将我的答案更改为使用:functions 而不是:exports。两者都有效,但根据文档,:functions 看起来是最佳选择。
    • 还有没有办法按照模块中定义的顺序来获取它?它现在按字母顺序排列。
    【解决方案2】:

    由于 Elixir 也是 Erlang,因此也有一种 Erlang 方法可以做到这一点。

    每个 Elixir 和 Erlang 模块都有函数 module_info 在编译时定义 时间。此功能有两个方面。例如:

    iex(1)> Atom.module_info
     [module: Atom,
     exports: [__info__: 1, to_string: 1, to_char_list: 1, module_info: 0,
     module_info: 1], attributes: [vsn:       [66271031909514292894123295368320335064]],
     compile: [options: [:debug_info], version: '6.0.1',
     time: {2015, 9, 29, 2, 34, 37},
     source: '/private/tmp/elixir20150928-10892-fvin6a/elixir-1.1.1/lib/elixir/lib/atom.ex'],
     native: false,
     md5: <<49, 219, 86, 35, 141, 153, 70, 174, 245, 100, 68, 5, 62, 231, 60, 216>>]
    

    您可以指定要返回的特定属性。

     iex(2)> Atom.module_info(:exports)
      [__info__: 1, to_string: 1, to_char_list: 1, module_info: 0, module_info: 1]
    

    Erlang 函数版本:

    iex(3)> :crypto.module_info(:exports)
     [version: 0, stop: 0, supports: 0, info_lib: 0, hash: 2, hash_init: 1,
     hash_update: 2, hash_final: 1, hmac: 3, hmac: 4, hmac_init: 2, hmac_update: 2,
     hmac_final: 1, hmac_final_n: 2, block_encrypt: 4, block_encrypt: 3,
     block_decrypt: 3, next_iv: 2, next_iv: 3, stream_init: 3, stream_init: 2,
     stream_encrypt: 2, stream_decrypt: 2, rand_bytes: 1, strong_rand_bytes: 1,
     rand_bytes: 3, rand_uniform: 2, rand_seed: 1, mod_pow: 3, verify: 5, sign: 4,
     public_encrypt: 4, private_decrypt: 4, private_encrypt: 4, public_decrypt: 4,
     exor: 2, generate_key: 2, generate_key: 3, compute_key: 4, md5: 1, md5_init: 0,
     md5_update: 2, md5_final: 1, md4: 1, md4_init: 0, md4_update: 2, md4_final: 1,
     sha: 1, sha_init: 0, sha_update: 2, ...]
    

    这就是 IEx 自动完成功能使用的功能,它允许您扩展 Elixir 和 Erlang 功能。

    【讨论】:

      【解决方案3】:

      我一直在使用iex(1)&gt; exports TargetModuleName。它列出了属于一个模块的所有函数和宏。我偶然发现它试图弄清楚如何阻止 Map.__info__(:functions) 截断长函数列表。

      【讨论】:

      • 是的,iex 中有很多新的长字命令没有出现在默认的单字符命令列表中。如果您有一段时间没有这样做,值得在 iex 的帮助中四处寻找。
      【解决方案4】:

      不是一个函数,而是一种让模块在iex 中列出其函数的方法是写模块的名称,后跟.,然后点击标签:

      iex(1)> IO.     ## Hit tab
      ANSI                    Stream                  StreamError
      binread/1               binread/2               binstream/2
      binwrite/1              binwrite/2              chardata_to_string/1
      getn/1                  getn/2                  getn/3
      gets/1                  gets/2                  inspect/1
      inspect/2               inspect/3               iodata_length/1
      iodata_to_binary/1      puts/1                  puts/2
      read/1                  read/2                  stream/2
      warn/1                  warn/2                  write/1
      write/2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-14
        • 1970-01-01
        • 2023-03-15
        • 2020-07-29
        • 1970-01-01
        相关资源
        最近更新 更多