Nona
Nona

Reputation: 5462

How can I "inject" new functions into an existing module in the Elixir language itself?

Elixir the language itself has the following module with some methods such as:

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

Let's say I'm writing my own module in my own toy Elixir/Phoenix application and I decide I wanted to add another method in Calendar.ISO called "frog_day" which returns the string "frog". Obviously, I don't want to make a PR for "frog_day" into the Elixir language repository.

How would I go about injecting this in the Calendar.ISO module for use in my toy app? Or is this even possible?

Note: I realize this may come across as "monkey-patching" but I do have a specific use case for it.

Upvotes: 2

Views: 1387

Answers (1)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

You don’t.

Hacks with expand as shown in the answer linked by @matov should must be avoided (especially taken into account, that the linked answer does not do what you want.) Polymorphism in Elixir is being done with Protocols and/or Behaviours. In your case you don’t need the polymorphism either, just implement your own helper like:

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

and you are all set. There is no one single advantage to even try to put the method inside a foreign module (and you can’t in the first place since the module is already compiled at the moment.)

Upvotes: 6

Related Questions