Thread overview
override '.' member access
Jan 25, 2011
spir
Jan 25, 2011
Simen kjaeraas
Jan 25, 2011
spir
Jan 26, 2011
Simen kjaeraas
Jan 26, 2011
spir
Jan 26, 2011
spir
January 25, 2011
Hello,

Cannot find corresponding opSomething method, if any. (opDispatch seems to specialise for method call.)
Else, how to catch obj.member?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

January 25, 2011
spir <denis.spir@gmail.com> wrote:

> Hello,
>
> Cannot find corresponding opSomething method, if any. (opDispatch seems to specialise for method call.)
> Else, how to catch obj.member?

opDispatch is likely what you want. with the @property annotation, it
will readily support obj.member; and obj.member = foo; syntax.

-- 
Simen
January 25, 2011
On 01/25/2011 10:29 PM, Simen kjaeraas wrote:
> spir <denis.spir@gmail.com> wrote:
>
>> Hello,
>>
>> Cannot find corresponding opSomething method, if any. (opDispatch seems to
>> specialise for method call.)
>> Else, how to catch obj.member?
>
> opDispatch is likely what you want. with the @property annotation, it
> will readily support obj.member; and obj.member = foo; syntax.

Thank you, Simen, i'll try using opDispatch with @property. But I'm not sure how to write that concretely. My use case is of a type holding a string[AnyThing] AA called symbols. Then, I wish to map
	obj.id
to
	obj.symbols["id"]
(hope I'm clear)

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

January 26, 2011
spir <denis.spir@gmail.com> wrote:

> On 01/25/2011 10:29 PM, Simen kjaeraas wrote:
>> spir <denis.spir@gmail.com> wrote:
>>
>>> Hello,
>>>
>>> Cannot find corresponding opSomething method, if any. (opDispatch seems to
>>> specialise for method call.)
>>> Else, how to catch obj.member?
>>
>> opDispatch is likely what you want. with the @property annotation, it
>> will readily support obj.member; and obj.member = foo; syntax.
>
> Thank you, Simen, i'll try using opDispatch with @property. But I'm not sure how to write that concretely. My use case is of a type holding a string[AnyThing] AA called symbols. Then, I wish to map
> 	obj.id
> to
> 	obj.symbols["id"]
> (hope I'm clear)

I just found that it is, in fact, unpossible. That is, you can support
either a = foo.id; or foo.id = a; - not both. This is caused by bug 620:
http://d.puremagic.com/issues/show_bug.cgi?id=620

-- 
Simen
January 26, 2011
On 01/26/2011 12:05 AM, spir wrote:
> On 01/25/2011 10:29 PM, Simen kjaeraas wrote:
>> spir <denis.spir@gmail.com> wrote:
>>
>>> Hello,
>>>
>>> Cannot find corresponding opSomething method, if any. (opDispatch seems to
>>> specialise for method call.)
>>> Else, how to catch obj.member?
>>
>> opDispatch is likely what you want. with the @property annotation, it
>> will readily support obj.member; and obj.member = foo; syntax.
>
> Thank you, Simen, i'll try using opDispatch with @property. But I'm not sure
> how to write that concretely. My use case is of a type holding a
> string[AnyThing] AA called symbols. Then, I wish to map
> obj.id
> to
> obj.symbols["id"]
> (hope I'm clear)
>
> Denis

Right, just understood that you meant, I guess: since D supports properties with "x.a" syntax mapping to a func call x.a() under the hood, then one can use opDispatch intended for func calls to dispatch plain data membar access. (woof!).
FWIW: the following works fine:

alias int[string] Symbols;

class T {
    int i;
    Symbols symbols;
    this (int i, Symbols symbols) {
        this.i = i;
        this.symbols = symbols;
    }
    auto opDispatch (string name) () {
        auto p = (name in this.symbols);
        if (p)
            return *p;
        throw new Exception("No symbol called "~name~".");
    }
}
unittest {
    auto t = new T(1, ["j":2, "k":3]);
    writeln(t.i);
    writeln(t.j);
    writeln(t.k);
    writeln(t.l);   // throws as expected
}


Denis
-- 
_________________
vita es estrany
spir.wikidot.com

January 26, 2011
On 01/26/2011 01:06 AM, Simen kjaeraas wrote:
> spir <denis.spir@gmail.com> wrote:
>
>> On 01/25/2011 10:29 PM, Simen kjaeraas wrote:
>>> spir <denis.spir@gmail.com> wrote:
>>>
>>>> Hello,
>>>>
>>>> Cannot find corresponding opSomething method, if any. (opDispatch seems to
>>>> specialise for method call.)
>>>> Else, how to catch obj.member?
>>>
>>> opDispatch is likely what you want. with the @property annotation, it
>>> will readily support obj.member; and obj.member = foo; syntax.
>>
>> Thank you, Simen, i'll try using opDispatch with @property. But I'm not sure
>> how to write that concretely. My use case is of a type holding a
>> string[AnyThing] AA called symbols. Then, I wish to map
>> obj.id
>> to
>> obj.symbols["id"]
>> (hope I'm clear)
>
> I just found that it is, in fact, unpossible. That is, you can support
> either a = foo.id; or foo.id = a; - not both. This is caused by bug 620:
> http://d.puremagic.com/issues/show_bug.cgi?id=620

I do not really understand the subtleties of this bug, but indeed, I found no way to use opDispatch to set data members.
In other words, I could implement python's __getattr__ or Lua's __index,
not  python's __setattr__ or Lua's __newindex.

EDIT: Could do this as a workaround.

alias int[string] Symbols;

class T {
    int i;
    Symbols symbols;
    this (int i, Symbols symbols) {
        this.i = i;
        this.symbols = symbols;
    }
    auto opDispatch (string name) () {
        writeln("get");
        auto p = (name in this.symbols);
        if (p)
            return *p;
        throw new Exception("No symbol called "~name~".");
    }
    auto opDispatch (string name, Value) (Value value) {
        writeln("set ");
        auto p = (name in this.symbols);
        if (p) {
            *p = value;
            return;
        }
        throw new Exception("No symbol called '"~name~"'.");
    }
}
unittest {
    auto t = new T(1, ["j":2, "k":3]);
    writefln("<%s %s %s>", t.i, t.j,t.k);
    t.i = 11;
    t.j(22);
    t.k(33);
    writefln("<%s %s %s>", t.i, t.j,t.k);
//~     writeln(t.l);   // throws as expected
//~     t.l(44);   // throws as expected
    t.j = 222;  // Error: function
                // __trials__.T.opDispatch!("j").opDispatch ()
                // is not callable using argument types (int)
}

The last example shows how normal member-set syntax fails. I would like to know into what
	obj.name = val
is rewritten.

Denis
-- 
_________________
vita es estrany
spir.wikidot.com