On Mon, Jun 23, 2014 at 11:30:22AM -0400, Steven Schveighoffer via 
Digitalmars-d wrote:
> On Sat, 21 Jun 2014 15:47:03 -0400, Jonathan M Davis via Digitalmars-d
> <[email protected]> wrote:
> 
> >On Sat, 21 Jun 2014 18:50:21 +0000
> >Xinok via Digitalmars-d <[email protected]> wrote:
> >
> >>On Saturday, 21 June 2014 at 17:17:57 UTC, Suliman wrote:
> >>> Dart and few others modern languages support short declaration
> >>> constructor with parameter:
> >>>
> >>> class Person {
> >>>   String name;
> >>>
> >>>   Person(String name) {
> >>>     this.name = name;
> >>>   }
> >>> }
> >>>
> >>> // Shorter alternative
> >>> class Person {
> >>>   String name;
> >>>
> >>>   // parameters prefixed by 'this.' will assign to
> >>>   // instance variables automatically
> >>>   Person(this.name);
> >>> }
> >>>
> >>> it's there any DIP for adding this future to D?
> >>
> >>I'd prefer that we didn't crowd the language with minor shortcuts
> >>like these, and save syntactic sugar for more useful features.
> >>Plus, it would be easy enough to make a string mixin which generates
> >>such boilerplate code.
> >
> >Agreed. This would just add more stuff to the language that people
> >would have to understand, and it really doesn't add much benefit.
> >It's just a slightly terser syntax - and one that doesn't fit in with
> >any other kind of function declarations in D to boot.
> 
> Yeah, I don't think we save much with this. A mixin should be able to
> assign all the names given in the parameters that you name the same
> way.
> 
> In fact, I bet one can write a boiler-plate string that works for ANY
> class, using __traits(allMembers), as long as your parameter names
> match the member names. Then you just mixin that string as the first
> thing in the ctor.
[...]

Here's a first stab at a working mixin that does this (uncomment the
pragma(msg,...) lines to see the generated code):

        string defaultCtor(T)()
                if (is(T == class))
        {
                enum isDataMember(T, string memb) =
                        is(typeof(typeof(__traits(getMember, T, memb)).init));
        
                // Generate function signature
                string params, ctorBody;
                string delim = "";
                foreach (memb; __traits(derivedMembers, T))
                {
                        static if (isDataMember!(T, memb))
                        {
                                alias argtype = typeof(__traits(getMember, T, 
memb));
                                auto argname = "_" ~ memb;
                                params ~= delim ~ argtype.stringof ~ " " ~ 
argname;
                                delim = ", ";
        
                                ctorBody ~= "    " ~ memb ~ " = " ~ argname ~ 
";\n";
                        }
                }
        
                return "this(" ~ params ~ ")\n{\n" ~ ctorBody ~ "}";
        }
        
        class C {
                string name;
                int age;
                bool registered;
        
                mixin(defaultCtor!(typeof(this)));
                //pragma(msg, defaultCtor!(typeof(this)));
        
                void myMethod() {}
        }
        
        class D {
                int x, y;
                string label;
        
                mixin(defaultCtor!(typeof(this)));
                //pragma(msg, defaultCtor!(typeof(this)));
        }
        
        void main() {
                auto c = new C("John Doe", 30, true); // oh yeah
                auto d = new D(10, 20, "Node 1"); // rock on! ;-)
        }


Currently, this mixin doesn't handle inheritance very well, but it
should be trivial to extend it to collect all superclass data members
and package them off into a super(...) call inside the generated ctor.

D rawckz.


T

-- 
Making non-nullable pointers is just plugging one hole in a cheese grater. -- 
Walter Bright

Reply via email to