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