suggestion for eliminating the overload ambiguity for properties

Reiner Pope some at address.com
Sun Jul 29 22:37:26 PDT 2007


Bill Baxter wrote:
> Right now there's a problem in that if one uses property methods as 
> suggested by the D reference manual:
> 
> class Foo
> {
>   int prop() { ... }
>   int prop(int x) { ... }
> }
> 
> then you can't reliably get a delegate to the setter.   &aFoo.prop gets 
> you whichever appears first, which in this case is the getter.  This is 
> a known bug, and the most likely resolution for it will be to make 
> trying to do this an error.
> 
> So what if we just give D support for Java-style convention-based 
> deduction of properties.  You can keep using properties as-is, but _if_ 
> there's a method called 'set_prop' then it can be used as a setter 
> property.  So the above could be written as:
> 
> class Foo
> {
>   int prop() { ... }
>   int set_prop(int x) { ... }
> }
> 
> This way you can still use your property syntax, but you can also easily 
> distinguish the getter from the setter when taking a delegate.

I can see that being able to distinguish setter from getter is 
important, and it would be nice not to require casting for that. But I 
don't think that should be done in the language, because it doesn't 
generalise to selecting overloads for non-property functions.

I thought that you could write a template which gets you the 
getter/setter using __traits. In fact, I was right, and this turned out 
to be one of the cleanest uses of traits I've found. I wrote two 
templates called Getter and Setter, which will return the getter and 
setter for your particular properties. For instance, if a class Foo has 
a getter/setter pair, prop, you can write

auto f = new Foo();
auto getter = Getter!("prop").fn(f);
auto setter = Setter!("prop").fn(f);

It's not as nice as &f.prop_set, but I actually think it isn't too bad, 
over-all.

> ---
> Would it be possible to write a __traits-using mixin that scanned the 
> class mixed-into for methods of the form "set_blah" and created a simple 
> wrappers around them like:
>    T blah(T v) { return set_blah(v); }
> 
> Can a mixin can add members generated on the fly like that?

Well.... it doesn't _error_, but I'm not sure what the results mean:

template GenCode(T)
{
     pragma(msg, __traits(derivedMembers, T).stringof);
     static if (__traits(derivedMembers, T).length == 3)
         const char[] GenCode = "void bar() {}";
     else
         const char[] GenCode = "void bam() {}";
}

const char[] Code2 = "void boo() {}";

template TMixin()
{
     void Boom() {}
}

class Foo
{
     void run() {}
     mixin TMixin;
     mixin(Code2);
     mixin(GenCode!(Foo));
}

This compiles, but the pragma outputs

["run","__T6TMixinZ","__T7GenCodeTC14derivedMembers3FooZ"]

so it doesn't seem very useful except for members actually declared _in_ 
the class.


   -- Reiner
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: properties.d
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20070730/bb8cff59/attachment.ksh>


More information about the Digitalmars-d mailing list