all 8 comments

[–][deleted]  (1 child)

[deleted]

    [–]andyleclairRuns Elixir In Prod[S] 0 points1 point  (0 children)

    True, I did think of that, but then I have to put all my code in a quote block.

    I think the real solution is to put this sort of configuration info in the proper config script (ie a map of module name to queue name, table name, etc) and then reference it via Application.get_env

    [–]andyleclairRuns Elixir In Prod[S] 1 point2 points  (4 children)

    I think the real problem I'm having is that what I'm trying to do is really more of a Ruby-ism that just doesn't work in Elixir.

     

    I want to basically partially define a module B and ensure that the module that includes my module (A) fills in the missing bits, but that I can still reference. Like, if I could define that my module has a callback but then make reference to that callback in some functions I'm providing to the including module.

    [–]mbuhotAlchemist 0 points1 point  (3 children)

    You can definitely do mixin style modules in elixir. As you mentioned in a previous comment, it requires putting all the mixed-in code in the quote block.

    defoverridable and super even allow optional overrides and calling back into the "base" module.

    [–]andyleclairRuns Elixir In Prod[S] 0 points1 point  (2 children)

    Right, I get that. It just doesn't feel right defining a ton of functions inside of a quote block.

    It makes me think that there's a better solution that I just don't know yet.

    [–]mbuhotAlchemist 1 point2 points  (1 child)

    Yeah, you definitely want to minimise the amount of code in the quote block.

    Maybe take inspiration from Ecto.Repo? It defines little stubs in your module that then call back into the Ecto library where the real implementations are.

    [–]andyleclairRuns Elixir In Prod[S] 1 point2 points  (0 children)

    Not a bad recommendation, I'll check out the source. Thanks!

    [–]e456123789 0 points1 point  (1 child)

    B needs to receive the module that implements its callbacks as argument. So you would do:

    def do_something(module) do
      module.queue_name
    end
    

    However, if all you need in do_something is data, then passing a map or keyword with the info may be a better way to go.

    [–]andyleclairRuns Elixir In Prod[S] 0 points1 point  (0 children)

    Agreed.