defstruct in a dynamically named module?

143 views
Skip to first unread message

Ian Duggan

unread,
Jun 22, 2016, 7:17:07 PM6/22/16
to elixir-lang-talk

Is there some technique for making the code below work?


--Ian



defmodule Module.concat(["Foo"]) do

  defstruct name: nil, age: 5


  def whostruct do

    %__MODULE__{}

  end

end



** (CompileError) tmp/src.exs:5: Foo.__struct__/0 is undefined, cannot expand struct Foo

    (elixir) src/elixir_map.erl:44: :elixir_map.translate_struct/4

    (elixir) src/elixir_clauses.erl:36: :elixir_clauses.clause/7

    (elixir) src/elixir_def.erl:195: :elixir_def.translate_clause/7

    (elixir) src/elixir_def.erl:184: :elixir_def.translate_definition/8

    (elixir) src/elixir_def.erl:95: :elixir_def.store_definition/9

    (elixir) src/elixir.erl:175: :elixir.erl_eval/3

John W Higgins

unread,
Jun 22, 2016, 8:21:21 PM6/22/16
to elixir-l...@googlegroups.com
I would suggest two things.

First, I believe the short option would be

def whostruct do
  struct(__MODULE__)
end

But I would strongly suggest you look at creating a macro here to build your module - that's sort of the standard "build it dynamically" concept

Something like this

defmodule ModuleBuilder do
  defmacro build_module(mod_name) do
    quote do
      defmodule unquote(mod_name) do

        defstruct name: nil, age: 5

        def whostruct do
          struct(__MODULE__)
        end
      end
    end
  end
end

defmodule Foo do
  require ModuleBuilder

  ModuleBuilder.build_module(Module.concat([__MODULE__, "Bar"]))
end


Would appear to be a much better choice in my opinion.

The above would end up with a Foo.Bar module that can be called as in Foo.Bar.whostruct

John

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/2b3d073f-7a12-4b93-8db5-35ca1f241340%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

José Valim

unread,
Jun 23, 2016, 1:42:23 AM6/23/16
to elixir-l...@googlegroups.com

But I would strongly suggest you look at creating a macro here to build your module - that's sort of the standard "build it dynamically" concept


What would the macro buy us though? The code posted is supposed to work fine. I just need to investigate why it doesn't.


--


José Valim
Skype: jv.ptec
Founder and Director of R&D

José Valim

unread,
Jun 23, 2016, 4:19:13 AM6/23/16
to elixir-l...@googlegroups.com
Hi Ian, indeed this does looks like a bug. can you please file a report in our issues tracker? Thank you!



José Valim
Skype: jv.ptec
Founder and Director of R&D

--

Ian Duggan

unread,
Jun 23, 2016, 8:41:37 AM6/23/16
to elixir-lang-talk, jose....@plataformatec.com.br
Sure thing. FWIW, it seems like it *might* work for compiled files but not from iex. (1.2.5 and 1.3.0). I will investigate a bit when I file the bug today.

--Ian
Reply all
Reply to author
Forward
0 new messages