Debugging a metaprogramming piece of code


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]))
    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
    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)

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
 in anonymous at .\<missing>:?
 in extract_rectilinear_data(::PyCall.PyObject) at D:\JuliaDev\VTKDataIO\src\par
 in extract_simple_data(::PyCall.PyObject) at D:\JuliaDev\VTKDataIO\src\paraview
 in extract_static_data at D:\JuliaDev\VTKDataIO\src\paraviewreaders.jl:27 [inli
 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!


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.