diff --git a/src/ScopedValues.jl b/src/ScopedValues.jl index 1cafbe3..4151190 100644 --- a/src/ScopedValues.jl +++ b/src/ScopedValues.jl @@ -251,6 +251,20 @@ struct ScopedFunctor{F} end (sf::ScopedFunctor)() = @enter_scope sf.scope sf.f() +""" + get(val::ScopedValue{T1}, default::T2)::Union{T1, T2} + +Like the single-argument [`ScopedValues.get`](@ref), but returns the +provided `default` (rather than `nothing`) if `val` has no default. +Also, does not wrap the return in `Some`. +""" +function get(val::ScopedValue{T1}, default::T2) where {T1, T2} + scope = current_scope() + scope === nothing && return isassigned(val) ? val.default : default + scope = scope::Scope + return Base.get(scope.values, val, isassigned(val) ? val.default : default) +end + @deprecate scoped with end # module ScopedValues diff --git a/test/runtests.jl b/test/runtests.jl index 7801d14..6a7b90b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -141,3 +141,15 @@ end end sf() end + +const sval_unassigned = ScopedValue{Int}() +@testset "get with default" begin + @test ScopedValues.get(sval_unassigned, nothing) == nothing + @test ScopedValues.get(sval_unassigned, -1) == -1 + @with sval_unassigned=>10 begin + @test ScopedValues.get(sval_unassigned, -1) == 10 + end + @static if VERSION >= v"1.9" + @test 0 == @allocations ScopedValues.get(sval_unassigned, nothing) + end +end