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.

1 Like

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.

2 Likes

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.