www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - override '.' member access

reply spir <denis.spir gmail.com> writes:
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
Jan 25 2011
next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
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
Jan 25 2011
parent spir <denis.spir gmail.com> writes:
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
Jan 26 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
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
Jan 25 2011
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
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
Jan 25 2011
prev sibling parent spir <denis.spir gmail.com> writes:
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
Jan 26 2011