Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hasproperty and hasfield to Base RFC #30496

Merged
merged 10 commits into from
Feb 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ New library functions
Standard library changes
------------------------

* Added `Base.hasproperty` and `Base.hasfield` ([#28850]).

#### LinearAlgebra

* Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998]).
Expand Down
2 changes: 2 additions & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,9 @@ export
fieldnames,
fieldcount,
fieldtypes,
hasfield,
propertynames,
hasproperty,
isabstracttype,
isbitstype,
isprimitivetype,
Expand Down
19 changes: 19 additions & 0 deletions base/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,17 @@ fieldnames(::Core.TypeofBottom) =
throw(ArgumentError("The empty type does not have field names since it does not have instances."))
fieldnames(t::Type{<:Tuple}) = ntuple(identity, fieldcount(t))

"""
hasfield(T::Type, name::Symbol)

Returns a boolean indicating whether DataType has the specified field as one of
its own fields.
"""
function hasfield(::Type{T}, name::Symbol) where T
@_pure_meta
return fieldindex(T, name, false) > 0
end

"""
nameof(t::DataType) -> Symbol

Expand Down Expand Up @@ -1204,3 +1215,11 @@ REPL tab completion on `x.` shows only the `private=false` properties.
propertynames(x) = fieldnames(typeof(x))
propertynames(m::Module) = names(m)
propertynames(x, private) = propertynames(x) # ignore private flag by default

"""
hasproperty(x, s::Symbol)

Returns a boolean indicating whether the object `x` has the specified property as one of
its own properties.
"""
hasproperty(x, s::Symbol) = s in propertynames(x)
4 changes: 4 additions & 0 deletions test/reflection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ mutable struct TLayout
end
tlayout = TLayout(5,7,11)
@test fieldnames(TLayout) == (:x, :y, :z) == Base.propertynames(tlayout)
@test hasfield(TLayout, :y)
@test !hasfield(TLayout, :a)
@test hasproperty(tlayout, :x)
@test !hasproperty(tlayout, :p)
@test [(fieldoffset(TLayout,i), fieldname(TLayout,i), fieldtype(TLayout,i)) for i = 1:fieldcount(TLayout)] ==
[(0, :x, Int8), (2, :y, Int16), (4, :z, Int32)]
@test fieldnames(Complex) === (:re, :im)
Expand Down