使用宏生成将在REPL中执行的Julia命令

时间:2018-11-01 16:52:38

标签: julia

我是Julia(和stackoverflow)新手,但尝试简化函数调用未成功。 我需要定义调用来创建30个不同结构的许多实例,每个实例具有一组不同的属性。 下面的代码有效,但是将迫使用户两次使用完全相同的字符串,如下所示:          EV_668876 = newEV(“ EV_668876”,“测试EV”) 这是一种痛苦,并可能导致错误。 我已经编写了一个宏来生成命令,但是无法获得REPL来执行命令。 这是代码(很抱歉,它的长度)。

 mutable struct EV
    label::FixedLabel
    id::FixedId
    name::String
    designAuth::Ident
    descripn::String
    timestamp::String
    priority::Int16
     assoc_EO::Ident   # this needs a new Set of EOstructs, to be defined
    origin_OV::Ident    # similar Set of OVstructs
    OV_destination::Ident    # this needs a new OVstruct, to be defined
    underRespOf::Ident
    underAuthOf::Ident
end

function newEV(id::String, name::String)
    trylabel = String(split(id,['-',':','_'])[1]) # Note that split() yields a SubString(String)
    if trylabel !== "EV"       # ! => not
        throw(DomainError("This id $id is not an EV, try again"))
    end
    labelFixed = FixedLabel(trylabel) 
    registerId(id) # registers id if OK 
    idFixed = FixedId(id)
    # ident = newId(id,name)
    new = EV(labelFixed,idFixed,name,anon_anon,"","",0,anon_anon,anon_anon,anon_anon,anon_anon,anon_anon)
end

EV_668876 = newEV("EV_668876", "test EV") # runs OK and produces
#=
This runs OK and produces
EV_668876 registered OK
EV(FixedLabel("EV"), FixedId("EV_668876"), "test EV", Ident(FixedLabel("PPR"), FixedId("PPR-2"), "Anon_Anon"), "", "", 0, Ident(FixedLabel("PPR"), FixedId("PPR-2"), "Anon_Anon"), Ident(FixedLabel("PPR"), FixedId("PPR-2"), "Anon_Anon"), Ident(FixedLabel("PPR"), FixedId("PPR-2"), "Anon_Anon"), Ident(FixedLabel("PPR"), FixedId("PPR-2"), "Anon_Anon"), Ident(FixedLabel("PPR"), FixedId("PPR-2"), "Anon_Anon"))
#=

# === Attempting to use a macro to simplify the newEV() function ===
macro create(id,name)
    label = "EV"
     return :(println($id," = new",$label,"(\"",$id,"\", \"",$name,"\")"))
end
@create("EV_97234894","new test")
#=
This   generates    
EV_97234894 = newEV("EV_97234894", "new test")   which is what I want 
but returns a type nothing – is that why REPL doesn't execute the result?
#=
# ==============================================

1 个答案:

答案 0 :(得分:2)

据我了解(我不确定您的示例中的打印效果如何),您需要一个可扩展的宏

@create <id> <name>

<id> = newEV("<id>", name)

以下将实现这一目标:

julia> macro create(id::Symbol, name)
           :($(esc(id)) = newEV($(String(id)), $name))
       end
@create (macro with 1 method)

julia> @macroexpand @create EV_234324 "new test"
:(EV_234324 = (Main.newEV)("EV_234324", "new test"))

@macroexpand用于调试,因为我没有复制您的代码。它只是获取由宏调用产生的表达式。

esc在此处是必需的,因为您希望由符号id给出的标识符最终在调用范围中定义。