Thanks for these pieces of wizardry. I had a need for also adding a body to
the module being created. Got it to work based on the code below; sharing
if someone else needs more examples than in the ones Patrick linked to:
julia> function create_module(modname::Symbol)
Expr(:toplevel, :(module ($modname) end))
end
create_module (generic function with 1 method)
julia> add_module(modname::Symbol) = begin
eval(Main, create_module(modname))
eval(Main, modname)
end
add_module (generic function with 1 method)
julia> vm1 = add_module(:MyModule1)
MyModule1
julia> typeof(MyModule1)
Module
julia> eval(MyModule1, quote
function somefunc(); 1; end
end)
somefunc (generic function with 1 method)
julia> eval(vm1, quote
function someotherfunc(); 2; end
end)
someotherfunc (generic function with 1 method)
julia> MyModule1.somefunc()
1
julia> MyModule1.someotherfunc()
2
julia> function add_module(modname::Symbol, body::Expr)
mod = add_module(modname)
eval(mod, body)
mod
end
add_module (generic function with 2 methods)
julia> varmod = add_module(:MyModule2, quote
function somefunc(); 2; end
end)
MyModule2
julia> MyModule2.somefunc()
2
julia> varmod.somefunc()
2
Cheers,
Robert Feldt
Den onsdagen den 29:e januari 2014 kl. 23:48:50 UTC+1 skrev Patrick O'Leary:
>
> Might need some super-secret trickery
>
> https://github.com/JuliaLang/julia/issues/5276
> https://github.com/JuliaLang/julia/issues/1639
>
> On Wednesday, January 29, 2014 4:28:26 PM UTC-6, Mauro wrote:
>>
>> Good catch! But a quote-block and :() should be equivalent, right? Is
>> this a bug?
>>
>> The trouble is that my use-case, I have two lines of code and then the
>> :()-trick doesn't work anymore because it get translated into a
>> quote-block:
>>
>> julia> eval(:(x=1; module MO end))
>> ERROR: invalid method definition: not a generic function
>>
>> On Wed, 2014-01-29 at 21:08, [email protected] wrote:
>> > The problem seems to have to do with it getting wrapped in a quote
>> block.
>> >
>> > ~~~
>> > julia> quote module MO end end
>> > quote # none, line 1:
>> > $(Expr(:module, true, :MO, quote
>> > eval(x) = top(Core).eval(MO,x)
>> > eval(m,x) = top(Core).eval(m,x)
>> > end))
>> > end
>> >
>> > julia> :(module MO end)
>> > :($(Expr(:module, true, :MO, quote
>> > eval(x) = top(Core).eval(MO,x)
>> > eval(m,x) = top(Core).eval(m,x)
>> > end)))
>> >
>> > julia> eval(quote module MO end end)
>> > ERROR: invalid method definition: not a generic function
>> >
>> > julia> eval(:(module MO end))
>> > Warning: replacing module MO
>> > ~~~
>> >
>> >
>> > On Wed, Jan 29, 2014 at 2:13 PM, Mauro <[email protected]> wrote:
>> >
>> >> As far as I can tell, below macro is the identity-macro and works for
>> >> everything I tried but for module definitions. Why? In fact, I
>> >> struggle to get a module definition working within a macro.
>> >>
>> >> julia> macro id(ex)
>> >> :($(esc(ex)))
>> >> end
>> >>
>> >> julia> @id x=5
>> >> 5
>> >> julia> @id type MT end
>> >>
>> >> julia> @id module MO end
>> >> ERROR: invalid method definition: not a generic function
>> >>
>> >> Second example:
>> >>
>> >> macro typ(ex) # this works and produces type TY
>> >> :(esc(type TY end))
>> >> end
>> >>
>> >> macro mod(ex) # this doesn't
>> >> :(esc(module MO end))
>> >> end
>> >>
>> >> ERROR: syntax: malformed module expression
>> >>
>> >> Is there a way to define modules within macros?
>> >>
>>
>> --
>> Sent with my mu4e
>>
>>