alias this private?

js.mdnq js_adddot+mdng at gmail.com
Sun Dec 9 11:23:17 PST 2012


On Sunday, 9 December 2012 at 16:50:55 UTC, Ali Çehreli wrote:
> On 12/09/2012 01:42 AM, js.mdnq wrote:
>
> > Actually, it doesn't seem to work ;/ Your code worked but
> mine does
> > unless I make it public. It is a public/private issue and I
> get a ton of
> > errors:
>
> This is not adding to the discussion much but it is again 
> because the member is private. writeln() is in a separate 
> module, which cannot access a private member of another module. 
> (Actually it is std.traits.isImplicitlyConvertible that can't 
> access that member.):
>
> class A
> {
>     struct B(T)
>     {
>     private:
>         //public:
>         T Value;
>     public:
>         alias Value this;
>
>         T opAssign(F)(F v)
>         {
>             //writeln(Name ~ " ...");
>             Value = cast(T)v;
>             return Value;
>         }
>     }
>
>     B!int b;
> }
>
> // Copied from isImplicitlyConvertible
> template isImplicitlyConvertible_LOCAL(From, To)
> {
>     enum bool isImplicitlyConvertible_LOCAL = is(typeof({
>         void fun(ref From v)
>         {
>             void gun(To) {}
>             gun(v);
>         }
>     }));
> }
>
> import std.traits;
>
> int main(string[] argv)
> {
>
>     A c = new A();
>
>     c.b = 34;
>
>     static assert(isImplicitlyConvertible_LOCAL!(A.B!int, 
> int)); // PASSES
>     static assert(isImplicitlyConvertible      !(A.B!int, 
> int)); // FAILS
>
>     return 0;
> }
>
> > So while it might "work" in the simple case it doesn't seem
> to actually
> > work...
>
> I am not sure that it should work. If it is private, maybe it 
> should stay private.
>
> What you seem to need is read-only access to a private member. 
> There are other ways of achieving that. The following program 
> uses both a read-only property function and an 'alias this':
>
> module main;
>
> import std.stdio;
>
> class A
> {
>     struct B(T)
>     {
>     private:
>         //public:
>         T Value_;
>     public:
>
>         // read-only accessor
>         T Value() const @property
>         {
>             return Value_;
>         }
>
>         // Automatic conversion to the read-only accessor
>         alias Value this;
>
>         T opAssign(F)(F v)
>         {
>             //writeln(Name ~ " ...");
>             Value_ = cast(T)v;
>             return Value_;
>         }
>     }
>
>     B!int b;
> }
>
> int main(string[] argv)
> {
>
>     A c = new A();
>
>     c.b = 34;
>     writeln(c.b);
>     getchar();
>     return 0;
> }
>
> Ali

but b is not private, only the internal representation of it. 
e.g., `alias Value_ this` is public. I do realize that it sort of 
makes Value_ and b one and the same but they are not quite the 
same.

To me, it breaks encapsulation. writeln(c.b) is accessing b, not 
Value_. b is a "virtual type" in the sense that it wraps Value_. 
While it seems to do something funky like change the protection 
of Value_ from private to public it doesn't. There is no way to 
access Value_ when it is private. i.e., we can't do c.b.Value_;

To drive the point home. We could/should be able to completely 
encapsulate `Value_` by overriding opAssign and add getters and 
setters so that `Value_` is actually never even used(although 
pointless then).

Another way to see this:

struct sPassword
{
     private:
         string Password;
     public:
         alias this Password;
         opAssign
         opCast
         opCmp
         opGet { return "******"; }
         Change(old pass, new pass) { if ... }
         Validate(pass) { pass == Password; ... }
}

sPassword myPass;
writeln(myPass) same as writeln(myPass.Get()) which prints ******

Such a type would be very secure. There is no way to get at 
Password(except through looking directly at memory, but we could 
encrypt it to make it difficult). But for all practical purposes 
myPass acts like a password.

We can't accidently display the password to the user(in fact, 
there is no way unless a method is added to return the password, 
in which case there is no reason to make Password private.

In any case, it just seems to me that we should be able to use 
private this way. If we want the additional functionality we just 
make it public.

(it does sort of seem sPassword is like a readonly type but it's 
more than that as it encapsulates completely)

Now, if Password was public instead of private, anyone could do 
myPass.Password to get the password.


(the code isn't meant to be working D code but just a mix of 
pseudo and hypothetical D code)


More information about the Digitalmars-d-learn mailing list