Extending D's support for object-oriented design with private(this)

NotYouAgain NotYouAgain at gmail.com
Fri Apr 26 10:30:50 UTC 2024


On Thursday, 25 April 2024 at 19:48:11 UTC, Jonathan M Davis 
wrote:
> ..
> ...
> The normal answer is that if you really need the other code in 
> the module to not have access to the class' members, then that 
> class should just go in another module. In practice, the 
> current situation rarely causes problems. It seems more to be 
> something that annoys some folks on principle rather than being 
> an actual technical issue. I would be shocked if this DIP went 
> anywhere.
>
> - Jonathan M Davis

Another example, again, not on principle, but an actual issue.

The class below is from: 
https://dlang.org/spec/class.html#invariants

Sadly, the invariant here is ignored when I access the private 
member directly.

The below will pass the unittest.

However, by changing:
private:
     int day;
     int hour;

to:
private(this):
     int day;
     int hour;
not only has the author made their intent clear (as they have the 
tool to do it with private(this), but the compiler will now know 
the intent as well, and will rightly refuse to compile the code.

// ---------------
module m;
@safe:
import std;

class Date
{
     this(int d, int h)
     {
         day = d;    // days are 1..31
         hour = h;   // hours are 0..23
     }

     invariant
     {
         assert(1 <= day && day <= 31);
         assert(0 <= hour && hour < 24);
     }

   private:
     int day;
     int hour;
}

unittest
{
     Date d = new Date(1,1);
     d.day = 0; // invariant has no effect here.
                // day/hour really should not be accessible here 
anyway
                // - but there's no way in D to prevent this,
                // except by putting the unittest in a separate 
module to the class.
}
// -----------


More information about the dip.ideas mailing list