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. >> >
