在Elixir中,有没有一种方法可以获取模块的函数列表?

73
与我们可以让 Ruby 中的任何对象(或类)列出其方法一样,是否有任何函数在 Elixir 中列出属于模块的所有函数?是否有像 String.functions 这样的东西(其中 String 可以替换为任何其他模块名称)?
4个回答

105

每个 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]

5
更新:我改变了我的答案,使用:functions代替:exports。两者都可以工作,但根据文档,:functions看起来是最好的选择。 - Steven Schobert
有没有一种方法可以按照模块中定义的顺序获取它?现在它是按字母顺序排序的。 - Phillipp

43

由于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函数。


17

我一直在使用iex(1)> exports TargetModuleName。它可以列出属于一个模块的所有函数和宏。我是因为想弄清如何防止 Map.__info__(:functions) 截断长函数列表而偶然发现了它。


1
是的,在iex中有相当多的新的longword命令,这些命令在单个字符命令的默认列表中不会显示出来。如果您已经有一段时间没有使用过iex,请花点时间查看帮助文档,这非常值得一试。 - Fred the Magic Wonder Dog

3

不是一个函数,而是一种让模块在 iex 中列出其函数的方法,只需写下模块名称,然后加上 .,再按下 Tab 键:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接