Sorry I screwed up copying Example 1. The internal stuct, Embed, should not have been prepended with Demo. The error message reflects the error for the correct code but my cut & paste of the example afterwards forgot to cut it off. On Jul 16, 2016 9:58 PM, "Peter Hamilton" <[email protected]> wrote:
> Nesting defmodule inside another defmodule prepends the outer module. So > in the first example you actually defined Demo.Demo.Embed, and that's why > it couldn't find Demo.Embed. > > On Sat, Jul 16, 2016, 9:59 AM Benjamin Scherrey <[email protected]> > wrote: > >> I believe the following code examples are all identically equivalent. >> I don't see a place in the spec that would cause me to think that any >> of these code examples would fail to compile yet the first two fail >> and the last two work. I would also suggest that the first two >> (especially the first) are far better in terms of being able to reason >> about one's code because it doesn't require one to put a small >> submodule/structure which is only meant to be meaningful in the >> context of the parent module/structure into an independent file or >> define it prior to its parent owning module. I know that modules are >> technically flat (which is why v4 works) and that we're really just >> talking about something that kinda resembles a namespace but it >> doesn't change my impression that these are still equivalent code. >> >> Can anyone tell me where in the language specification would make me >> understand why these first two fail? >> Also, is there any reason we can't support the first version of this code? >> >> Version 1: >> file demo.ex >> defmodule Demo do >> >> defmodule Demo.Embed do >> defstruct local: 0 >> end >> >> defstruct name: "", embed: %Embed{} >> end >> >> scherrey@(none) ~/develop/elixir/demo $ mix compile >> >> == Compilation error on file lib/demo.ex == >> ** (CompileError) lib/demo.ex:7: cannot access struct Demo.Embed, the >> struct was not yet defined or the struct is being accessed in the same >> context that defines it >> (elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4 >> (stdlib) lists.erl:1353: :lists.mapfoldl/3 >> (stdlib) lists.erl:1354: :lists.mapfoldl/3 >> >> This: "the struct is being accessed in the same context that defines >> it" is a pretty big hint but I disagree with it. By time line 7 is >> being compiled the Embed struct is already fully defined. >> >> Version 2: >> file demo.ex >> defmodule Demo do >> >> alias Demo.Embed >> >> defstruct name: "", embed: %Embed{} >> end >> >> >> defmodule Demo.Embed do >> defstruct local: 0 >> end >> >> scherrey@(none) ~/develop/elixir/demo $ mix compile >> >> == Compilation error on file lib/demo.ex == >> ** (CompileError) lib/demo.ex:5: Demo.Embed.__struct__/0 is undefined, >> cannot expand struct Demo.Embed >> (elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4 >> (stdlib) lists.erl:1353: :lists.mapfoldl/3 >> (stdlib) lists.erl:1354: :lists.mapfoldl/3 >> >> Version 3: >> file demo.ex >> defmodule Demo do >> >> alias Demo.Embed >> >> defstruct name: "", embed: %Embed{} >> end >> >> file embed.ex >> defmodule Demo.Embed do >> defstruct local: 0 >> end >> >> This compiles and works. >> >> Version 4: >> file demo.ex >> defmodule Demo.Embed do >> defstruct local: 0 >> end >> >> defmodule Demo do >> >> alias Demo.Embed >> >> defstruct name: "", embed: %Embed{} >> end >> >> This compiles and works. >> >> I find this quite counter intuitive. Am I missing something obvious? >> >> thanx, >> >> -- Ben Scherrey >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/CACo3ShgwQ5V1bkRQ7_C4A5Kc7y2OGONE%2Bs6wVh7no1rhwzDn3A%40mail.gmail.com >> . >> For more options, visit https://groups.google.com/d/optout. >> > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/CAOMhEnwbM%3DfeN%2BWndyOUnXCO0VToG_uMKnjL-N7tQKPvjzjUDg%40mail.gmail.com > <https://groups.google.com/d/msgid/elixir-lang-core/CAOMhEnwbM%3DfeN%2BWndyOUnXCO0VToG_uMKnjL-N7tQKPvjzjUDg%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CACo3Shhjn4PG25S3u9XpmV0D4s1uqi8qO25EKfoRN-gHDGbxqQ%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
