I'm trying to extend a method from the JSON.jl module, specifically I'm doing this (extending 'JSON.lower', as documented, to allow serialisation),
generally - I'm asking what are the current Julia "best practices" for extending a method from another module - especially - if this is a method in-change of some of some policy of the module (as in this case in JSON.jl
).
Is there actually a way to guarantee the updated method will be used by the imported module, except for patching it?
Let's demonstrate both desired and sinister behaviour:
module TestProgram
using JSON
import JSON.lower # not sure whether this is needed
JSON.print(Set([1,2,1]))
## output:
## {"dict":{"2":null,"1":null}}
## not the output I want or expect
## in this case might be a good idea to patch JSON.jl and pull request
## and "JSON.print" - is now compiled with this default behaviour
JSON.lower{T}(v::Set{T}) = collect(v) # overloading 'JSON.lower'
println(json(Set([1,2,1])))
## output:
## [2,1]
JSON.print(Set([1,2,1]))
## output still:
## {"dict":{"2":null,"1":null}}
end # module
- If anywhere during runtime before - some piece of code already ran this method,
json(v::Set{T})
- then this method is already compiled, and will not use my extention of 'JSON.lower' - This actually happen to me and was hard to debug, as the
json()
call was behaving as expected, whileJSON.print()
was behaving differently (just by change in some run-flow) - Since any module (JSON.jl here) can be used by another package I'm using - I have no way of knowing my code actually runs first and actually extends a method correctly
So - what are the best practices to ensure that?
[Currently tested this behaviour with Julia 0.4.6 and 0.5.0]
JSON.lower
for types you don't own, since JSON is an important package that many others depend on. It's best to create your own types to wrap around built-ins likeSet
if you need custom JSON serialization. – Fengyang Wanglower
forSet
would be welcome. – Fengyang Wang