December 09, 2013
Jay Norwood:

>     struct Suit {string nm; int val; int val2; string shortNm;};

You have missed my suggestions above regarding the struct :-)

Look at this:


void main() {
    int x;
    struct Foo1 {
        int bar1() { return x; }
    }
    pragma(msg, Foo1.sizeof);
    static struct Foo2 {
        // this gives an error
        int bar2() { return x; }
    }
    pragma(msg, Foo2.sizeof);
}


bar2() gives an error because it can't access x. If you comment out the bar2 line, the output is:

4u
1u

Usually you don't want your struct defined inside a function to contain a pointer to the enclosing function.



>
>     static Suit[5] suits =  [
> 		{"spades",1,6,"spd"},
> 		{"hearts",4,10,"hrt"},
> 		{"hearts2",4,10,"hrt2"},
> 		{"diamonds",10,16,"dmd"},
> 		{"clubs",11,17,"clb"}
> 		];

Unless you have to mutate the contents of a variable, like your suits, define it const or immutable:

      static immutable Suit[5] suits =  [
	       {"spades",1,6,"spd"},
              ...
             ];

Generally in D add const/immutable to all variables that you don't need to mutate, if/where you can.

Bye,
bearophile
December 09, 2013
>>    static Suit[5] suits =  [
>> 		{"spades",1,6,"spd"},
>> 		{"hearts",4,10,"hrt"},
>> 		{"hearts2",4,10,"hrt2"},
>> 		{"diamonds",10,16,"dmd"},
>> 		{"clubs",11,17,"clb"}

Also, in D it's better to put a space after every comma, to increase readability a little:

    static immutable Suit[5] suits =  [
 		{"spades", 1, 6, "spd"},

Bye,
bearophile
December 09, 2013
It looks like the writeln() does a pretty good job, even for enum names.

I also saw a prettyprint example that prints the structure member name, and compared its output.
http://forum.dlang.org/thread/ip23ld$93u$1@digitalmars.com


module main;

import std.stdio;
import std.traits;

void main()
{
    enum Suit { spades, hearts=4, diamonds=10, clubs }
    enum SuitShort { spd, hrt=4, dmd=10, clb }

    static struct Suits { Suit nm; int val; int val2;  SuitShort shortNm;}

    static Suits[] suits =  [
		{Suit.spades, 1, 6, SuitShort.spd},
		{Suit.hearts, 4, 10, SuitShort.hrt},
		{Suit.diamonds, 4, 10, SuitShort.dmd},
		{Suit.clubs, 10, 16, SuitShort.clb}
	];

    foreach (immutable member;  suits)
    {
	auto fields = __traits(allMembers, typeof(member));
	auto values = member.tupleof;

	foreach (index, value; values)
	{
	    writef("%s=%s, ", fields[index], value);
	}
	writeln();
 	member.writeln();
    }
}


output:
nm=spades, val=1, val2=6, shortNm=spd,
immutable(Suits)(spades, 1, 6, spd)
nm=hearts, val=4, val2=10, shortNm=hrt,
immutable(Suits)(hearts, 4, 10, hrt)
nm=diamonds, val=4, val2=10, shortNm=dmd,
immutable(Suits)(diamonds, 4, 10, dmd)
nm=clubs, val=10, val2=16, shortNm=clb,
immutable(Suits)(clubs, 10, 16, clb)
December 09, 2013
Jay Norwood:

Using enums, despite their problems, if often better than strings.


>     static Suits[] suits =  [
> 		{Suit.spades, 1, 6, SuitShort.spd},
> 		{Suit.hearts, 4, 10, SuitShort.hrt},
> 		{Suit.diamonds, 4, 10, SuitShort.dmd},
> 		{Suit.clubs, 10, 16, SuitShort.clb}
> 	];
>
>     foreach (immutable member;  suits)


In some cases you can also use with() to avoid struct/enum name repetitions (unfortunately it creates a scope, so if you define an immutable variable inside it, it will be invisible and destroyed once the with() scope ends. This reduces the usefulness of with()).


    with (Suit) with (SuitShort)
    {
        static Suits[] suits = [
            {spades,    1,  6, spd},
            {hearts,    4, 10, hrt},
            {diamonds,  4, 10, dmd},
            {clubs,    10, 16, clb}
        ];

        foreach (immutable member;  suits)
        ...


Bye,
bearophile
December 09, 2013
Thanks.  That's looking pretty clean.

I had already tried the shorter enum names without using the with statement, and it failed to compile.  I thought it might work since the struct definition already specifies the enum type for the two members.


>
>     with (Suit) with (SuitShort)
>     {
>         static Suits[] suits = [
>             {spades,    1,  6, spd},
>             {hearts,    4, 10, hrt},
>             {diamonds,  4, 10, dmd},
>             {clubs,    10, 16, clb}
>         ];
>
>         foreach (immutable member;  suits)
>         ...
>
>
> Bye,
> bearophile

December 09, 2013
I notice that if Suit and SuitShort have an enum with the same name, then you still have to fully qualify the enum names when using the with statement.  So, for example, if spd in SuitShort was renamed spades, the first entry in the array initialization would have to be {Suit.spades, 1, 6, SuitShort.spades}.

>>    with (Suit) with (SuitShort)
>>    {
>>        static Suits[] suits = [
>>            {spades,    1,  6, spd},
>>            {hearts,    4, 10, hrt},
>>            {diamonds,  4, 10, dmd},
>>            {clubs,    10, 16, clb}
>>        ];
>>
>>        foreach (immutable member;  suits)
>>        ...
>>
>>
>> Bye,
>> bearophile

December 09, 2013
Jay Norwood:

> I notice that if Suit and SuitShort have an enum with the same name, then you still have to fully qualify the enum names when using the with statement.  So, for example, if spd in SuitShort was renamed spades, the first entry in the array initialization would have to be {Suit.spades, 1, 6, SuitShort.spades}.

Yes, that's named anti-shadowing, the D type system tried to avoid such bugs in your code.

Bye,
bearophile
1 2
Next ›   Last »