module My
const Here = My
macro fieldsof(Texpr)
T = eval(Texpr)
names_and_types = zip(fieldnames(T), fieldtypes(T))
fields = (:($(esc(a))::$(esc(A))) for (a, A) in names_and_types)
Expr(:block, fields...)
end
fieldsof(T) = macroexpand(Here, :(@fieldsof($T)))
abstract type AbstractPerson end
name(x::AbstractPerson) = x.name
age(x::AbstractPerson) = x.age
data(x::AbstractPerson) = x.data
struct Person{T} <: AbstractPerson
name::String
age::Int
data::T
end
abstract type AbstractStudent <: AbstractPerson end
grade(x::AbstractStudent) = x.grade
struct Student{T} <: AbstractStudent
@fieldsof Person{:T}
grade::Int
end
end
Main.My
My.fieldsof(My.Person{:T})
quote name::String age::Int64 data::T end
My.fieldsof(My.Person{:T}) |> Meta.show_sexpr
(:block, (:(::), :name, String), (:(::), :age, Int64), (:(::), :data, :T) )
p = My.Person("Ken", 28, "魔術師")
Main.My.Person{String}("Ken", 28, "魔術師")
@show My.name(p)
@show My.age(p)
@show My.data(p)
;
My.name(p) = "Ken" My.age(p) = 28 My.data(p) = "魔術師"
My.fieldsof(My.Student{:T})
quote name::String age::Int64 data::T grade::Int64 end
s = My.Student("Taro", 14, Dict("好き"=>"カレーライス", "嫌い"=>"ピーマン"), 8)
Main.My.Student{Dict{String, String}}("Taro", 14, Dict("好き" => "カレーライス", "嫌い" => "ピーマン"), 8)
@show My.name(s)
@show My.age(s)
@show My.data(s)
@show My.grade(s)
;
My.name(s) = "Taro" My.age(s) = 14 My.data(s) = Dict("好き" => "カレーライス", "嫌い" => "ピーマン") My.grade(s) = 8