I’m writing a specialized plotting function (let’s call it A(), say) that does quite a lot of logic, and then calls plot() to generate a new plot. Is there a way that I can make a paired function (let’s call it A!(), say) without repeating all the logic in the second version? The only difference would be that A() would call plot() and A!() would call plot!(), with the same logic before the plot call and the same arguments in the plot call.
I’m guessing that this sort of thing comes up quite a bit. Is the best practice to put the logic that goes before the plot calls into a new function and have both A() and A!() call that?
If you can’t separate the logic that come before the call to plot you can use a macro instead (just saying, it’s not the best solutions)
const PLOT_FUNC = (:plot, :plot!)
const FUNCS = (:A, :A!)
for i in Base.OneTo(2)
func = FUNCS[i]
plot = PLOT_FUNC[i]
eval(quote
function $func(args...)
# function body
$plot(args...)
end
end )
end
It’s just a way to achieve what you want, just a proposition
In addition to factoring out the common code to a separate function, like @karei suggested, another common solution would be, to include an additional argument (possibly with default value) should_mutate::Bool=false and branch only for the call that differs.
Of course you could also pass the function (plot or plot!) as argument, but this might be overkill for two choices.
Can you define the mutating method first and define the non-mutating one based on it? This is a very common pattern for mutating. Something like:
function A!(p, arg1, arg2)
#logic logic
return(plot!(p, etc))
end
function A(arg1, arg2)
p = plot(somearguments) #maybe create the axis or something initial
A!(p, arg1, arg2)
end