Feb. 20th, 2012
"ошибки в окружении"
Feb. 20th, 2012 12:51 pmА любопытно устроен менталитет программистов - если чего не хватает, типа файл не найден, то это всё считается чьи-то ошибки. Кругом ошибки, и если программа валится по npe, а корневая причина отсутствие какого-нибудь файла по предполагаемому пути, то это "ошибка". Сегодня за обедом с архитектором беседую, говорю, слышь, ты тут класс написал, "декорированный брокер", у него есть делегат, которого ты называешь _decorated, и ты нигде вообще не проверяешь что он null, не null, а делегируешь себе - это типа as designed? На что он ответствует - ну npe будет если только система неправильно сконфигурирована, тогда вообще сервер должен завершать работу.
Он, конечно, ни хера работу не завершает, а хуярит и хуярит, извините за выражение, исключение за исключением.
И я не думаю, что мы с ним когда-нибудь договоримся.
Но меня что-то нынче пробило писать примерно вот так:
Да затрахало елозить с юниттестами да дебагерами. Кусок кода может сам признаться, чего ему не хватает, сразу, а не после трагических ошибок.
P.S. Надеюсь вы понимаете, что этот дешевый приёмчик есть замена правильному решению
Он, конечно, ни хера работу не завершает, а хуярит и хуярит, извините за выражение, исключение за исключением.
И я не думаю, что мы с ним когда-нибудь договоримся.
Но меня что-то нынче пробило писать примерно вот так:
def existingFile(file: File) = {
require(file.exists(), "File " + file.getAbsolutePath + " must exist")
file
}
def existingFile(path: String) = existingFile(new File(path))
def existingFile(folder: File, name: String) = existingFile(new File(existingFile(folder), name))
Да затрахало елозить с юниттестами да дебагерами. Кусок кода может сам признаться, чего ему не хватает, сразу, а не после трагических ошибок.
P.S. Надеюсь вы понимаете, что этот дешевый приёмчик есть замена правильному решению
class ExistingFile(File file)...
фцук, где наши типы?!
Feb. 20th, 2012 04:44 pm
object FS {
class TextFile(val file: File) {
def text = Source.fromFile(file).mkString
def text_=(s: String) {
val out = new PrintWriter(file, "UTF-8")
try{ out.print(s) } finally{ out.close }
}
def parent = new Folder(file.getParentFile)
override def toString = file.getAbsolutePath
}
class ExistingFile(file: File) extends TextFile(file) {
require(file.exists(), "File " + file.getAbsolutePath + " must exist")
}
class Folder(path: File) extends ExistingFile(path) {
require(path.isDirectory, "File " + path.getAbsolutePath + " must be a directory")
def file(name: String) = new TextFile(new File(path, name))
def subfolder(name: String) = new Folder(file(name))
def existingFile(name: String) = new ExistingFile(file(name))
}
implicit def asFile(file: TextFile) = file.file
implicit def textFile(file: File) = new TextFile(file)
implicit def existingFile(file: File) = new ExistingFile(file)
implicit def asFolder(file: File) = new Folder(file)
implicit def file(name: String) = new File(name)
}
and the usage is:
val configFiles = List("ac_office.xml", "broker.xml", "dse.xml", "pe.xml", "ao_office.xml", "dashboard.xml", "license.txt"")
for (name <- configFiles) {
val d = bootDir.file(name)
if (!d.exists) d.text = setupDir.subfolder("setup").existingFile(name).text
}