Debugging a metaprogramming piece of code


#1

I need some help debugging the following piece of metaprogramming code.

function extract_rectilinear_data(block)
    extents = block[:GetDimensions]()
    dim = length(extents)
    num_of_points = prod(extents)

    d = [:xcoord, :ycoord, :zcoord]
    for j in 1:dim
        @eval begin
            $(d[j]) = zeros($(extents[j]))
        end
    end
    for j in 1:dim
        @eval begin
            k = 1
            for i in 1:$(prod(extents[1:j-1])):$(prod(extents[1:j]))
                $(d[j])[k] = block[:GetPoint](i-1)[$(j)]
                k += 1
            end
        end
    end
    point_coords = [eval(d[i]) for i in 1:dim]

    point_data, cell_data = get_structured_point_and_cell_data(block)
    return VTKRectilinearData(point_coords, point_data, cell_data)
end

Here is the error. It seems that the macro is not seeing block, the input to the function, which I suspect is some naive metaprogramming error.

ERROR: UndefVarError: block not defined
 in macro expansion; at D:\JuliaDev\VTKDataIO\src\paraviewreaders.jl:160 [inline
d]
 in anonymous at .\<missing>:?
 in extract_rectilinear_data(::PyCall.PyObject) at D:\JuliaDev\VTKDataIO\src\par
aviewreaders.jl:158
 in extract_simple_data(::PyCall.PyObject) at D:\JuliaDev\VTKDataIO\src\paraview
readers.jl:41
 in extract_static_data at D:\JuliaDev\VTKDataIO\src\paraviewreaders.jl:27 [inli
ned]
 in read_vtk(::String) at D:\JuliaDev\VTKDataIO\src\paraviewreaders.jl:19

The error is in this line: $(d[j])[k] = block[:GetPoint](i-1)[$(j)]

Thanks alot in advance!


#2

Do NOT use eval this way. In fact, do not use eval in a function that you want to call multiple times in general. (with very few exceptions that you’ll not need to worry about for the time being).

As for why the error happens. eval works in global scope. We will not make it work in local scope.

As for what you should do, don’t try to create variables based on runtime values. Use an array if you want to index it by number and use a dict if you want to index them by name.