Reordered class fields?

Peter Summerland p.summerland at gmail.com
Wed Oct 31 08:21:25 PDT 2012


On Wednesday, 31 October 2012 at 08:23:26 UTC, Jacob Carlborg 
wrote:
> On 2012-10-31 09:14, Peter Summerland wrote:
>
>> Thanks for the help.
>>
>> Should the the following example, taken from the D Language 
>> Reference,
>> be considered incorrect or at least misleading? It clearly 
>> depends on
>> lexical ordering of the returned fields:
>>
>> Class Properties
>>
>> The .tupleof property returns an ExpressionTuple of all the 
>> fields in
>> the class, excluding the hidden fields and the fields in the 
>> base class.
>>
>> class Foo { int x; long y; }
>> void test(Foo foo) {
>>   foo.tupleof[0] = 1; // set foo.x to 1
>>   foo.tupleof[1] = 2; // set foo.y to 2
>>   foreach (x; foo.tupleof)
>>     writef(x);        // prints 12
>> }
>
> I would at least consider it bad practice. Even if the compiler 
> guarantees a specific order it's quite easy for the developer 
> to change the order of the fields in Foo and then have "test" 
> break.

>
> I would suggest one always access the fields by name. Example:
>
> https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L1448
>
> https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L260
>

Thanks for the links. I can probably use some of the Reflection 
module in my code. I am making a very minimal sqlite3 library, 
which mostly just manages connections and statements to ensure 
they are closed and finalized automatically. I did add bind, step 
and scan methods to the Sqlite3Stmt struct but that's about it. 
Other than that you have to use the native c interface.

More importantly, I think that it is really very instructive to 
read over your code.

Re breaking test. You are right of course. But in my case the POD 
object is meant only to be used to package a row of data. The 
client cannot change it. Here is an example of how I might make a 
function to query a database

// POD structure to package rows returned by query
struct Employee
{
   int id_num;
   string name;
   int rank;
}

// returns an array of Employee objs for employees with given rank
Employee[] getEmployees(Sqlite3 db, int rank)
{
   static string query =
     "select e_num, e_name, e_rank from employee where e_rank = ?";

   auto app = appender!(Employee[]);
   auto stmt = db.prepare(query);
   stmt.bind(rank);
   stmt.scanFields!("id_num,name,rank")(app); // SAFE
   //stmt.scanFields(app);  // WORKS FOR POD STRUCTS LIKE EMPLOYEE
   return app.data;
}

It's not the greatests: You have to change the query if the 
database changes or if you want to change Employee, etc. But at 
least the query and Employee are defined locally in your code.

>> It would be nice if the Language Reference was specific on 
>> this point.
>> I am aware that the order of the members returned by
>> __traits(allMembers, D) is not defined (per the LR). But that 
>> is a
>> larger, more complex list.
>>
>> I am just beginning with D, but I think having the tupleof 
>> property for
>> classes and structs return their fields in lexical order might 
>> be useful.
>
> 1. It wouldn't hurt if it was clearly specified in the language 
> specification.
> 2. You can always sort the list
> 3. I wouldn't count on the order regardless, see above
>
>> E.g., I have written a "scan" function to load up a struct or 
>> class from
>> a row returned by a database query. I have, say, 
>> scan!"x,y,z"(obj) to
>> load data into fields x,y,z of obj. Based on the example above 
>> and by
>> experimenting, it appears that at least for dmd running on 
>> Linux, that
>> the fields returned by tupleof are indeed in lexical order.  
>> That
>> allowed me to have a "" default for the string of field names 
>> which
>> indicates that all the fields should be loaded. I.e., I have
>> scan!""(obj), which can be written scan(obj). Again, it seems 
>> to work
>> for simple classes and structs with Dmd on Ubuntu.
>
> Indeed, DMD seems to return them in lexical order, but again, I 
> wouldn't rely on the, see above.
>
>> Don't get me wrong -- I'll be happy without the default 
>> version if that
>> is the answer. I'm not suggesting any changes.




More information about the Digitalmars-d-learn mailing list