Custom Constructors
Adding Custom code to the structures
AcuteML introduces three @creator
, @extractor
, and @updater
macros to be used inside @aml
definition. The location of the macros specifies their location in the function. For example, putting @creator
at the begining, adds the code to begining of creator function.
Put
@creator
inside@aml
to add a custom code to the creator function (DOM creation when the struct is instanciated).This macro only affects creation (not extraction/updating), but can be used in combination with other macros.
Put
@extractor
inside@aml
to add a custom code to the extractor function (DOM parsing when a html/xml text is used for instanciation of a struct).This macro only affects creation (not creation/updating), but can be used in combination with other macros.
Be careful that setting struct fields using
@extractor
only changes the struct field and not the xml code.Put
@updater
inside@aml
to add a custom code to the updater function (DOM updating after instanciation of a struct).This macro only affects updating (not creation/extraction), but can be used in combination with other macros.
In the following example IQ
and average
are calculated automatically. Also, in the following example log
is filled automatically (which doesn't have an associated xml element).
using AcuteML
# Definition
@aml mutable struct Student "student"
# add custom code to the begining of creator function
# the following automatically fills IQ based on the name
@creator begin
if occursin("smart", name)
name = replace(name, "-smart" => "") # remove smart from name
IQ = "smart"
elseif occursin("genius", name)
name = replace(name, "-genius" => "") # remove smart from name
IQ = "genius"
else
error("Give a smart student.")
end
end
name::String, "~"
GPA::Float64, "~"
IQ::UN{String} = nothing, att"~" # default to nothing, but filled automatically by first @cretor macro
# add custom code to the end of extractor function
log::UN{String} = nothing, "~"
@extractor begin
if GPA > 4.0
log = "A genius with a GPA of $GPA is found" # setting fields using @extractor only changes the field and not the xml code
end
end
end
@aml mutable struct MathClass "math-class"
@creator begin
GPAsum = 0.0
for student in students
GPAsum = GPAsum + student.GPA
end
average = GPAsum / length(students) # fill average field
end
students::Vector{Student}, "student"
average::UN{Float64} = nothing, "average" # calculated automatically
end
################################################################
# Creation
smarts = [Student(name = "Jack-smart", GPA = 2.0), Student(name = "Sara-genius", GPA = 5.0)]
mathclass = MathClass(students = smarts)
mathclass.students[1].name # "Jack"
mathclass.students[2].name # "Sara"
mathclass.average # 3.5
pprint(mathclass)
# <math-class>
# <student IQ="smart">
# <name>Jack</name>
# <GPA>2.0</GPA>
# </student>
# <student IQ="genius">
# <name>Sara</name>
# <GPA>5.0</GPA>
# </student>
# <average>3.5</average>
# </math-class>
################################################################
# Extraction
xml = parsexml("""
<math-class>
<student>
<name>Jack</name>
<GPA>2.0</GPA>
</student>
<student>
<name>Sara</name>
<GPA>5.0</GPA>
</student>
<average>3.5</average>
</math-class>
""")
mathclass = MathClass(xml)
mathclass.students[2].log # "A genius with a GPA of 5.0 is found"