【问题标题】:Implement macros based on cyclic (sub)module dependencies基于循环(子)模块依赖实现宏
【发布时间】:2018-10-05 12:58:35
【问题描述】:

如果你有两个模块,AB,它们应该包含两个函数,barbaz,它们依赖于彼此的模块,这可以通过首先将函数声明为空来实现,然后之后添加方法:

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

但是,我有一种情况,AB 包含依赖于 barbaz 的宏。由于(我认为?)我不能从模块外部向宏添加方法,因此必须在内部声明它们。但后来我无法再规避循环导入了——以下失败是因为WARNING: could not import Wrapper.B into A,而BA 中未定义:

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

有没有可能如何实现这种模式? (只是重命名 foos 并将它们移动到 Wrapper 并不是一个真正的选择,因为我希望名称相同......)。

【问题讨论】:

    标签: module julia metaprogramming


    【解决方案1】:

    我可以通过在AB之外声明barbaz,在子模块中使用和重新定义它们,然后最终实现它们的方法来解决这个问题:

    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
    

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 2014-04-28
      • 2018-03-17
      • 2017-10-27
      • 2021-09-18
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多