On Thu, 05 Feb 2009 20:26:03 -0500, Alex Burton <alex...@mac.com> wrote:

Robert Jacques Wrote:

On Thu, 05 Feb 2009 06:55:46 -0500, Alex Burton <alex...@mac.com> wrote:

> Hi,
>
> I just found a bug that comes out of the property syntax.
>
> The property syntax is great in that it allows a smooth transition from
> simple code dealing with public member variables to the use of
> interfaces without needing to update the client code.
> i.e. A.bob = 1 can stay as A.bob = 1 when bob changes from being an int
> to being void A::bob(int i)
> instead of changing to A.bob(1).
>
> But this can introduce the bug I show below.
>
> Proposal :
> If the temporary returned by the property syntax getter function is
> modified, then the corresponding setter function needs to be called with
> the temporary as argument.
>
> struct A
> {
>       int i;
>       int j;
> };
>
> class B
> {
>   A mA;
> public:
>    A a() { return mA; }
>    void a(A a) { mA = a; }
> };
>
>
> int main()
> {
>      B b;
>      b.a.j = 10;     // error b.a is a temporary.
> }

This isn't a bug, it's a feature. What you wanted to use were ref returns
(see http://www.digitalmars.com/d/2.0/function.html )
ref A a() { return mA; }


Using
ref A a() { return mA; }
requires us to have a member variable mA ( which is actually there in the example). One of the reasons for using the setter and getter functions instead of the raw member variable is that there is not actually a member variable. For example:
A a()
{
     Dataset ds = mDatabase.Execute("SELECT A,B FROM TABLE");
     return A(ds[0][0],ds[0][1]);
}

void a(A a)
{
     mDatabase.Execute(format("INSERT %d,%d INTO TABLE;",a.i,a.j));
}

The only way I can see to handle this correctly is to use my proposal above.

This could be a really valuable feature in D if correctly implemented.
Being able to transparently change from a member variable in a struct to getters and setters on a struct to getters and setters on a class and in reverse order is really powerful and allows code to evolve in a much more fluid way.

Alex

Alex, this looks like you want to use proxy structs/objects. Remember each of the following are equivalent:

b.a.j = 10;
<=>
(b.a).j = 10;
<=>
auto c = b.a;
c.j = 10;

And that last case is a kinda tricky.

Also, the x.y.z = 10 not doing anything when y is a struct from your other post is a well known issue is all languages that have POD struct (As far as I know). The solution is to move x.y to a ref return property. Moving from POD members to functions in order to support more complex logic is the primary motivation of properties.

Reply via email to