web-dev-qa-db-fra.com

Dans Elixir, existe-t-il un moyen d'obtenir un module pour répertorier ses fonctions?

De la même manière que nous pouvons obtenir n'importe quel objet (ou classe) dans Ruby pour lister ses méthodes, y a-t-il une fonction dans Elixir pour lister toutes les fonctions appartenant à un module? Quelque chose (au moins à distance) ) comme String.functions (où String pourrait être remplacé par tout autre nom de module)?

59
iconoclast

Chaque module dans Elixir définit un __info__ fonction que vous pouvez appeler pour obtenir des informations sur ce module.

Selon Elixir Docs, 1.6.6 par exemple , vous pouvez le passer :functions pour obtenir une liste des fonctions que contient le module.

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]
82
Steven Schobert

Comme Elixir est également Erlang, il existe également un moyen Erlang de le faire.

Chaque module Elixir et Erlang a la fonction module_info défini au moment de la compilation. Il existe deux aspects de cette fonction. Par exemple:

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

Vous pouvez spécifier un attribut spécifique à renvoyer.

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

Version de la fonction 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, ...]

C'est ce que la fonction de saisie semi-automatique IEx utilise qui vous permet d'étendre les fonctions Elixir et Erlang.

J'utilise iex(1)> exports TargetModuleName. Il répertorie toutes les fonctions et macros appartenant à un module. Je suis tombé dessus en essayant de comprendre comment empêcher Map.__info__(:functions) de tronquer une longue liste de fonctions.

5
sheepgobeep