Wrap elixir module

impl elixir
elixir list length
elixir map
elixir append to list
map module elixir
elixir list, index
elixir tuple
elixir list to string

If you have a module, for instance

defmodule Foo do
    # lots of "unknown" functions
end

How can I create a wrapper-module for that Foo, like:

defmodule Bar do
    # wrap all functions in Foo
end

But in Bar I want to expose all functions in Foo, but additionally I want to add some code in each function, specifically I want to try/catch a specific error that can show up in any Foo.Error exception... I'd like to do this without adding a function for each function in Foo, since that will get repetetive.

Can I do this with macros?

AFAIU you want to perform some kind of object-oriented programming by replicating the logic of inheritance between classes. But this is not the philosophy of any functional programming language like Elixir as you probably already know.

However, If this is really what you want to do, I found this question that uses metaprogramming and aim at doing something similar to what you are looking for. It looks complicated though.

Edit : After we had some further talk I understand your problem better. If you want to define function without too much repetition then metaprogramming is the way to go ! Here is a simple example on how to define several functions in a module thanks to metaprogramming :

defmodule MyModule do
  Enum.each ~w(method1 method2), fn(method_name) ->
    def unquote(:"#{method_name}")(), do: unquote(method_name)
  end
end

I'd like to do this without adding a function for each function in Foo, since that will get repetetive.

I think that's what I would do, but are you sure it would be that repetitive ?

Also you can also use the Exceptional lib that will help you write less error-handling functions :)

Metaprogramming to create a wrapping/delegating module , I want to use metaprogramming to "wrap" another module's functions. For example: defmodule Foo do def one(x) do end def two(x, y) do� Note − In Elixir, there is no need to define the Foo module in order to define the Foo.Bar module, as the language translates all module names to atoms. You can define arbitrarilynested modules without defining any module in the chain. For example, you can define Foo.Bar.Baz without defining Foo or Foo.Bar.

This is a good use of defmacro, but definitely look into defedelegate as well. It lets you add(delegate) named references to functions in other/external modules.

Module — Elixir v1.11.0-dev, Elixir v1.11.0-dev Module behaviour View Source. Provides functions to deal with modules during compilation time. It allows a developer to dynamically add,� Elixir module - A "thick" wrapper for Erlang's rand module (replacing random) - Hal9000/elixir_random

With magic of metaprogramming everything is possible (however not always this makes sense):

defmodule Bar do
  Code.ensure_compiled(Foo)

  for {func, arity} <- Foo.__info__(:functions) do
    args = Macro.generate_arguments(arity, __MODULE__)

    def unquote(func)(unquote_splicing(args)) do
      Foo.unquote(func)(unquote_splicing(args))
    rescue
      Foo.Error -> handle_error()
    end
  end
end

However this will not work for macros.

List — Elixir v1.10.4, Lists in Elixir are effectively linked lists, which means they are internally represented in Most of the functions in this module work in linear time. wrap( term). This is an address validation module, which just validates that a certain address has less than 32 characters. Also, let’s say that the validatefunction emits an event (our side-effect).This

optional dependencies: `Code.ensure_loaded?/1` wrapping `use , Environment Elixir & Erlang/OTP versions (elixir --version): 1.8.1 Operating defmodule UseInEnsureLoaded do if Code.ensure_loaded? elixir documentation: Using modules. Example. Modules have four associated keywords to make using them in other modules: alias, import, use, and require. alias will register a module under a different (usually shorter) name:

marcelog/jsonex: An elixir module to wrap jsonerl, Jsonex. An elixir module to wrap jsx. See expm homepage for jsonex. Use example. Encoding. View all of README.md. Releases. 2.0 published over 7 years� The architecture of Mint lends itself to being extensible and enables other library authors to wrap Mint however they see fit. This is where Finch comes in. Finch is a library that wraps Mint and provides many of the HTTP client features that you would expect from a fully-fledged HTTP client.

Erlang libraries, module; The rand module; The zip and zlib modules. Elixir provides excellent interoperability with Erlang libraries. In fact, Elixir discourages simply wrapping� Elixir Industrial Equipment, Inc. has been supplying the industries leaders of world-class manufacturing equipment to support the needs of manufacturers and businesses in the Philippines. With branches in Mandaue City, Cebu and Sta. Rosa, Laguna, we supply, install, and service a range of industrial equipment, including inspection, processing

Comments
  • there are several ways to do this and all involve macros. Either implement defmacro __using__() in Foo and then add use Foo in Bar, or create inline code in Bar module that should read Foo.__info__(:functions) and "redefine" all in Bar. Question is do you really need this? it smells like bad decision and documenting inherited functions may be a tricky.
  • on the other hand, there are many examples of similar thing when developers conditionally speaking "inherit" genserver for instance. This is done with use where macro __using__(..) is executed during compile time, in some cases there is @beforecomple hook which allows "used" module to run its function just before compilation.
  • Rather than being something motivated by a misplaced desire to replicate OOP in Elixir, I interpreted OP's question as closer to wanting to map a higher-order function (one which sends functions to functions with better error-handling) over a module, which seems like a fairly functional thing to do.
  • @JohnColeman I agree ! maybe trying to do metaprogramming to replicate the behaviour of Phoenix's action_fallback (hexdocs.pm/phoenix/Phoenix.Controller.html#action_fallback/1) would help, but this looks very complicated to me, whereas writing a few function that you just call in a line in each function with a pipe operator doesn't sound that repetitive.
  • I know the philosophy isn't to use try/catch in that way, but I still want to catch a certain error that show up in any of the functions within a 3rd party module I'm wrapping
  • @UjCorb the way I solved it it was very repetetive, because in module Bar I had every function from Foo defined, but I was imagining there was a way to solve it using only one function + some macro magic :)
  • Ok :) I added a simple metaprogramming example to define functions in a loop. Maybe you can start from there. Hope it helps !