Sorry,
but now I have some doubt relative to concatenation for my redefined Array.

In my exampled (attached) I've redefined AbstractArray creating a simple container for an Array, and I redefined also start() / next() / done() calling same operations for internal Array, but in following few lines of code:

a = MyArr{2}(1,2)
a[1,1] = "hello"
a[1,2] = "world"
cat(1, a, ["bob" "alice"])

cat() fails with following error:

ERROR: MethodError: `next` has no method matching next(::Array{AbstractString,2})
Closest candidates are:
  next(::Array{T,N}, ::Any)
  next(::AbstractArray{T,N}, ::Any)
 in _unsafe_batchsetindex! at multidimensional.jl:328
 in setindex! at abstractarray.jl:572
 in cat_t at abstractarray.jl:840
 in vcat at abstractarray.jl:861

Anyone can indicate me what MUST be reimplemented for AbstractArray{T,N} to support concatenation operations?

Many thanks in advance

Leonardo



Il 13/09/2015 09:48, Leonardo ha scritto:
Many thanks!
I've understood that parametric type and number of dimension are necessary, then I can write something like:
type MyArr{N} <: AbstractArray{String,N}
...
end

but, cause I want constructor receives the range of components for each dimension like:
a = MyArr{3}(2,3,4)
I MUST ensure that parametric dimension be consistent with passed number of indexes, highlighting (with an Error) that forms like:
a = MyArr{3}(2,3)
are illegal (see my attached example)

(maybe OT: I think that using Integer as Type Parameter is a bit confusing for people like me that have developed by many year in other languages with generics as Java, C++, C# because use of a object-parameter opposed to conventional type-parameter is a bit odd; see also https://groups.google.com/forum/#!topic/julia-users/3NM7tZV5buQ )

Leonardo

P.S. surprisingly chapters http://docs.julialang.org/en/release-0.4/manual/interfaces/ and http://docs.julialang.org/en/latest/manual/interfaces/ are unavailable into relative PDFs on readthedocs.org



Il 11/09/2015 14:46, Matt Bauman ha scritto:
On Friday, September 11, 2015 at 3:11:48 AM UTC-4, Leonardo wrote:

    I like to have a /unique/ type that contains only a specified
    type and that can handle any dimension, but only during object
    instancing (not during subsequent lifecycle of object, also if
    both phases are at runtime), than parametrized dimension (the
    N in AbstractArray{T,N}) is not useful for me.


You can have a constructor that deals with the parameter for you:

MyArr(number_of_dimensions::Int) = MyArr{Any, number_of_dimensions}()

I'm afraid I still don't understand why you want to do this, so my answers probably aren't all that helpful.

    But - if I understood your indications - there is no way to do
    this without redefine a bunch of methods.
    At least, can I find somewhere a minimal list of these methods?


That's correct. Omitting the dimensionality isn't a supported way to subtype AbstractArray. I suppose you can still do it, but being unsupported means that you're on your own to figure out what all needs to be re-implemented. And unfortunately, I'm afraid that the list isn't so minimal. It's a part of the AbstractArray definition that is very heavily leveraged in the base code to improve performance and specify behavior.

You can start to get a sense of how heavily these parameters are used by looking at the methods defined for AbstractArray{T,1} (AbstractVector) and AbstractArray{T,2} (AbstractMatrix):

julia> methodswith(AbstractVector)
151-element Array{Method,1}: …

julia> methodswith(AbstractMatrix)
164-element Array{Method,1}: …

Those don't even include methods defined for arbitrary dimensionality but still require N to be defined, like `ndims{T,N}(A::AbstractArray{T,N}) = N`.



using Base

type MyArr{N} <: AbstractArray{String,N}
        data::Array{String}
        
        function MyArr(dims::Int...)
                if length(dims) != N
                        throw(ErrorException("Wrong number of dimensions 
(different from Parametric dimension)"))
                end
                
                o = new()
                o.data = Array{String}(dims...)
                
                return o
        end
end

#Mandatory
function Base.size(A::MyArr)
        return Base.size(A.data)
end

Base.linearindexing{T<:MyArr}(::Type{T}) = Base.LinearFast()

#Mandatory?
function Base.getindex(A::MyArr, I::Int...)
        return A.data[I...]
end

function Base.setindex!(A::MyArr, v::Any, I::Int...)
        A.data[I...] = v
end

function Base.start(A::MyArr)
        return Base.start(A.data)
end

function Base.next(A::MyArr, state::Any)
        return Base.next(A.data)
end

function Base.done(A::MyArr, state::Any)
        return Base.done(A.data)
end

Reply via email to