Función varargs con argumentos opcionales
Tengo un script foo.jl
con una función que puede tomar 4 argumentos, 2 de los cuales son opcionales. Puedo hacer esto fácilmente con
function bar(a, b, c=1, d=2)
println(a, b, c, d)
end
bar(ARGS[1], ARGS[2], ARGS[3], ARGS[4])
Puedo llamar a esto con argumentos desde la terminal con
$:> julia foo.jl 1 2 3 4
1234
Pero si quisiera especificar solo los dos primeros argumentos a
y b
, con c=1
y d=2
, no podría llamar al script con $:> julia foo.jl 1 2
ya que el script no contiene una llamada a función con 2 argumentos. Una solución alternativa es medir la longitud de ARGS
in foo.jl
y llamar condicionalmente bar
:
if length(ARGS) == 2
bar(ARGS[1], ARGS[2])
elseif length(ARGS) == 3
bar(ARGS[1], ARGS[2], ARGS[3])
else
bar(ARGS[1], ARGS[2], ARGS[3], ARGS[4])
end
Pero esto es un poco voluminoso cuando se pasa de 4 argumentos. Así que miré el uso de argumentos variables, donde podría llamar a un número arbitrario de argumentos con
function bar(a, b, x...)
println(a, b, x)
end
bar(ARGS[1], ARGS[2], ARGS[3:end])
llamando a esto de múltiples maneras
$:> julia foo.jl 1 2 12(String[],) $:> julia foo.jl 1 2 3 4
12(["3", "4"],)
$:> julia foo.jl 1 2 3 4 5 6
12(["3", "4", "5", "6"],)
Pero entonces no sé cómo (o si puedo) establecer un valor predeterminado para x...
si no se proporciona en la terminal. Algo ingenuo como function bar(a, b, x...=(1, 2))
no funciona. Una solución aquí sería establecer las variables dentro de la función según el contenido o el tamaño de x...
. Pero no sé si hay una mejor manera de hacer esto.
Así que estoy buscando una forma de llamar a una función usando argumentos de la terminal, donde se requiere un número (2 en este caso), mientras que el resto son opcionales y están configurados por defecto.
Respuestas
Quizás esté buscando la siguiente función:
function flexiargs(a1,a2,a3="3",a4="4",a5="5",a6...)
println((a1,a2,a3,a4,a5,a6))
end
flexiargs(args::AbstractVector)=flexiargs(args...)
Esta función funcionará con cualquier número de parámetros siempre que haya al menos dos de ellos.
Probemos con los siguientes datos:
args0=["one","two"]
args1=["one","two","three","four"];
args2=vcat(args,"five","six","seven")
Vamos a ver cómo funciona:
julia> flexiargs(args0)
("one", "two", "3", "4", "5", ())
julia> flexiargs(args1)
("one", "two", "three", "four", "5", ())
julia> flexiargs(args2)
("one", "two", "three", "four", "five", ("six", "seven"))
Finalmente, tenga en cuenta que esto también está bien:
function flexiargs(a1,a2,a3="3",a4="4",a5="5",a6...=("6","7"))
println((a1,a2,a3,a4,a5,a6))
end
flexiargs(args::AbstractVector)=flexiargs(args...)
En ese caso, de forma predeterminada (si no hay suficientes valores args
) a6
, será simplemente un elemento, Tuple
siendo el único elemento un Tuple
("6","7")
.