I’d like to preprocess the parameters that are passed to an Agent upon construction. How would I go about that?
A simple example of what I’d like to do:
function make_set(t::Union{Nothing, Symbol, Set{Symbol}})
if t === nothing
return Set{Symbol}()
elseif t isa Symbol
return Set([t])
else
return t
end
end
@agent struct TestAgent(NoSpaceAgent)
types::Set{Symbol} = make_set(types)
end
But that doesn’t work. The code compiles fine but when I then execute:
TestAgent(id = 1, types = :test)
I get the following error:
ERROR: MethodError: Cannot convert
an object of type Symbol to an object of type Set{Symbol}
Closest candidates are:
convert(::Type{T}, ::T) where T<:AbstractSet
@ Base set.jl:550
convert(::Type{T}, ::T) where T
@ Base Base.jl:84
convert(::Type{T}, ::AbstractSet) where T<:AbstractSet
@ Base set.jl:551
…
Is there a solution for this?
Thanks in advance,
Stef
Hi Stef.
Unfortunately, I’m not aware of a good way to achieve what you’re looking for. The closest I can manage is creating a helper function which calls your agent constructor as follows:
TestAgent_helper(; kwargs...) = begin
types = get(kwargs, :types, nothing)
TestAgent(; kwargs..., types=make_set(types))
end
You can check that the following calls work correctly
TestAgent_helper(; id=1, types=:test) # types will be Set([:test])
TestAgent_helper(; id=1) # types will be Set{Symbol}()
It’s still not clear to me why what you’re after would be desirable. Is there a reason in your use case why processing your types
data before calling the constructor would be inconvenient? Perhaps there are other ways to address the issues you are facing without adding extra logic into or around the agent constructor.
You didn’t ask for an explanation of the error, but I’ll give one below just in case.
What your code does is set the default value of types
to be make_set(types)
You get an error because when you pass in a value for types
it is used instead of the default value, and it is not of the specified type. Your default value would also error if you called the agent constructor without specifying types
since types
is not defined anywhere else.
Hope this is useful. Regards,
Paolo
2 Likes
The main reason why I want to do this is to make it easier to use the code. Writing
TestAgent(types = :aType)
is just less cumbersome than having to write
TestAgent(types = Set([:aType]))
all the time
Thank you for the explanation. That definitely helps.
Kind regards,
Stef
1 Like