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 pmobject 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 }