2017-09-07 1 views
2

Elixir la langue elle-même a le module suivant avec des méthodes telles que:Comment puis-je "injecter" de nouvelles fonctions dans un module existant dans le langage Elixir lui-même?

defmodule Calendar.ISO do 
    @spec leap_year?(year) :: boolean() 
    @impl true 
    def leap_year?(year) when is_integer(year) and year >= 0 do 
    rem(year, 4) === 0 and (rem(year, 100) > 0 or rem(year, 400) === 0) 
    end 
end 

Disons que je vous écris mon propre module dans mon propre jouet d'application Elixir/Phoenix et je décide que je voulais ajouter une autre méthode Calendar.ISO appelé "frog_day" qui renvoie la chaîne "frog". Évidemment, je ne veux pas faire un PR pour "frog_day" dans le référentiel du langage Elixir.

Comment est-ce que je pourrais injecter ceci dans le module Calendar.ISO pour l'utiliser dans mon app jouet? Ou est-ce même possible?

Note: Je me rends compte que cela peut sembler être un "patch de singe" mais j'ai un cas d'utilisation spécifique pour cela.

+0

Vous aurez besoin de créer un nouveau module (ie MyCalendar) qui étend Calendar.ISO. Jetez un oeil à [cette question] (https://stackoverflow.com/questions/35302208/how-do-you-extend-inherit-an-elixir-module) qui je pense est proche de ce que vous cherchez. – matov

+0

Le correctif de singe est explicitement interdit dans Elixir. –

Répondre

3

Vous ne le faites pas.

Hacks avec expand comme indiqué dans la réponse liée par @matov devrait doit être évitée (surtout pris en compte, que la réponse liée ne fait pas ce que vous voulez.) Polymorphisme dans Elixir est fait avec Protocols et/ou Behaviours. Dans votre cas, vous n'avez pas besoin polymorphisme soit, juste mettre en œuvre votre propre aide comme:

defmodule Extensions.Calendar.ISO do 
    def frog_day?(day), do: "frog" 
end 

et vous êtes tous ensemble. Il est pas un seul avantage pour essayer même de mettre la méthode dans un module étranger (et vous ne pouvez pas en premier lieu puisque le module est déjà compilé pour le moment.)