From d5bad22bd0e5b64b36e4e5f5f025003ac96b7ed3 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Tue, 1 Oct 2019 17:31:17 -0700 Subject: [PATCH] Use markdown files as docstring --- docs/src/index.md | 6 ++- src/ConstructionBase.jl | 81 +++++++++-------------------------------- src/constructorof.md | 62 +++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 66 deletions(-) create mode 100644 src/constructorof.md diff --git a/docs/src/index.md b/docs/src/index.md index 2ea5e2f..b25e3cf 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -3,6 +3,8 @@ ```@index ``` -```@autodocs -Modules = [ConstructionBase] +```@docs +ConstructionBase +ConstructionBase.constructorof +ConstructionBase.setproperties ``` diff --git a/src/ConstructionBase.jl b/src/ConstructionBase.jl index 293858e..b0b6bcc 100644 --- a/src/ConstructionBase.jl +++ b/src/ConstructionBase.jl @@ -3,71 +3,24 @@ module ConstructionBase export setproperties export constructorof +# Use markdown files as docstring: +for (name, path) in [ + :ConstructionBase => joinpath(dirname(@__DIR__), "README.md"), + :constructorof => joinpath(@__DIR__, "constructorof.md"), +] + # Don't fail when somehow importing docstrings doesn't work (we + # don't loose any functionalities for that). We use explicit + # `@docs` in `docs/src/index.md` to make sure importing docstrings + # succeeds in CI. + try + include_dependency(path) + str = read(path, String) + @eval @doc $str $name + catch err + @error "Failed to import docstring for $name" exception=(err, catch_backtrace()) + end +end -""" - constructorof(T::Type) - -Return an object `ctor` that can be used to construct objects of type `T` -from their field values. Typically `ctor` will be the type `T` with all parameters removed: -```jldoctest -julia> using ConstructionBase - -julia> struct T{A,B} - a::A - b::B - end - -julia> constructorof(T{Int,Int}) -T -``` -It is however not guaranteed, that `ctor` is a type at all: -```jldoctest; setup = :(using ConstructionBase) -julia> struct S - a - b - checksum - S(a,b) = new(a,b,a+b) - end - -julia> ConstructionBase.constructorof(::Type{<:S}) = - (a, b, checksum=a+b) -> (@assert a+b == checksum; S(a,b)) - -julia> constructorof(S)(1,2) -S(1, 2, 3) - -julia> constructorof(S)(1,2,4) -ERROR: AssertionError: a + b == checksum -``` -Instead `ctor` can be any object that satisfies the following properties: -* It must be possible to reconstruct an object from its fields: -```julia -ctor = constructorof(typeof(obj)) -@assert obj == ctor(fieldvalues(obj)...) -@assert typeof(obj) == typeof(ctor(fieldvalues(obj)...)) -``` -* The other direction should hold for as many values of `args` as possible: -```julia -ctor = constructorof(T) -fieldvalues(ctor(args...)) == args -``` -For instance given a suitable parametric type it should be possible to change -the type of its fields: -```jldoctest; setup = :(using ConstructionBase) -julia> struct T{A,B} - a::A - b::B - end - -julia> t = T(1,2) -T{Int64,Int64}(1, 2) - -julia> constructorof(typeof(t))(1.0, 2) -T{Float64,Int64}(1.0, 2) - -julia> constructorof(typeof(t))(10, 2) -T{Int64,Int64}(10, 2) -``` -""" @generated function constructorof(::Type{T}) where T getfield(parentmodule(T), nameof(T)) end diff --git a/src/constructorof.md b/src/constructorof.md new file mode 100644 index 0000000..a90748a --- /dev/null +++ b/src/constructorof.md @@ -0,0 +1,62 @@ + constructorof(T::Type) + +Return an object `ctor` that can be used to construct objects of type `T` +from their field values. Typically `ctor` will be the type `T` with all parameters removed: +```jldoctest +julia> using ConstructionBase + +julia> struct T{A,B} + a::A + b::B + end + +julia> constructorof(T{Int,Int}) +T +``` +It is however not guaranteed, that `ctor` is a type at all: +```jldoctest; setup = :(using ConstructionBase) +julia> struct S + a + b + checksum + S(a,b) = new(a,b,a+b) + end + +julia> ConstructionBase.constructorof(::Type{<:S}) = + (a, b, checksum=a+b) -> (@assert a+b == checksum; S(a,b)) + +julia> constructorof(S)(1,2) +S(1, 2, 3) + +julia> constructorof(S)(1,2,4) +ERROR: AssertionError: a + b == checksum +``` +Instead `ctor` can be any object that satisfies the following properties: +* It must be possible to reconstruct an object from its fields: +```julia +ctor = constructorof(typeof(obj)) +@assert obj == ctor(fieldvalues(obj)...) +@assert typeof(obj) == typeof(ctor(fieldvalues(obj)...)) +``` +* The other direction should hold for as many values of `args` as possible: +```julia +ctor = constructorof(T) +fieldvalues(ctor(args...)) == args +``` +For instance given a suitable parametric type it should be possible to change +the type of its fields: +```jldoctest; setup = :(using ConstructionBase) +julia> struct T{A,B} + a::A + b::B + end + +julia> t = T(1,2) +T{Int64,Int64}(1, 2) + +julia> constructorof(typeof(t))(1.0, 2) +T{Float64,Int64}(1.0, 2) + +julia> constructorof(typeof(t))(10, 2) +T{Int64,Int64}(10, 2) +```