Adding documentation string in metaprogramming function definition eval loop

I have this nice codeblock:

for (dim, Dim) in (("time", :Time), ("zonal", :Lon))
    @eval begin
        # """
        #     $(dim)average(a::DimensionalArray, i=end)
        # Return the $(dim)-averaged `a` (average across dimension $Dim).
        # Do the time average from index `1` to `i` of that dimension.
        # """
        $(Symbol(dim, :average))(a::AbDimArray) = drop(mean, a, $(Dim))
        $(Symbol(dim, :average))(a::AbDimArray, i) = drop(mean, a[$(Dim)(1:i)], $(Dim))
        export $(Symbol(dim, :average))
    end
end

which works, and does exactly what it should: it defines 2 functions, timeaverage and zonalaverage that do what they are supposed to do.

Now what I"d like to do is make these functions have a documentation string! I’ve written the docstring as you can see (its commented out), but I find that it throws error that dim is not defined… How do I attach a docstring in a function I define in such a way? I could define the necessary string before the @eval block, but I don’t know how to attach it.

You need to interpolate twice; into the expression and into the string:

julia> for (dim, Dim) in (("time", :Time), ("zonal", :Lon))
           @eval begin
               """
                   $($(dim))average(a::DimensionalArray, i=end)
               Return the $($(dim))-averaged `a` (average across dimension $($(string(Dim)))).
               Do the time average from index `1` to `i` of that dimension.
               """
               $(Symbol(dim, :average))(a::Array) = drop(mean, a, $(Dim))
               $(Symbol(dim, :average))(a::Array, i) = drop(mean, a[$(Dim)(1:i)], $(Dim))
               export $(Symbol(dim, :average))
           end
       end

help?> timeaverage
search: timeaverage

  timeaverage(a::DimensionalArray, i=end)

  Return the time-averaged a (average across dimension Time). Do the time average from index 1 to i of that dimension.

Note also the string(Dim), not sure why that is needed.

For me the string was not necessary (and in fact made the printing worse, as it showed across dimension string(DimensionalData.Dim)). I guess the difference was that in my workspace Time is an existing struct?

Yea, that makes sense.