@@ -54,10 +54,12 @@ See also [`required`](@ref) and [`default`](@ref).
54
54
"""
55
55
transformed (:: StatsStep , :: NamedTuple ) = ()
56
56
57
- _get (a:: NTuple{N,Symbol} , @nospecialize (nt:: NamedTuple )) where N =
58
- map (s-> getfield (nt, s), a)
59
- _get (a:: NamedTuple{S1} , nt:: NamedTuple{S2} ) where {S1,S2} =
60
- map (s-> getfield (ifelse (sym_in (s, S2), nt, a), s), S1)
57
+ _get (nt:: NamedTuple , args:: Tuple{Vararg{Symbol}} ) =
58
+ map (s-> getfield (nt, s), args)
59
+
60
+ # This method is useful for obtaining default values
61
+ _get (nt:: NamedTuple , args:: NamedTuple ) =
62
+ map (s-> getfield (ifelse (sym_in (s, keys (nt)), nt, args), s), keys (args))
61
63
62
64
"""
63
65
groupargs(s::StatsStep, ntargs::NamedTuple)
@@ -75,7 +77,7 @@ Instead, one should define methods for
75
77
See also [`combinedargs`](@ref).
76
78
"""
77
79
groupargs (s:: StatsStep , @nospecialize (ntargs:: NamedTuple )) =
78
- (_get (required (s), ntargs )... , _get (default (s), ntargs )... ,
80
+ (_get (ntargs, required (s))... , _get (ntargs, default (s))... ,
79
81
transformed (s, ntargs)... )
80
82
81
83
"""
@@ -162,6 +164,15 @@ function show(io::IO, ::MIME"text/plain", p::AbstractStatsProcedure{A,T}) where
162
164
end
163
165
end
164
166
167
+ """
168
+ _get_default(p::AbstractStatsProcedure, ntargs::NamedTuple)
169
+
170
+ Obtain default values for arguments of each [`StatsStep`](@ref) in procedure `p`
171
+ and then merge any default value for arguments not found in `ntargs` into `ntargs`.
172
+ """
173
+ _get_default (p:: AbstractStatsProcedure , @nospecialize (ntargs:: NamedTuple )) =
174
+ merge ((default (s) for s in p). .. , ntargs)
175
+
165
176
"""
166
177
SharedStatsStep
167
178
@@ -336,19 +347,20 @@ function show(io::IO, ::MIME"text/plain", p::PooledStatsProcedure)
336
347
end
337
348
338
349
"""
339
- StatsSpec{Alias, T<:AbstractStatsProcedure}
350
+ StatsSpec{T<:AbstractStatsProcedure}
340
351
341
352
Record the specification for a statistical procedure of type `T`.
342
353
343
354
An instance of `StatsSpec` is callable and
344
355
its fields provide all information necessary for conducting the procedure.
345
- An optional name for the specification can be attached as parameter `Alias` .
356
+ An optional name for the specification can be specified .
346
357
347
358
# Fields
348
- - `args::NamedTuple`: arguments for the [`StatsStep`](@ref)s in `T`.
359
+ - `name::String`: a name for the specification (takes `""` if not specified).
360
+ - `args::NamedTuple`: arguments for the [`StatsStep`](@ref)s in `T` (default values are merged into `args` if not found in `args`).
349
361
350
362
# Methods
351
- (sp::StatsSpec{A, T})(; verbose::Bool=false, keep=nothing, keepall::Bool=false)
363
+ (sp::StatsSpec{T})(; verbose::Bool=false, keep=nothing, keepall::Bool=false)
352
364
353
365
Execute the procedure of type `T` with the arguments specified in `args`.
354
366
By default, a dedicated result object for `T` is returned if it is available.
@@ -359,37 +371,38 @@ Otherwise, the last value returned by the last [`StatsStep`](@ref) is returned.
359
371
- `keep=nothing`: names (of type `Symbol`) of additional objects to be returned.
360
372
- `keepall::Bool=false`: return all objects returned by each step.
361
373
"""
362
- struct StatsSpec{Alias, T<: AbstractStatsProcedure }
374
+ struct StatsSpec{T<: AbstractStatsProcedure }
375
+ name:: String
363
376
args:: NamedTuple
364
377
StatsSpec (name:: Union{Symbol,String} ,
365
378
T:: Type{<:AbstractStatsProcedure} , @nospecialize (args:: NamedTuple )) =
366
- new {Symbol( name),T} ( args)
379
+ new {T} ( string ( name), args)
367
380
end
368
381
369
382
"""
370
- ==(x::StatsSpec{A1, T}, y::StatsSpec{A2, T})
383
+ ==(x::StatsSpec{T}, y::StatsSpec{T})
371
384
372
385
Test whether two instances of [`StatsSpec`](@ref)
373
386
with the same parameter `T` also have the same field `args`.
374
387
375
388
See also [`≊`](@ref).
376
389
"""
377
- == (x:: StatsSpec{A1, T} , y:: StatsSpec{A2, T} ) where {A1,A2,T} = x. args == y. args
390
+ == (x:: StatsSpec{T} , y:: StatsSpec{T} ) where T = x. args == y. args
378
391
379
392
"""
380
- ≊(x::StatsSpec{A1, T}, y::StatsSpec{A2, T})
393
+ ≊(x::StatsSpec{T}, y::StatsSpec{T})
381
394
382
395
Test whether two instances of [`StatsSpec`](@ref)
383
396
with the same parameter `T` also have the field `args`
384
397
containing the same sets of key-value pairs
385
398
while ignoring the orders.
386
399
"""
387
- ≊ (x:: StatsSpec{A1, T} , y:: StatsSpec{A2, T} ) where {A1,A2,T} = x. args ≊ y. args
400
+ ≊ (x:: StatsSpec{T} , y:: StatsSpec{T} ) where T = x. args ≊ y. args
388
401
389
- _procedure (:: StatsSpec{A, T} ) where {A,T} = T
402
+ _procedure (:: StatsSpec{T} ) where T = T
390
403
391
- function (sp:: StatsSpec{A, T} )(;
392
- verbose:: Bool = false , keep= nothing , keepall:: Bool = false ) where {A,T}
404
+ function (sp:: StatsSpec{T} )(;
405
+ verbose:: Bool = false , keep= nothing , keepall:: Bool = false ) where T
393
406
args = verbose ? merge (sp. args, (verbose= true ,)) : sp. args
394
407
ntall = result (T, foldl (|> , T (), init= args))
395
408
if keepall
@@ -416,12 +429,12 @@ function (sp::StatsSpec{A,T})(;
416
429
end
417
430
end
418
431
419
- show (io:: IO , :: StatsSpec{A} ) where {A} = print (io, A == Symbol ( " " ) ? " unnamed" : A )
432
+ show (io:: IO , sp :: StatsSpec ) = print (io, sp . name == " " ? " unnamed" : sp . name )
420
433
421
434
_show_args (:: IO , :: StatsSpec ) = nothing
422
435
423
- function show (io:: IO , :: MIME"text/plain" , sp:: StatsSpec{A, T} ) where {A,T}
424
- print (io, A == Symbol ( " " ) ? " unnamed" : A , " (" , typeof (sp). name. name,
436
+ function show (io:: IO , :: MIME"text/plain" , sp:: StatsSpec{T} ) where T
437
+ print (io, sp . name == " " ? " unnamed" : sp . name , " (" , typeof (sp). name. name,
425
438
" for " , T. parameters[1 ], " )" )
426
439
_show_args (io, sp)
427
440
end
@@ -517,19 +530,18 @@ function proceed(sps::AbstractVector{<:StatsSpec};
517
530
end
518
531
519
532
function _parse! (options:: Expr , args)
520
- noproceed = false
521
533
for arg in args
522
534
# Assume a symbol means the kwarg takes value true
523
535
if isa (arg, Symbol)
524
536
if arg == :noproceed
525
- noproceed = true
537
+ return true
526
538
else
527
539
key = Expr (:quote , arg)
528
540
push! (options. args, Expr (:call , :(=> ), key, true ))
529
541
end
530
542
elseif isexpr (arg, :(= ))
531
543
if arg. args[1 ] == :noproceed
532
- noproceed = arg. args[2 ]
544
+ return arg. args[2 ]
533
545
else
534
546
key = Expr (:quote , arg. args[1 ])
535
547
push! (options. args, Expr (:call , :(=> ), key, arg. args[2 ]))
@@ -538,18 +550,24 @@ function _parse!(options::Expr, args)
538
550
throw (ArgumentError (" unexpected option $arg " ))
539
551
end
540
552
end
541
- return noproceed
553
+ return false
542
554
end
543
555
544
556
function _spec_walker1 (x, parsers, formatters, ntargs_set)
545
- @capture (x, StatsSpec (formatter_ (parser_ (rawargs__))... )(;o__)) || return x
557
+ @capture (x, spec_ (formatter_ (parser_ (rawargs__))... )(;o__)) || return x
558
+ # spec may be a GlobalRef
559
+ name = spec isa Symbol ? spec : spec. name
560
+ name == :StatsSpec || return x
546
561
push! (parsers, parser)
547
562
push! (formatters, formatter)
548
563
return :(push! ($ ntargs_set, $ parser ($ (rawargs... ))))
549
564
end
550
565
551
566
function _spec_walker2 (x, parsers, formatters, ntargs_set)
552
- @capture (x, StatsSpec (formatter_ (parser_ (rawargs__))... )) || return x
567
+ @capture (x, spec_ (formatter_ (parser_ (rawargs__))... )) || return x
568
+ # spec may be a GlobalRef
569
+ name = spec isa Symbol ? spec : spec. name
570
+ name == :StatsSpec || return x
553
571
push! (parsers, parser)
554
572
push! (formatters, formatter)
555
573
return :(push! ($ ntargs_set, $ parser ($ (rawargs... ))))
@@ -613,7 +631,8 @@ macro specset(args...)
613
631
isexpr (specs, :block , :for ) ||
614
632
throw (ArgumentError (" last argument to @specset must be begin/end block or for loop" ))
615
633
616
- parsers, formatters, ntargs_set = Symbol[], Symbol[], NamedTuple[]
634
+ # parser and formatter may be GlobalRef
635
+ parsers, formatters, ntargs_set = [], [], NamedTuple[]
617
636
walked = postwalk (x-> _spec_walker1 (x, parsers, formatters, ntargs_set), specs)
618
637
walked = postwalk (x-> _spec_walker2 (x, parsers, formatters, ntargs_set), walked)
619
638
nparser = length (unique! (parsers))
0 commit comments