mauro3/Parameters.jl

Unable to create another constructor based on type

davibarreira opened this issue · 4 comments

Hey, first of all. Thanks for this package! It's really great.

Here is the issue. I have the following struct:

@with_kw mutable struct Example
    fillcolor::Color   = parse(Colorant,"black")
    x::Real   = 1
end

Now, I want to be able to use Example(fillcolor = "white"). For that, I tried doing

Example(;fillcolor::String, kwargs...) = Example(;fillcolor = parse(Colorant, fillcolor) , kwargs...)

The problem is that, once I define this new function, then the Example() stops working.

In Julia, multiple dispatch only works with positional arguments. Thus your second definition overwrites the previous 0-argument method, which was the keyword constructor which Parameters.jl defines. Thus it does not work anymore. See:

julia> methods(Example)
# 5 methods for type constructor:
[1] Example(; fillcolor, x) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:493
[2] Example(pp::Example; kws...) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:569
[3] Example(pp::Example, di::AbstractDict) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:572
[4] Example(pp::Example, di::Tuple{Symbol, Any}...) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:573
[5] Example(fillcolor, x) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:505

julia> Example(;fillcolor::String, kwargs...) = Example(;fillcolor = parse(Int, fillcolor) , kwargs...)
Example

julia> methods(Example)
# 5 methods for type constructor:
[1] Example(; fillcolor, kwargs...) in Main at REPL[7]:1
[2] Example(pp::Example; kws...) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:569
[3] Example(pp::Example, di::AbstractDict) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:572
[4] Example(pp::Example, di::Tuple{Symbol, Any}...) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:573
[5] Example(fillcolor, x) in Main at /home/mauro/julia/dot-julia-dev/Parameters/src/Parameters.jl:505

I don't think there is a way to do this but I will ponder it a bit longer.

Oh, I see. Thanks for the answer.

So, instead of writing a dispatch, would it be possible to somehow write a "preprocessing" function for the input? I mean the following example:

struct M
 color1::Color
 color2::Color
end

M(;color1="white",
   color2="blue") = M(parse(Colorant,color1), parse(Colorant,color2))

There was some discussion on adding hooks to pre and post-process inputs, but no code... See #52