Making peace with Images.jl #168
Description
It's fairly well known that using DataArrays, Images
produces a whole slew of ambiguity warnings. I'm contemplating trying to end those warnings by doing the tedious work of defining stub functions that throw errors for the ambiguous cases. For this to work well, we'll need to make it independent of the order in which Images and DataArrays are loaded, hence there may need to be some cooperation between the projects.
It's a little tricky making this work, but I may have a viable design. As a reminder, here are the constraints:
- The ambiguity-resolving methods (more specific than those defined in any of the packages) must come before the ambiguous methods. For this to work, all the relevant types (from both DataArrays and Images) have to be defined. Conversely, we don't want to add those definitions until all relevant types (i.e., both packages) are present.
- With precompilation, you can't just insert
if isdefined(Main, :Images)
somewhere in your code; precompilation will "lock in" the state at the time of compilation, and not be adjustable to the situation at the time of usage. All code that checks about the existence of another package must be in the__init__
function. __init__
runs as the final step of module definition/initialization. Consequently, if you add the ambiguity-resolving functions to Images' or DataArrays'__init__
function, it will be too late.
On the Images side, I plan to split out an ImagesCore
module that contains the basic type definitions, which then gets used by Images
. (It could be an internal module, but I wonder if @SimonDanisch would be happier if it were a standalone package so that packages like ImageMagick
could use just the core and not bring in all the rest of the code.) I plan to place the check for DataArrays
inside ImagesCore
. In other words, it will look like this:
module Images
using ImagesCore
...
# code, including the stuff that causes ambiguity warnings with DataArrays
end
module ImagesCore
# define types
function __init__()
if isdefined(Main, :DataArrays)
eval(Expr(:import, :DataArraysImages))
end
end
end
Since ImagesCore gets loaded at the beginning of Images
, its __init__
function will execute in time to prevent the ambiguities. DataArrays
could use a similar strategy, and also import DataArraysImages
.
Interested?