Another way I'd like Swift to keep code succinct

Hi,

Recently I was writing classes to capture data of different types and output them as fixed length fields in a number of different fixed length records. I was working in Delphi, but wondering if Swift would be able to make it better. Each record class needed to mention each record 3 times: declaring a class variable to represent the field, then creating the object, then initialising it with a value from a database. The order of creation of the field objects is key because that determines the order they appear in in the output file.



I was thinking that with Swift I could have reduced the number of mentions by name of these field objects, and thus the number of places where mistakes could be made or just reduce the tedium of programming it. There are probably a couple of hundred fields to be declared, so it would be great to be able to create them in the same statement as they are declared in. But they have to be added to an array that belongs to the record class, which at present you can't do


A simple convention that could be observed is that properties of a class are evaluted from top to bottom and anything with an assignment can be used in initialising later properties. Here's some simplified code along the same lines as what I was doing:


class Field {


var length: Int

var mandatory: Bool

var value: String = ""


init(inout list: [Field], length: Int, mandatory: Bool){

self.length = length

self.mandatory = mandatory

list.append(self)

}

}// Field


class Record {

var items = [Field]() // This is now validly initialised, so should be available in subclasses.

var length: Int


init(length: Int) {

self.length = length

}


func write(fileName: String) {

// open file

for field in items {

write(field)

}

}


private func write(field: Field) {

// Do stuff

}


}// Record


class PersonRecord: Record {

var nameField = Field(list: &items, length: 20, mandatory: true) // Use the items member of the superclass.

var addressField = Field(list: &items, length: 20, mandatory: false)

var phoneField = Field(list: &items, length: 20, mandatory: true)


/// Plus another 20 or so fields


}// PersonRecord



// Plus another 10 or so record classes.

If you take a look at the Swift rules for initialization, one of the "safety rules" (in the "Two-Phase Initialization" section) is that the designated initializer of a class must initialize all of the variables declared in that class _before_ calling an initializer in its superclass.


https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID216


So the invidual "field" properties of the subclass would actually need to be initialized before the container array from the superclass, in order to meet the "safety rule" requirements.


If you wanted to do something like this in swift, you could include the info you need to look up the values in the field object, and use a generic Record class that references your different record types as the generic subtype...


struct Field
{
    let key: String // whatever info you need to look up value in database (maybe two properties, table + column)
    let length: Int
    let mandatory: Bool
    var value: String = ""
  
    init(key: String, length: Int, mandatory: Bool)
    {
        self.key = key
        self.length = length
        self.mandatory = mandatory
    }
}// Field


protocol RecordType
{
    static var prototype: [Field] {get}
    static var length: Int {get}
}


class Record<T: RecordType>
{
    var items = [Field]()
  
    init(identifier: String)
    {
        for field in T.prototype
        {
            items.append(lookupField(field, forIdentifier: identifier))
        }
    }
  
    func lookupField(field: Field, forIdentifier identifier: String) -> Field
    {
        // lookup value for field in database using field.key and record identifier (and process as necessary)
        // update field.value with new value
        return field
    }


    func write(fileName: String) {
        // open file
        for field in items {
            write(field)
        }
    }
  
    private func write(field: Field) {
        // Do stuff
    }
  
}// Record


struct PersonRecord: RecordType
{
    static let prototype: [Field] =
    [
        Field(key: "nameField", length: 20, mandatory: true),
        Field(key: "addressField", length: 20, mandatory: false),
        Field(key: "phoneField", length: 20, mandatory: true),
  
    /// Plus another 20 or so fields
  
    ]
  
    static let length = 500
  
}// PersonRecord




/// Plus another 10 or so record classes.

Can you explain why the subclass gets its variable initialised first? At first impression it would seem that it would make more sense to do the superclass first.

At least one reason is that method calls during superclass initialisation can be dynamically dispatched to the subclass. So the subclass variables need to be in a valid state before the superclass initialisation starts.

Another way I'd like Swift to keep code succinct
 
 
Q