If the macro returns a single documentable expression, such as a function 
or type, then you shouldn’t need to do anything special, just add an @doc 
to the for-loop that generates the methods.

If the macro returns a block expression then you need to tell the docsystem 
how you’d like to handle it. Use Base.@__doc__ to mark the subexpression 
you’d like to document in expression returned by the macro. See this 
section of the manual, 
http://docs.julialang.org/en/latest/manual/documentation/#macro-generated-code, 
for an example. Something like the following should work for the code in 
this thread:

macro operator_obs(name)
    M = esc(:M)
    n = esc(name)
    d = esc(symbol(".", name))
    quote
        import Base: $n
        Base.@__doc__ $(n)(m_1::$M, m_2::$M) = $(M)($(d)(m_1.a, m_2.a), 
$(d)(m_1.b, m_2.b))
    end
end

for op in [:+, :-, :*, :/]
    @eval begin
        @doc "`$($op)` docs for type `M`." ->
        @operator_obs $op
    end
end

help?> M(1, 2) + M(2, 3)
  + docs for type M.

help?> M(1, 2) / M(2, 3)
  / docs for type M.

Documenting code generated by a function, rather than a macro, isn’t going 
to be as clean though. You’d need to use @doc after defining the code, 
perhaps something like:

for op in [:+, :-, :*, :/]
    @eval begin
        operator_obs($op)
        @doc "`$($op)` docs for type `M`." $(op)(::M, ::M)
    end
end

to add docs to the correct op method.

— Mike
​


On Wednesday, 16 December 2015 17:41:36 UTC+2, j verzani wrote:
>
> While this topic is active, can anyone suggest how this can be 
> incorporated with docstrings to add help entries to the newly generated 
> methods?
>
> On Wednesday, December 16, 2015 at 5:22:24 AM UTC-5, Greg Plowman wrote:
>>
>> I have exactly the same requirement. 
>> Additionally, I often have more than 2 fields and also change the fields 
>> of my custom types.
>>
>> So I use a slightly more general version of the above:
>>
>>
>> function CompositeBinaryOp(T::Symbol, op::Symbol)
>>     expressions = [ :($op(x1.$field, x2.$field)) for field in 
>> fieldnames(eval(T)) ]
>>     body = Expr(:call, T, expressions...)
>>     quote
>>         function $op(x1::$T, x2::$T)
>>             return $body
>>         end
>>     end
>> end
>>
>> type M
>>     a
>>     b
>> end
>>
>> import Base: +, -, *, /, ^
>>
>> for T in [:M]
>>     for op in [:+, :-, :*, :/, :^]
>>         #eval(CompositeBinaryOp(T, op))
>>
>>         code = CompositeBinaryOp(T, op)
>>         println(code, "\n")
>>         eval(code)
>>     end
>> end
>>
>>  
>> The advantage here for me is that I can change the fields (number, type 
>> order etc.) and operators don't need manual updating.
>>
>> I have similar functions for copy constructors, unary operators etc.
>>
>

Reply via email to