Реализация макросов на основе циклических (под) модульных зависимостей - PullRequest
0 голосов
/ 05 октября 2018

Если у вас есть два модуля, 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 содержат макросы, которые зависят от bar и baz.Поскольку (я думаю?) Я не могу добавлять методы в макрос извне модуля, они должны быть объявлены внутри.Но тогда я больше не могу обойти циклический импорт - следующее не получается, потому что 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 s и переместить их в Wrapper на самом деле не вариант, так как я хочу, чтобы имена были одинаковыми ...).

1 Ответ

0 голосов
/ 05 октября 2018

Я мог бы решить проблему, объявив 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
...