Skip to content

Commit 2944f38

Browse files
mkittirfourquet
andauthored
Document how to create an undefined reference (Ref) and detect that using isassigned (#35723)
* Document how to create a Ref to undef and how to detect is a Ref refers to undef * Document Ref{T}() behavior when T is a primitve bit type. * Change primitive to bitstype, isdefined to isassigned, doc isassigned * Document isassigned(::RefValue). Remove no invalid Ref language. * Remove duplicate isassigned docs for arrays in essentials.jl * Refer to undefined reference rather than undef for isassigned * isassigned reference docs, fix line returns in doc * Fix line returns for isassigned(RefValue) doc * Add backticks to quote code as suggested by @rfourquet Co-authored-by: Rafael Fourquet <fourquet.rafael@gmail.com> * Change `undef` to undefined, fix examples Change `undef` to undefined reference Add comments to examples Remove C_NULL example due to confusion List normal `Ref` usage first * Create a markdown header for examples * Clarify that error when attempting to deference Clarify that the act of dereferencing causes the error to be thrown. @rfourquet * Remove undefined Ref bitstype comparison Comparison of an undefined reference value bitstype to zero may be true. Insert a semicolon just to demonstrate usage but not the result. Co-authored-by: Rafael Fourquet <fourquet.rafael@gmail.com>
1 parent 3826279 commit 2944f38

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

base/refpointer.jl

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,52 @@ Creation of a `Ref` to a value `x` of type `T` is usually written `Ref(x)`.
1313
Additionally, for creating interior pointers to containers (such as Array or Ptr),
1414
it can be written `Ref(a, i)` for creating a reference to the `i`-th element of `a`.
1515
16-
When passed as a `ccall` argument (either as a `Ptr` or `Ref` type), a `Ref` object will be
17-
converted to a native pointer to the data it references.
16+
`Ref{T}()` creates a reference to a value of type `T` without initialization.
17+
For a bitstype `T`, the value will be whatever currently resides in the memory
18+
allocated. For a non-bitstype `T`, the reference will be undefined and attempting to
19+
dereference it will result in an error, "UndefRefError: access to undefined reference".
1820
19-
There is no invalid (NULL) `Ref` in Julia, but a `C_NULL` instance of `Ptr` can be passed to
20-
a `ccall` Ref argument.
21+
To check if a `Ref` is an undefined reference, use [`isassigned(ref::RefValue)`](@ref).
22+
For example, `isassigned(Ref{T}())` is `false` if `T` is not a bitstype.
23+
If `T` is a bitstype, `isassigned(Ref{T}())` will always be true.
24+
25+
When passed as a `ccall` argument (either as a `Ptr` or `Ref` type), a `Ref`
26+
object will be converted to a native pointer to the data it references.
27+
28+
A `C_NULL` instance of `Ptr` can be passed to a `ccall` `Ref` argument to initialize it.
2129
2230
# Use in broadcasting
23-
`Ref` is sometimes used in broadcasting in order to treat the referenced values as a scalar:
31+
`Ref` is sometimes used in broadcasting in order to treat the referenced values as a scalar.
32+
33+
# Examples
2434
2535
```jldoctest
26-
julia> isa.(Ref([1,2,3]), [Array, Dict, Int])
36+
julia> Ref(5)
37+
Base.RefValue{Int64}(5)
38+
39+
julia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Treat reference values as scalar during broadcasting
2740
3-element BitVector:
2841
1
2942
0
3043
0
44+
45+
julia> Ref{Function}() # Undefined reference to a non-bitstype, Function
46+
Base.RefValue{Function}(#undef)
47+
48+
julia> try
49+
Ref{Function}()[] # Dereferencing an undefined reference will result in an error
50+
catch e
51+
println(e)
52+
end
53+
UndefRefError()
54+
55+
julia> Ref{Int64}()[]; # A reference to a bitstype refers to an undetermined value if not given
56+
57+
julia> isassigned(Ref{Int64}()) # A reference to a bitstype is always assigned
58+
true
59+
60+
julia> Ref{Int64}(0)[] == 0 # Explicitly give a value for a bitstype reference
61+
true
3162
```
3263
"""
3364
Ref

base/refvalue.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,31 @@ mutable struct RefValue{T} <: Ref{T}
88
RefValue{T}(x) where {T} = new(x)
99
end
1010
RefValue(x::T) where {T} = RefValue{T}(x)
11+
"""
12+
isassigned(ref::RefValue) -> Bool
13+
14+
Test whether the given [`Ref`](@ref) is associated with a value.
15+
This is always true for a [`Ref`](@ref) of a bitstype object.
16+
Return `false` if the reference is undefined.
17+
18+
# Examples
19+
```jldoctest
20+
julia> ref = Ref{Function}()
21+
Base.RefValue{Function}(#undef)
22+
23+
julia> isassigned(ref)
24+
false
25+
26+
julia> ref[] = (foobar(x) = x)
27+
foobar (generic function with 1 method)
28+
29+
julia> isassigned(ref)
30+
true
31+
32+
julia> isassigned(Ref{Int}())
33+
true
34+
```
35+
"""
1136
isassigned(x::RefValue) = isdefined(x, :x)
1237

1338
function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T

doc/src/base/c.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Base.systemerror
2424
Base.windowserror
2525
Core.Ptr
2626
Core.Ref
27+
Base.isassigned(::Base.RefValue)
2728
Base.Cchar
2829
Base.Cuchar
2930
Base.Cshort

0 commit comments

Comments
 (0)