Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create another constructor based on type #144

Closed
davibarreira opened this issue Jan 18, 2022 · 4 comments
Closed

Unable to create another constructor based on type #144

davibarreira opened this issue Jan 18, 2022 · 4 comments

Comments

@davibarreira
Copy link

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.

@mauro3
Copy link
Owner

mauro3 commented Jan 19, 2022

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.

@davibarreira
Copy link
Author

Oh, I see. Thanks for the answer.

@davibarreira
Copy link
Author

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

@mauro3
Copy link
Owner

mauro3 commented May 29, 2022

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

@mauro3 mauro3 closed this as completed May 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants