Skip to content

Fix module lookup issue #497

@rjplevin

Description

@rjplevin

Mimi currently represents components by a ComponentId that contains two Symbols, a module name and a component name. This was adequate in our prior implementation, which maintained a global dict of components keyed by this id. The use of the global dictionary defeated module compilation, so we now look for the module name in Main (unless it's :Mimi, which we recognize internally as the current Mimi module.)

This is not a general solution, however, because modules aren't necessarily known in Main when we need to reference them. Some calls are processed while the module is being defined, so while the Module exists, it's not available in Main until the definition is complete, which is too late for our purposes.

More generally, a single symbol is inadequate to identify a module. Nested modules can be represented by a module "path", e.g., (:Main, :MimiDICE, :Mimi), but the full path isn't findable via Main until the module (in this example, MimiDICE) definition is complete.

In the class-based branch, ComponentId now includes the path to the module:

struct ComponentId <: MimiStruct
    module_path::Union{Nothing, NTuple{N, Symbol} where N}
    module_name::Symbol
    comp_name::Symbol
end

Internally in @defcomponent, I pass the Module instance itself to allow a component to be added, avoiding module lookup:

function find_module(path::NTuple{N, Symbol} where N)
    m = Main
    for name in path
        try
            m = getfield(m, name)
        catch
            error("Module name $name was not found in module $m")
        end
    end
    return m
end

function compdef(comp_id::ComponentId; module_obj::Union{Nothing, Module}=nothing)
    if module_obj === nothing
        path = @or(comp_id.module_path, (:Main, comp_id.module_name))        
        module_obj = find_module(path)
    end

    return getfield(module_obj, comp_id.comp_name)
end

At this point, I'd rather finish testing/debugging the component revisions and not attempt to back-port this stuff to the current branch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions