Adding a payload to a type
Simen Kjærås
simen.kjaras at gmail.com
Mon May 27 09:27:37 UTC 2019
On Monday, 27 May 2019 at 08:40:45 UTC, Amex wrote:
> I have some types I've declared and I'd like to magically
> extend them and add data. The problem is I inheriting from them
> them is bad news.
>
> Suppose, for example, I have an image type that is used in an
> application. For a small part of the application it needs to
> associate with each image type an xy coordinate type that adds
> a coordinate to the image to be used by the part of the app
> that needs to have coordinates for the image. The rest of the
> app does not care or need the xy coordinates.
>
> Inheritance solves this problem in some sense except it
> doesn't. If I want to add new data then it breaks.
>
> class image;
> class xy : image; // can only add an image.
> class z : ??; ?? could be xy, image, or something else
>
> Inheritance is not the correct thing to do here. I only want to
> associate data with an object. The hierarchy does not matter.
>
>
> I could add a payload type to image but this causes problems
> since it would have to be void or of a singular type. Mainly it
> causes problems with the serializer I'm using since it can't
> handle voids(I might be able to get it to work with a special
> type but it will not be easy).
>
>
> I could, of course, add a parallel struct that somehow
> associates the image it's extra data but to keep them in sync
> will not be easy since it will have to persist between runs(so
> the address could not be used).
>
> One could think of what I'm trying to do is create a tuple that
> holds the image and any other data.
>
> tuple(tuple(image, xy), z) // the outer tuple may occur later
> without knowing that the image has been "wrapped".
>
> How does one normally handle this? It seems like something
> really simple to do(attach data) but it has no real
> programmatic way to do naturally that works with oop.
>
>
> The main thing is that attaching different data should "stack"
> and not effect the base type or break the type hierarchy. If
> something takes an image it should take any extended object.
>
>
> I feel like the only way to do this is to create a special type
> that can be serialized properly and is part of the base
> class... I'll have to do it for all the classes. Hopefully
> someone has some better ideas?
There's of course many different ways to skin a cat. Here's my
first idea:
class Image {
// regular image stuff
Metadata[] metadata;
T getMetadata(T : Metadata)() {
foreach (e; metadata) {
if (cast(T)e !is null) {
return cast(T)e;
}
}
return null;
}
}
abstract class Metadata {}
class Coordinates : Metadata {
int x, y;
this(int x, int y) {
this.x = x;
this.y = y;
}
}
unittest {
auto img = new Image();
img.metadata ~= new Coordinates(1,2);
auto coords = img.getMetadata!Coordinates;
assert(coords.x == 1);
assert(coords.y == 2);
}
This could easily be extended to support multiple metadata of the
same type by adding a name field or such.
--
Simen
More information about the Digitalmars-d-learn
mailing list