How to override "="

284 views Asked by At

I was looking into Haxe abstracts and was very interested in building an abstract that would wrap a class and unify it to, in my case, an Int.

@:forward()
abstract Abs(Op)
{
    public inline function new(value:Int = 0, name:String = "unnamed" )
    {
        this = new Op();
        this.value = value;
        this.name = name;

    }

    @:to
    private inline function toInt():Int
    {
        return this.value;
    }
}

class Op
{
    public var value:Int = 0;
    public var name:String = "no name";

    public function new()
    {

    }
}

The problem I ran in to is when defining a @:from method - it has to be static and can take only one parameter - a new value. So whenever I set the abstract's instance value from the @:from method I will have to create a new instance of the abstract, thus resetting all the variables.

Basically what I'm talking about is this:

var a = new Abs(5, "my abs"); // value is 5; name is "my abs"
a = 100; // value is 100; name is reset to "unnamed" but I want it to be preserved

As much as I could find out we cannot overload the = operator in abstracts other than through implicit casting with a @:from method and I haven't found a way to really achieve this with macros.

If you have any ideas on how this can be done, please provide a minimalist example.

1

There are 1 answers

7
Mark Knol On

It depends what you want to do, but if you use this:

var a = new Abs(5, "my abs");
var myInt:Int = a;

It will use the abstract Abs.toInt function.

@:to
private inline function toInt():Int
{
    return this.value;
}

The other way around also works:

var million = 1000000;
var myAbs:Abs = million;

It will use the static Abs.fromInt function.

@:from
static inline function fromInt(value:Int)
{
    return new Abs(value, "what");
}

This is because it uses the implicit cast. http://haxe.org/manual/types-abstract-implicit-casts.html

Try it yourself: http://try.haxe.org/#Ae1a8

Is that what you are looking for?