Property discussion wrap-up

TommiT tommitissari at hotmail.com
Fri Feb 1 06:49:46 PST 2013


On Thursday, 31 January 2013 at 16:44:03 UTC, TommiT wrote:
> So, going back to the concept of property as a crossbreed 
> between a namespace and a variable. Here's my new take on it:
>
> * Property looks like a namespace when it is defined, and a 
> variable when it is used.
>
> * Property definition creates its own lexical scope.
>
> * Properties can't hold any variables, don't take up any 
> memory, and you can't take the address of a property.
>
> * Properties may have a special opGet operator that will be 
> called eagerly whenever a naked property is used, i.e. a 
> property is used without applying any such operator or member 
> function that is defined for that particular property.
>
> I don't know if properties really need to have member 
> functions, but I wouldn't want to rule them out right off the 
> bat.
>
> struct T
> {
>     private int value;
>
>     bool isCorrect() const
>     {
>         return false;
>     }
>
>     property myProp
>     {
>         // the special "eager casting operator" of properties
>         int opGet() const
>         {
>             return value;
>         }
>
>         void opAssign(int v)
>         {
>             value = v;
>             // doesn't have to return anything
>         }
>
>         void opAssign(string s : "+")(int v)
>         {
>             // 'this' refers to the enclosing object
>             this.value += v;
>         }
>
>         // function attribute 'const' refers to the
>         // constness of the enclosing object
>         bool isCorrect() const
>         {
>             return value == 42;
>         }
>
>         ref T sayWhat()
>         {
>             // isCorrect refers to: this.myProp.isCorrect
>             // ...and not to:       this.isCorrect
>             assert(isCorrect());
>
>             // 'this' refers to the enclosing object
>             return this;
>         }
>
>         int data; // error: properties can't hold any variables
>     }
> }
>
> void foo(T : int)(T t);
>
> int fn(T.myProp p); // error: T.myProp is a property, not a type
>
> ...
>
> T t;
> foo(t.myProp);     // foo(t.myProp.opGet());
> auto v = t.myProp; // int v = t.myProp.opGet();
> t.myProp = 41;     // t.myProp.opAssign(41);
> t.myProp += 1;     // t.myProp.opAssign!"+"(41);
> assert(t.myProp.isCorrect());
>
> immutable T t2;
> t2.myProp.sayWhat(); // error: cannot call a non-const property
>                      // method of an immmutable variable t2

Here's some more elaboration of the interplay between 1) "naked" 
property use, 2) property methods/operators and 3) the 
methods/operators of the type which "naked" property use returns 
through the opGet operator:

struct Speed
{
     int _value;

     void opOpAssign(string op)(int rhs)
         if (op == "+")
     {
         _value += rhs;
         assert(1 <= _value && _value <= 4);
     }
}

struct Sneak
{
     int _value;

     void opOpAssign(string op)(int rhs)
         if (op == "+")
     {
         _value += rhs;
         assert(1 <= _value && _value <= 4);
     }
}

struct Character
{
     private Speed _speed;
     private Sneak _sneak;

     property speed
     {
         ref Speed opGet()
         {
             return _speed;
         }

         void opOpAssign(string op)(int rhs)
             if (op == "+")
         {
             _speed += rhs;
             assert(_speed._value + _sneak._value <= 5);
         }
     }

     property sneak
     {
         ref Sneak opGet()
         {
             return _sneak;
         }
     }
}

void main()
{
     Character c;

     c.speed += 1; // calls: c.speed.opOpAssign!"+"(1);
     c.sneak += 1; // calls: c.sneak.opGet() += 1;
                   // i.e.   c._sneak.opOpAssign!"+"(1);
}

As far as I know, the obove kind of thing isn't possible with the 
current state of affairs; with @property attribute, you cannot 
provide the extra level of encapsulation that checks that the sum 
of 'speed' and 'sneak' isn't above 5.


More information about the Digitalmars-d mailing list