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)

Reply via email to