Reputation: 19162
type ExtendedJumpArray{T,T2} <: AbstractArray{Float64,1}
u::T
jump_u::T2
end
Base.length(A::ExtendedJumpArray) = length(A.u)
Base.size(A::ExtendedJumpArray) = (length(A),)
function Base.getindex(A::ExtendedJumpArray,i::Int)
i <= length(A.u) ? A.u[i] : A.jump_u[i-length(A.u)]
end
function Base.setindex!(A::ExtendedJumpArray,v,i::Int)
i <= length(A.u) ? (A.u[i] = v) : (A.jump_u[i-length(A.u)] = v)
end
similar(A::ExtendedJumpArray) = deepcopy(A)
indices(A::ExtendedJumpArray) = Base.OneTo(length(A.u) + length(A.jump_u))
I thought I was the cool kid on the block, creating an array which could index past its length (I am doing it for a specific reason). But Julia apparently doesn't like this:
julia> ExtendedJumpArray([0.2],[-2.0])
Error showing value of type ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}:
ERROR: MethodError: no method matching inds2string(::Int64)
Closest candidates are:
inds2string(::Tuple{Vararg{AbstractUnitRange,N}}) at show.jl:1485
in _summary(::ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}, ::Int64) at .\show.jl:1490
in #showarray#330(::Bool, ::Function, ::IOContext{Base.Terminals.TTYTerminal}, ::ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}, ::Bool) at .\show.jl:1599
in display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::MIME{Symbol("text/plain")}, ::ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}) at .\REPL.jl:132
in display(::Base.REPL.REPLDisplay{Base.REPL.LineEditREPL}, ::ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}) at .\REPL.jl:135
in display(::ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}) at .\multimedia.jl:143
in print_response(::Base.Terminals.TTYTerminal, ::Any, ::Void, ::Bool, ::Bool, ::Void) at .\REPL.jl:154
in print_response(::Base.REPL.LineEditREPL, ::Any, ::Void, ::Bool, ::Bool) at .\REPL.jl:139
in (::Base.REPL.##22#23{Bool,Base.REPL.##33#42{Base.REPL.LineEditREPL,Base.REPL.REPLHistoryProvider},Base.REPL.LineEditREPL,Base.LineEdit.Prompt})(::Base.LineEdit.MIState, ::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Bool) at .\REPL.jl:652
in run_interface(::Base.Terminals.TTYTerminal, ::Base.LineEdit.ModalInterface) at .\LineEdit.jl:1579
in run_frontend(::Base.REPL.LineEditREPL, ::Base.REPL.REPLBackendRef) at .\REPL.jl:903
in run_repl(::Base.REPL.LineEditREPL, ::Base.##932#933) at .\REPL.jl:188
in _start() at .\client.jl:360
Is there an easy way to do this without breaking the show
methods, and whatever else may be broken? Or is there a better way to do this in general?
Upvotes: 2
Views: 88
Reputation: 31362
Indices needs to return a tuple, just like size
.
julia> Base.similar(A::ExtendedJumpArray) = deepcopy(A)
julia> Base.indices(A::ExtendedJumpArray) = (Base.OneTo(length(A.u) + length(A.jump_u)),)
julia> ExtendedJumpArray([0.2],[-2.0])
2-element ExtendedJumpArray{Array{Float64,1},Array{Float64,1}}:
0.2
-2.0
julia> length(ans)
1
Having indices
and size
disagree in the dimensionality of an array, though, is likely to end with confusion and strife. Some functions use size
, whereas others use indices
. See display vs. length above.
Upvotes: 2