代码之家  ›  专栏  ›  技术社区  ›  phipsgabler

基于循环(子)模块依赖关系实现宏

  •  0
  • phipsgabler  · 技术社区  · 6 年前

    如果有两个模块, A B ,其中应包含两个函数, bar baz ,它们依赖于彼此的模块,这可以通过首先将函数声明为空,然后添加方法来实现:

    module Wrapper
    
    
    module A
    
    const x = 1
    
    function bar end
    
    end # module A
    
    
    module B
    
    const x = 2
    
    function baz end
    
    end # module B
    
    
    import .A: bar
    import .B: baz
    
    bar(expr) = quote
        println("bar", $(B.x))
        $expr
    end
    
    baz(expr) = quote
        println("baz", $(A.x))
        $expr
    end
    
    end # module Wrapper
    

    然而,我有一个案例 A. B 包含依赖于 酒吧 巴兹 .自从(我想?)我不能从模块外部向宏添加方法,它们必须在内部声明。但是我不能再绕过循环导入了——下面的失败是因为 WARNING: could not import Wrapper.B into A ,正在离开 B 中未定义 A. :

    module Wrapper
    
    
    module A
    
    import ..Wrapper.B
    
    const x = 1
    
    macro foo(expr)
        B.baz(expr)
    end
    
    function bar end
    
    end # module A
    
    
    module B
    
    import ..Wrapper.A
    
    const x = 2
    
    macro foo(expr)
        A.bar(expr)
    end
    
    function baz end
    
    end # module B
    
    
    import .A: bar
    import .B: baz
    
    bar(expr) = quote
        println("bar", $(B.x))
        $expr
    end
    
    baz(expr) = quote
        println("baz", $(A.x))
        $expr
    end
    
    end # module Wrapper
    

    有没有可能实现这种模式?(只需重命名 foo 并将其移动到 Wrapper 不是真正的选项,因为我希望名称相同。

    1 回复  |  直到 6 年前
        1
  •  0
  •   phipsgabler    6 年前

    我可以通过声明 bar baz 外部 A B ,在子模块中使用并重新定义它们,然后最终实现它们的方法:

    module Wrapper
    
    function bar end
    function baz end
    
    
    module A
    
    import ..Wrapper
    
    const x = 1
    
    macro foo(expr)
        Wrapper.baz(expr)
    end
    
    const bar = Wrapper.bar
    
    end # module A
    
    
    module B
    
    import ..Wrapper
    
    const x = 2
    
    macro foo(expr)
        Wrapper.bar(expr)
    end
    
    const baz = Wrapper.baz
    
    end # module B
    
    
    import .A
    import .B
    
    bar(expr) = quote
        println("bar", $(B.x))
        $expr
    end
    
    baz(expr) = quote
        println("baz", $(A.x))
        $expr
    end
    
    end # module Wrapper
    

    结果:

    julia> Wrapper.A.bar(1)
    quote
        #= /tmp/test.jl:119 =#
        println("bar", 2)
        #= /tmp/test.jl:120 =#
        1
    end
    
    julia> Wrapper.B.baz(1)
    quote
        #= /tmp/test.jl:124 =#
        println("baz", 1)
        #= /tmp/test.jl:125 =#
        1
    end
    
    julia> Wrapper.B.@foo 1
    bar2
    1
    
    julia> Wrapper.A.@foo 1
    baz1
    1