kodecocodes / swift-style-guide

The official Swift style guide for Kodeco.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

one-off variables

EricWVGG opened this issue · comments

What’s your opinion on…

let workingDirectory = DirectoryConfig.detect().workDir
let filePath = [
        workingDirectory + "Public",
        "uploads",
        filename
    ].joined(separator: "/")
let fileUrl = URL(fileURLWithPath: filePath)
let imageData = try Data(contentsOf: fileUrl)

vs

let imageData = try Data(contentsOf: URL(fileURLWithPath: [
        DirectoryConfig.detect().workDir + "Public",
        "uploads",
        filename
    ].joined(separator: "/")))

? All those let's drive me up the wall. I'm probably in the minority on this.

The main issue I have with your code is that you should use appendPathComponent() to construct paths instead of joining strings using the "/" character.

If there's a clear argument label, then I avoid "one-off variables". But the parentheses and square brackets have to match up better than your example, for me to consider it clear.

e.g.

let imageData = try Data(
  contentsOf: URL(
    fileURLWithPath: [
      DirectoryConfig.detect().workDir + "Public",
      "uploads",
      filename
    ].joined(separator: "/")
  )
)

I do like to separate out lines that require try, though, because try propagates in a way that doesn't clearly state what exactly throws. So I would use one constant, for your example:

let url = URL(
  fileURLWithPath: [
    DirectoryConfig.detect().workDir + "Public",
    "uploads",
    filename
  ].joined(separator: "/")
)
let imageData = try Data(contentsOf: url)

@hollance Fair enough, but I’m just asking about this general style of handling information.

@EricWVGG you are worried about plenty local constants declared in order to load an image data from file.
I'd say if this is the only occasion to load such file it is ok to place this logic in single method. Otherwise I recommend you to compose final image path somewhere in class that is aware of file system structure and finaly use something next to load image

let url = DirectoryConfig.detect().workPublicUploadsFileUrl(for: filename)
let imageData = try Data(contentsOf: url)

… maybe I should have just pseudocoded this question.

let foo = GetFooFromSomewhere(on: "herpderp")
let derp = ["junk", "trunk", "dunk"].joined(":")
let someOp = YackittySmack(withFoo: foo, andDerp: derp)
let result = someOpLoader(op: SomeOp)

vs

let result = someOpLoader(op: YackittySmack(
  withFoo: GetFooFromSomewhere(on: "herpderp"),
  andDerp: ["junk", "trunk", "dunk"].joined(":")
))

I appreciate the note about segregating "try"s.

@EricWVGG in general it is better to name each step to make clear what is retrieved from operation, instead of makeing cascaded. Well-written code does not require comments (mostly)
Thus

let someId = SomeRepo().someGetter()
let someTempFileName = SomeClass.something(someid)
let finalData = self.someMethod(someTempFileName)

is easier to read than

let finalData = self.someMethod(SomeClass.something(SomeRepo().someGetter()))

Especially in 2-4 weeks

Definitely prefer the "multiple let" approach. It's much more clear and much more self-documenting. That brings it in line with the injunction under Comments that "...the code should be as self-documenting as possible."