I’m trying to build a function using metaprogramming. I followed this approach, which is good.
I am defining a function similar to the following:
function myfunc(x::Int64,....)
# Now I call another function using x as a parameter
anotherfunction(x)
end
In anotherfunction, I have something like
function anotherfunction(x)
if typeof(x) <: Int
#whatever
...
This fails because anotherfunction receives x as a Symbol, rather than the value.
The actual functions are (sorry about my messy code):
function create_function( ptr::Ptr{VSPlugin}, funcname::String, params)
#https://stackoverflow.com/questions/37230071/metaprogramming-julia-functions-with-args-and-keyword-args
#https://github.com/JuliaMath/DecFP.jl/blob/master/src/DecFP.jl
# Creamos la lista de parámetros: los obligatorios + los opcionales (les asigna nothing)
# Lo siguiente crea la interfaz que queremos que tenga nuestra función.
f_arguments = []
f_argumentsopt = Expr(:parameters)
for i in 1:length(params)
param = params[i]
tipo = get_new_type( param[2] )
if length(param) == 2 #Expr(:kw,:y,Float64(2))
ex = Expr(:(::),Symbol(param[1]),tipo)
f_arguments = [f_arguments ; ex ]
elseif length(param) > 2 && param[3] == "opt"
# param=Union{Int64,Nothin}=nothin
ex = Expr(:(::),Symbol(param[1]),Union{tipo, Nothing}) # Asignamos el tipo
ex = Expr(:kw,ex, :nothing)
#ex = Expr(:kw,Symbol("$(param[1])"),Union{tipo, Nothing}=nothing)
f_argumentsopt.args = [f_argumentsopt.args; ex ]
end
end
f_call = Expr( :call, Symbol(funcname), f_argumentsopt )
# Añadimos sólo los parámetros obligatorios
for ex in f_arguments
f_call.args = [f_call.args ; ex]
end
# Cuerpo de la función
f_body = quote
# Creamos un vsmap a partir de la llamada.
lista = []
#mymap = createMap()
for param in $params
if length(param) == 2 # Los obligatorios
tmp = (param[1], Symbol(param[1]) )
#if param[2] == "int"
# propSetInt( mymap, param[1], eval(Symbol(param[1])), paAppend )
#end
#print(param[2]) # Una opción construir el vsmap a partir del tipo definido: int llama a propSetInt
lista = [lista ; tmp]
elseif length(param) > 2 && param[3] == "opt"
for (k,v) in kwargs
if k == Symbol(param[1]) && !(v == nothing)
tmp = (param[1], v) # Añadimos el parámetro con su valor
lista = [lista ; tmp]
end
end
end
end
println("LISTA2VSMAP: $(lista) ") # Toma el tipo del valor, que es desconocido.
vsmap = list2vsmap( lista )
invoke( $ptr, $funcname, vsmap )
end
f_declare = Expr( :function, f_call, f_body )
eval( f_declare )
#f_declare
end
and the call to lista2vsmap is:
function list2vsmap( items ) #::Array{Any,1}
vsmap = createMap()
for item in items
key = item[1]
value = item[2]
#if typeof( value ) == Symbol
# value = esc(eval(value))
# println(value)
#end
if typeof( value ) <: AbstractFloat
propSetFloat( vsmap, key, value, paAppend )
elseif typeof( value ) <: Int
propSetInt( vsmap, key, value, paAppend )
elseif typeof( value ) <: Array{Int64,1}
propSetIntArray( vsmap, key, value )
elseif typeof( value ) <: Array{Float64,1}
propSetFloatArray( vsmap, key, value )
elseif typeof( value ) <: AbstractString
propSetData( vsmap, key, value, paAppend )
elseif typeof( value ) == VSNodeRef
propSetNode( vsmap, key, value, paAppend )
elseif typeof( value ) == VSFrameRef
propSetFrame( vsmap, key, value, paAppend )
elseif typeof( value ) == VSFuncRef
propSetFunc( vsmap, key, value, paAppend )
else
println("[ERROR] vsmap - list2vsmap: tipo no soportado: $(typeof(value))")
end
end
vsmap
end
Thanks