NahaJuliaLib.jl
NahaJuliaJib is a library of small utilities that I wish Julia had, but, near as I can tell, doesn't yet.
Type Hierarchy
NahaJuliaLib.allsubtypes — Functionallsubtypes(t::Type)Return a Vector of t and all of its subtypes.
NahaJuliaLib.showsubtypes — Functionshowsubtypes(t::Type) Print a hierarchical list of t and all of its subtypes.
NahaJuliaLib.pedigree — Functionpedigree(t::Type)Return a Vector of t and its supertypes.
Defining Object Properties
Rather than use a condirional tree to determine which peoperty is being queried by getproperty, we can method specialize on Val types. We should then be able to automate propertynames based on the defined methods.
A struct might have fields, which are exposed as properties. The Val methods will not shadow the method that implements that.
NahaJuliaLib.@njl_getprop — Macro@njl_getprop MyStructDefine the methods necessary so that Val specialized getproperty methods for MyStruct will find Val specialized properties.
Here's a trivial, but illustrative example:
using NahaJuliaLib
struct MyStruct
a::Int
end
@njl_getprop MyStruct
function Base.getproperty(o::MyStruct, prop::Val{:b})
o.a * 2
end
ms = MyStruct(3)
MyStruct(3)
ms.a
ms.b
propertynames(ms)2-element Vector{Symbol}:
:a
:bTracing functions
Sometimes when debugging one wants to track the call and return of certain specified functions.
NahaJuliaLib.@trace — Macro@trace(global_flag, definition)Cause the call arguments and return values of the function defined by definition to be logged if global_flag is true at run time. definition should define a method.
NahaJuliaLib.analyze_traces — Functionanalyze_traces(log::VectorLogger)Given a log containinig log records produced by @trace, return a vector of TraceRecords. Each of those TraceRecords is the root of a tree of TraceRecords that represent the call tree.
Use show_trace to print the call hierarchy in a human readable form.
NahaJuliaLib.show_trace — Functionshow_trace(trace::TraceRecord)Print the specified TraceRecord hierarchy in a human readable form.
using Logging
using VectorLogging
using NahaJuliaLib
@trace(trace_hanoi,
function hanoi(from, to, other, count)
if count == 0
return nothing
else
hanoi(from, other, to, count - 1)
println("move 1 from $from to $to")
hanoi(other, to, from, count - 1)
return (from, to) # arbitrary result to show
end
end
)
trace_hanoi = true
logger = VectorLogger()
with_logger(logger) do
hanoi(:a, :b, :c, 3)
end
begin
traces = analyze_traces(logger)
show_trace(traces[1])
endmove 1 from a to b
move 1 from a to c
move 1 from b to c
move 1 from a to b
move 1 from c to a
move 1 from c to b
move 1 from a to b
(Main.hanoi)(a, b, c, 3) => (:a, :b)
(Main.hanoi)(a, c, b, 2) => (:a, :c)
(Main.hanoi)(a, b, c, 1) => (:a, :b)
(Main.hanoi)(a, c, b, 0) => nothing
(Main.hanoi)(c, b, a, 0) => nothing
(Main.hanoi)(b, c, a, 1) => (:b, :c)
(Main.hanoi)(b, a, c, 0) => nothing
(Main.hanoi)(a, c, b, 0) => nothing
(Main.hanoi)(c, b, a, 2) => (:c, :b)
(Main.hanoi)(c, a, b, 1) => (:c, :a)
(Main.hanoi)(c, b, a, 0) => nothing
(Main.hanoi)(b, a, c, 0) => nothing
(Main.hanoi)(a, b, c, 1) => (:a, :b)
(Main.hanoi)(a, c, b, 0) => nothing
(Main.hanoi)(c, b, a, 0) => nothing