I have a type DataRow. It’s goal is to act like a row of a DataFrame, but standing on its own.

It’s one dimensional

It’s indexable

It iterates through values

It stores values in a Vector{Any} internally

I’m trying to extend in-place broadcasting, via this link.

If r is a DataRow with two elements, I would like

r .= [3, 4]

to update the values of r. I’ve implemented

Base.BroadcastStyle(::Type{<:DataRow}) = Broadcast.Style{DataRow}()
function copyto!(dest::DataRow, bc::Broadcasted{Broadcast.DefaultArrayStyle{1}})
println("success")
nothing
end

This feels like the method to implement, but I haven’t yet been able to hit this method

julia> r .= [1, 2]
ERROR: MethodError: no method matching copyto!(::DataRow, ::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(identity),Tuple{Array{Int64,1}}})

Overall I’m pretty lost about how to implement broadcasting. Any help is appreciated, particularly if someone could point me to a good implementation in some package that I can copy

Base.BroadcastStyle(::Type{<:DataRow}) = Broadcast.Style{DataRow}()
function Base.copyto!(r::DataRow, bc::Broadcasted)
bcf = Broadcast.flatten(bc)
bcf2 = Base.Broadcast.preprocess(r, bcf)
for i in 1:length(r)
r[i] = bcf2[i]
end
r
end

EDIT : I have no idea what these preprocess steps are. Can someone help me understand tem?

I am not sure you need to flatten (you are not using any internal structure of bc yet in your code), preprocess is probably needed (to do unaliasing). Now for 1:length(r) is probably safe, but a normal thing would be to use axes(bcf2, 1) (but I think it should be the same in this case as you are not accepting non standard indexing in bcf2 anyway - right?).