You can use multiple dispatch and a "wrapper" type to modify the behaviour
of a function. For instance, given this function
function foo(x)
return x+x
end
foo(11) # 22
You can write:
type Pumpkin
nhorse
end
import Base.(+)
(+)(p1::Pumpkin, p2::Pumpkin) = "2 pumpkins and $(p1.nhorse+p2.nhorse)
horses"
foo(Pumpkin(11)) # 2 pumpkins and 22 horses
In the same way, you could define `testset_beginend` for your wrapper
type... That's IMO a bad idea in this case, because @testset was not
written to be extended, and the definition might change in future versions
of Julia. I personally would copy-paste (or fork) those functions I need to
change.
HTH,
Cédric
On Sat, Feb 6, 2016 at 10:57 AM, Robert Feldt <[email protected]>
wrote:
> One concrete example:
>
> I want to reuse the @testset macro in base/test.jl but change the two
> utility functions it calls out to (testset_beginend, testset_forloop) to
> have a richer interface to the AbstractTestSet values used during testing.
>
> But the question is a general one and I tried to simplify the code to the
> essentials. The macro m1 might be very large and complex and I do not want
> to rewrite it or copy-paste it in another module but simply want to
> re-implement some of its utility functions etc.
>
> Hope this helps clarify,
>
> Robert
>
>
> Den lördag 6 februari 2016 kl. 16:37:54 UTC+1 skrev Cedric St-Jean:
>>
>> Could you give some context and a more concrete description of what
>> you're trying to do?
>>
>> macro m1(ex)
>> @show(ex)
>> @show f1(ex)
>> end
>> function f1(ex)
>> "M1.f1: $ex"
>> end
>>
>> Do you want the macro m1 to expand into code that calls `M2.f1`? Or do
>> you literally want the code in `m1` to call `M2.f1`, as in the example you
>> gave? That would be an unusual request, but it could be done with multiple
>> dispatch...
>>
>> On Saturday, February 6, 2016 at 6:39:49 AM UTC-5, Robert Feldt wrote:
>>>
>>> My feeling is that am missing something very basic here or that this has
>>> been asked/misunderstood many times before. ;) But since I could find an
>>> answer in my searches here goes:
>>>
>>> How can I reuse some parts of another module while re-implementing some
>>> of it's lower-level functions (it uses internally)? In the example code
>>> below I want to create a new module M2 which reuses (via import and then
>>> export) a macro from another module M1 but re-implements a lower level f1
>>> function that is used in the implementation of m1.
>>>
>>> module M1
>>> export @m1
>>> macro m1(ex)
>>> @show(ex)
>>> @show f1(ex)
>>> end
>>> function f1(ex)
>>> "M1.f1: $ex"
>>> end
>>> end
>>>
>>> a = 1
>>> M1.@m1 a + 1 # prints: f1(ex) = "M1.f1: a + 1"
>>>
>>> # I want to reuse @m1 but redefine the f1 it uses.
>>> module M2
>>> import M1: @m1
>>> function f1(ex)
>>> "M2.f1: $ex"
>>> end
>>> end
>>>
>>> M2.@m1 a + 1 # Not what I want, it still uses M1.f1
>>>
>>> module M3
>>> import M1: @m1, f1
>>> function f1(ex)
>>> "M3.f1: $ex"
>>> end
>>> end
>>>
>>> M3.@m1 a + 1 # What I want but gives warning that f1 in module M1
>>> overwritten
>>> M1.@m1 a + 1 # and M1.@m1 is affected which can affect others...
>>>
>>> Is there a way I can import @m1 from M1 into my new module but force it
>>> to call my newly defined f1?
>>> Am I totally on the wrong track here and another "design" is better?
>>>
>>> I'd rather not fall back to copy-paste solutions here...
>>>
>>> Thanks, Robert
>>>
>>>