Thursday 31 December 2015

Locally scoped things for cleaner code in Swift

Clean Code methodology says that your code should be its own documentation and what Swift adds to the system is function scoped anything. You can add a class, enum, protocol or struct that applies only to that function.

 So here in DevSketch I'm working on Swift parsing and I want turn a function declaration into its respective sections. So I want break apart

override func objectsForString(astring: String, inFilename headername: String) -> [AnyObject]

into 



override func objectsForString

and



astring: String, inFilename headername: String

and 


-> [AnyObject]

or at a more abstract level

somestuff func theName(theArguments) theReturnStuff 

 into ("somestuff func theName","theArguments","theReturnStuff") as part of a parsing pipeline.

 So what I do is walk along the declaration phrase and break it apart on the outermost brackets.

static func lineToFunctionSentenceParts(line:String)->(String,String,String) {
        
        enum PhrasePosition {
            case Name
            case Arguments
            case Returnval
        }
        
        var position = PhrasePosition.Name
        var bracketBalance = 0;
        
        var name = ""
        var arguments = ""
        var returnval = ""
        
        for xchar in line.characters {
            
            let sChar = String(xchar)
            let isBracket = adjustBracketBalance(sChar, bracketBalance: &bracketBalance)
            
            switch(position) {
                
                case .Name:
                    if isBracket {
                        position = .Arguments
                    } else {
                        name += sChar
                    }
                
                case .Arguments:
                    if isBracket && bracketBalance == 0 {
                        position = .Returnval
                    } else {
                        arguments += sChar
                    }
                
            
                case .Returnval:
                    returnval += sChar
            }
            
            
            
        }
        
        return (name,arguments,returnval)
        
    }


But the cool thing here is that i can describe to future me what i was doing with the locally scoped enum 


 enum PhrasePosition {
            case Name
            case Arguments
            case Returnval
        }
Sure I can do that in Objective-C but it would be
  1. Scoped to the entire m file.
  2. Up at the top where I can't see it.
This way I can use the enum as a single shot description of the local function actions and not worry about it being used elsewhere in an inappropriate context.

1 comment: