BoundsError when NullableArray a field


#1

(Posted originally as NullableArrays issue #190, likely should have started here on discourse before filing an issue…)

Not sure if I missed something about iteration interfaces or NullableArrays, but consider the following (valid for NullableArrays 0.1.0 and master, julia v0.5.1 and 0.6.0-pre.beta.14, on ubuntu 14):

julia> type A
           arr::Array{String}
       end

julia> a = A(String[])
A(String[])

julia> start(a.arr)
1

julia> done(a.arr, 1)
true

julia> using NullableArrays

julia> type B
           arr::NullableArray{String}
       end

julia> b = B(NullableArray{String}[])
B(Nullable{String}[])

julia> start(b.arr)
(Base.OneTo(0), 1)

julia> done(b.arr, 1)
ERROR: BoundsError
Stacktrace:
 [1] getindex at ./number.jl:38 [inlined]
 [2] done(::NullableArrays.NullableArray{String,1}, ::Int64) at ./abstractarray.jl:753

To be sure, when NullableArray is not a field:

julia> c = NullableArray{String}[]
0-element Array{NullableArrays.NullableArray{String,N} where N,1}

julia> start(c)
1

julia> done(c, 1)
true

#2

Note that c is an Array of NullableArrays of Strings, and not a NullableArray of Strings which is more expected. As a regular Array, the start returns an integer position.

b.arr is a NullableArray of Strings, and as start is not defined for NullableArrays, it goes to AbstractArray definition which returns the range. To check if done, one needs to pass the state of the iterator which in b.arr's case is the tuple (Base.OneTo(0), 1) and indeed done(b.arr,(Base.OneTo(0), 1)) is true.

The confusion may be the result of the [] in the construction, which creates an array. The type B constructor has to force the Nullable{String} type on arr and uses convert(NullableArray{String},NullableArray{String}[]) which works because the converted array is empty.

Conclusion, probably a typo, but perhaps Julia syntax dynamism is getting confusing.


#3

I wish it were a typo :blush:, just some bad habits when creating empty arrays. Thanks for the clarification.