Reputation: 11
I am a Julia (and stackoverflow) newbie but am trying unsuccessfully to simplify a function call. I need to define calls to create many instances of 30 different structs, each having a different set of properties. The code below works but will force the user to use exactly the same string twice, as in: EV_668876 = newEV("EV_668876", "test EV") This is a pain and likely to cause errors. I have written a macro to generate the command but can't get REPL to execute the command. Here is the code (sorry for its length).
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?
#=
# ==============================================
Upvotes: 1
Views: 93
Reputation: 20950
As far as I understand (and I'm not sure what the printing does in your example), you want a macro that expands
@create <id> <name>
to
<id> = newEV("<id>", name)
The following will achieve that:
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
is for debugging, since I didn't copy your code. It simply gets the expression that results from a macro call.
esc
aping is necessary here, since you want the identifier given by the symbol id
to end up being defined in the calling scope.
Upvotes: 2