Skip to content

Commit 2cd7855

Browse files
committed
Add eachof function for iterating while reading from io
This saves boilerplate versus a while !eof(io); read(io, T) loop. The function signature is patterned after the read(io, T) function signature. Prompted by #36132 but does not close #36132 I am open to better/clearer names for this function.
1 parent 865c636 commit 2cd7855

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

base/exports.jl

+1
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,7 @@ export
782782
close,
783783
countlines,
784784
eachline,
785+
eachof,
785786
eof,
786787
fd,
787788
fdio,

base/io.jl

+40
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,46 @@ eltype(::Type{<:EachLine}) = String
10031003

10041004
IteratorSize(::Type{<:EachLine}) = SizeUnknown()
10051005

1006+
struct EachOfIO{T, IOT <: IO}
1007+
stream::IOT
1008+
end
1009+
1010+
"""
1011+
eachof(io::IO, T)
1012+
1013+
Return an iterable object yielding [`read(io, T)`](@ref).
1014+
1015+
See also: [`skipchars`](@ref), [`eachline`](@ref), [`readuntil`](@ref)
1016+
1017+
!!! compat "Julia 1.6"
1018+
`eachof` requires Julia 1.6 or later.
1019+
1020+
# Examples
1021+
```jldoctest
1022+
julia> open("my_file.txt", "w") do io
1023+
write(io, "JuliaLang is a GitHub organization.\\n It has many members.\\n");
1024+
end;
1025+
1026+
julia> open("my_file.txt") do io
1027+
for c in eachof(io, Char)
1028+
c == '\\n' && break
1029+
print(c)
1030+
end
1031+
end
1032+
JuliaLang is a GitHub organization.
1033+
1034+
julia> rm("my_file.txt");
1035+
```
1036+
"""
1037+
eachof(stream::IOT, T::Type) where IOT<:IO = EachOfIO{T,IOT}(stream)
1038+
1039+
iterate(itr::EachOfIO{T}, state=nothing) where T =
1040+
eof(itr.stream) ? nothing : (read(itr.stream, T), nothing)
1041+
1042+
eltype(::Type{EachOfIO{T}}) where T = T
1043+
1044+
IteratorSize(::Type{<:EachOfIO}) = SizeUnknown()
1045+
10061046
# IOStream Marking
10071047
# Note that these functions expect that io.mark exists for
10081048
# the concrete IO type. This may not be true for IO types

doc/src/base/io-network.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Base.read!
1919
Base.readbytes!
2020
Base.unsafe_read
2121
Base.unsafe_write
22+
Base.eachof
2223
Base.peek
2324
Base.position
2425
Base.seek

test/read.jl

+6
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,12 @@ for (name, f) in l
300300

301301
cleanup()
302302

303+
verbose && println("$name eachof...")
304+
@test collect(eachof(io(), Char)) == Vector{Char}(text)
305+
@test collect(eachof(io(), UInt8)) == Vector{UInt8}(text)
306+
307+
cleanup()
308+
303309
verbose && println("$name countlines...")
304310
@test countlines(io()) == countlines(IOBuffer(text))
305311

0 commit comments

Comments
 (0)