Suppose there is a function in some package for which I want to implement a custom method in my own package MyPackage
. However, I also want users of MyPackage
to customize/overwrite that method further if they want. I’m wondering what is the best practice for allowing this.
As a specific example, let’s take DrWatson’s default_prefix
function. As discussed in the documentation of that function, let’s say I want to customize it for a MyType
in MyPackage
.
Option 1
One possibility is to define the following in MyPackage
:
import DrWatson
default_prefix_mytype(c) = "lala" # no type annotation!
DrWatson.default_prefix(c::MyType) = default_prefix_mytype(c)
I can then tell users of my package that if they want to overwrite the default_prefix
for MyType
, they should define their own
import MyPackage
MyPackage.default_prefix_mytype(c::MyPackage.MyType) = "user_lala"
Since that’s more specific than the default_prefix_mytype
without any type annotation, it will essentially overwrite the method in MyPackage
.
Option 2
The other possible solution would be to directly set
import DrWatson
DrWatson.default_prefix(c::MyType) = "lala"
in MyPackage
and to tell my users that if they don’t like that, they should just define their own
import DrWatson
using MyPackage: MyType
DrWatson.default_prefix(c::MyType) = "user_lala"
This would exactly overwrite the existing method.
The first method seems cleaner, but more convoluted to communicate in the documentation. The second method is easier to communicate, but it raises the question of how exactly Julia handles overwriting methods. Which method definition wins? I assume the last using
wins, right? If a user does using MyPackage
in their script, then overwrites the method, and then calls using MyPackage
again (directly or indirectly), the second using
is ignored, right? (Or does it revert the method definition?).
What is the recommended best practice in a situation like that? Is there some more elegant third option?