shorter alternative of constructor with parameter
H. S. Teoh via Digitalmars-d
digitalmars-d at puremagic.com
Mon Jun 23 09:44:04 PDT 2014
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
> <digitalmars-d at puremagic.com> wrote:
>
> >On Sat, 21 Jun 2014 18:50:21 +0000
> >Xinok via Digitalmars-d <digitalmars-d at puremagic.com> 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
More information about the Digitalmars-d
mailing list