I didn't know of "$($x)" to interpolate inside stirng inside expresion, thanks!
This also works: macro foo_op(op) quote dot_op = symbol(".$($op)") docstr = "`$($op)` also works for `Foo` types!" function Base.$op(a::Foo, b::Foo) Foo(dot_op(a.x, b.x)) end @doc Markdown.parse(docstr) Base.$op Base.$op end end El miércoles, 16 de diciembre de 2015, 11:19:24 (UTC-6), Michael Hatherly escribió: > > 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. >>> >>