Is it possible to know if a certain method supports a certain keyword argument, or one has to use exceptions?
Possible with hasmethod
(not applicable
), but this isn’t good practice. A particular call site doesn’t specify a method; method dispatch is handled for you as you provide various positional arguments. While different methods can have different keyword arguments, it’s good practice to keep the applicable keyword arguments consistent over interchangeable positional argument types or sometimes over a change in the function itself, like a plotting package’s functions sharing keyword arguments for graphics settings. You could add a keyword argument for all methods where a particular positional argument is narrowed down, like dims
for AbstractArray
s, but you wouldn’t use dims
in calls that may interchange either Number
s or Array
s for that argument. You should mostly rely on consistent keyword argument applicability, then use hasmethod
or handle MethodError
s as a last resort.
Thank you.
Here an example:
struct Foo
x::Int64
end
struct Goo
x::Int64
end
oo(f::Foo) = Foo.x + 1
oo(g::Goo;extra=0) = Goo.x + 1 + extra
hasmethod(oo,Tuple{Foo},(:extra,)) # false
hasmethod(oo,Tuple{Goo},(:extra,)) # true
I am doing this in a larger project. I cannot copy-paste code (MWE) from that, but here are the steps:
Use CodeTracking.code_string + MacroTools.splitdef
Provided you have the function
and the candidate method
at hand, you can do:
# where m is your method
types = tuple(m.sig.types[2:end]...)
# where fn is your function
codestring = CodeTracking.code_string(fn, types)
And now, your task is mainly parsing the codestring
(using Meta.parse
) and playing with the resulting expression.
I recommend using MacroTools.splitdef
for this and you’ll be able to easily extract all the :kwargs
(including their types and/or default values) from the expression above. So you can easily check if your target keyword is supported by a certain method.
Putting this together, you get a nice function that you call with function
, method
of interest, and your keyword symbol (+ bonus, you can check the type and value - if those were somehow set at the method definition).
Happy LLM function calling (I suspect that is what you want to achieve).
Depending on the situation, a useful alternative can be to let all methods slurp extraneous keyword arguments, e.g.
oo(f::Foo; _...) = Foo.x + 1
oo(g::Goo;extra=0, _...) = Goo.x + 1 + extra
The obvious drawbacks are that you need to have control of all methods yourself and that you lose all protection against misspelling of keywords or sending the wrong keywords to a method.