On Mon, Jul 27, 2015 at 4:27 PM, Christoph Ortner
<[email protected]> wrote:
> This is my first attempt at metaprogramming, so apologies if this should be
> obvious from the documentation (or just obvious):
>
> For defining an interface I am implementing "dummy functions" which just
> return a tailored error message if an interface function has not been
> implemented. At the moment this largely duplicates the standard Julia
> behaviour, but it just gives a little more information (e.g. the information
> that a certain function ought to be part of an interface), but long-term I
> want to give it additional functionality, e.g. more information.
>
> Because I am implementing many of these interface functions, I tried to
> write a macro:
>
> module Test
> using Docile, Lexicon, Compat
> export ffun
>
> macro protofun(fname, argtypes...)
>     # preprocess the arguments to generate an error message
>     errmsg = "AbstractAtomsInterface: `$(string(fname))("
>     for n = 1:length(argtypes)-1
>         errmsg *= string(argtypes[n]) * ", "
>     end
>     errmsg = errmsg[1:end-2] * ")' has no implementation."
>
>     eval(quote
>          @doc $(argtypes[end])->
>         function $(fname)($(argtypes[1:end-1]...))
>             error($errmsg)
>         end
>     end)
> end

Use `esc()` on the symbols passed in and don't use `eval`.

>
> @protofun(ffun, ::Number, ::String, doc"yads")
> end
>
>
> When I run this:
>
>
> julia> using Test
>
> julia> ffun(1.0, "abc")
> ERROR: AtomsInterface: `ffun(::Number, ::String)' has no implementation.
>  in ffun at /Users/ortner/gits/Atoms.jl/Test.jl:20
>
>
> What I would like to see is
>
> ERROR: AtomsInterface: `ffun(::Float64, ::ASCIIString)' has no
> implementation.
>  in ffun at /Users/ortner/gits/Atoms.jl/Test.jl:20
>
> It is clear to me why my implementation does not work as I hope, but I don't
> see how to make this work. I would be grateful about any suggestions.

The best way to write a macro is to write out what you'd like to
achieve and then figure out how to do the transformation.

In your case, you probably want sth like

function ffun(a1::Number, a2::String)
    error(string("something", typeof(a1), "sth in the middle",
typeof(a2), "sth else"))
end

so the way to do this is to turn `::Number` into `a1::Number` (hint,
you want `gensym`), and change the static string error message to a
call to `string` with the arguments you want.

>
> Many thanks,
> Christoph
>

Reply via email to