Code generation for docstrings

i know how to create functions with code generation, but how does one simultaneously create docstrings? it seems a global variable is required. is there no better way?

julia> struct MyNumber; x::Float64; end

julia> for op = (:sin, :cos, :tan, :log, :exp)
           @eval Base.$op(a::MyNumber) = MyNumber($op(a.x))
       end

julia> for op = (:sin, :cos, :tan, :log, :exp)
           @eval begin
           """
           my new definition for $op
           """
           Base.$op(a::MyNumber) = MyNumber($op(a.x))
           end
       end
ERROR: UndefVarError: `op` not defined in `Main`
Suggestion: check for spelling errors or missing imports.
Stacktrace:
 [1] top-level scope
   @ REPL[10]:3
 [2] eval(m::Module, e::Any)
   @ Core ./boot.jl:430
 [3] top-level scope
   @ REPL[10]:2

julia> for op = (:sin, :cos, :tan, :log, :exp)
           global g_op
           g_op = op
           @eval begin
           """
           my new definition for $g_op
           """
           Base.$op(a::MyNumber) = MyNumber($op(a.x))
           end
       end

help?> sin
search: sin sinc sign asin sinh sind in min isinf using asind asinh stdin sinpi sincos bind Main

  sin(x)

  Compute sine of x, where x is in radians.

  See also sind, sinpi, sincos, cis, asin.

  Examples
  โ‰กโ‰กโ‰กโ‰กโ‰กโ‰กโ‰กโ‰ก

  julia> round.(sin.(range(0, 2pi, length=9)'), digits=3)
  1ร—9 Matrix{Float64}:
   0.0  0.707  1.0  0.707  0.0  -0.707  -1.0  -0.707  -0.0
  
  julia> sind(45)
  0.7071067811865476
  
  julia> sinpi(1/4)
  0.7071067811865475
  
  julia> round.(sincos(pi/6), digits=3)
  (0.5, 0.866)
  
  julia> round(cis(pi/6), digits=3)
  0.866 + 0.5im
  
  julia> round(exp(im*pi/6), digits=3)
  0.866 + 0.5im

  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

  my new definition for sin

  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

  sin(A::AbstractMatrix)

  Compute the matrix sine of a square matrix A.

  If A is symmetric or Hermitian, its eigendecomposition (eigen) is used to compute the sine.
  Otherwise, the sine is determined by calling exp.

  Examples
  โ‰กโ‰กโ‰กโ‰กโ‰กโ‰กโ‰กโ‰ก

  julia> sin(fill(1.0, (2,2)))
  2ร—2 Matrix{Float64}:
   0.454649  0.454649
   0.454649  0.454649

I think it needs double-escaping like $($op) in the docstring - the inner $ being the interpolation for @eval and the outer one being ordinary string interpolation.

1 Like

Or you can interpolate the whole pre-interpolated string into @eval like $(""".....$op.....""").