Панмировые боги
Мы тут решили расширить дочке музыкальный репертуар, а то в последнее время у неё наметились явные фавориты и мы
Пока слушали, мне подумалось, что это была отличная заставка для для альтернативной версии сериала «Американские боги» (снят по книге Нила Геймана). Песня, безусловно, противоположна по смыслу, но затрагивает ту же тему.
То и другое произведение упоминает массу богов, но с разных сторон — песня
В сериале конфликт между старыми богами — то, чему люди
Вполне возможно, что Гейман проглядел эту идею или принёс её в жертву сюжету —
Честно сказать мне с такой мыслью трудно согласиться.
Может это и слишком наивно, когда на Часах Судного дня 2,5 минуты до полуночи, но мне кажется, что любовь, семья, человечность, взаимопомощь, доброта — всё это в большой цене и сейчас, эти старые боги (давайте придерживаться этого термина) могут спать спокойно — людским вниманием они будут обеспечены всегда.
Да и новые боги всё же лучше многих старых — куда более мягкие, податливые, демократичные. Вряд ли интернет стал бы так популярен в наше время, если бы требовал кровавых жертв перед каждым к нему подключением. Интернет вообще один из самых приятных богов — даже
Да, новые боги требуют ценнейшего ресурса — времени (как будто старые не требовали), но и давать способны немало, это уже вопрос собственных целеустремлений того, кто к ним обращается.
Аналог defer в языке R
В Гоу есть интересная конструкция (defer) — её содержимое выполняется, когда заканчивает работу функция, в которой эта конструкция объявлена, очень удобно память освобождать или другие ресурсы. Я накидал небольшой пример, чтобы было понятно:
package main
import (
"bufio"
"fmt"
"os"
)
func readFile(filename string) (out []string) {
file, _ := os.Open(filename)
defer file.Close()
b := bufio.NewReader(file)
for {
if str, err := b.ReadString('\n'); err != nil {
break
} else {
out = append(out, str)
}
}
return out
}
func main() {
var lines []string
for _, line := range readFile("/etc/passwd") {
if line[0] != '#' {
lines = append(lines, line)
}
}
fmt.Println(lines)
}В примере одна функция построчно читает файл и возвращает массив строк. Её использует основная функция (main), чтобы прочитать файл с информацией о пользователях в системе, удалив оттуда комментарии — строки, начинающиеся с «#». Обработку ошибок я не стал делать — и без этого длинновато вышло.
В фунции чтения файла блок defer вызовется как только мы покинем функцию и закроет используемый файл. Такой способ лучше, чем отсутствующий «Гоу» блок try…finally, так как позволяет указать способ освобождения ресурса очень близко к началу его использования.
Есть языки, которые, на мой взгляд, решают эту задачу ещё лучше (например, Пайтон со своим with), но у Гоу своя атмосфера и выбранное решение отвечает духу языка.
«Эр» на «Гоу» совсем не похож, у языков совершенно разные идеологии, поэтому я очень удивился, обнаружив в «Эр» тот же подход, что выбран в «Гоу».Тот же пример на «Эре»:
readFile <- function(filename) {
f <- file(filename, 'r')
on.exit({
close(f)
})
return(readLines(f))
}
lines <- readFile('/etc/passwd')
print(lines[!grepl('^#', lines)])Конструкция on.exit делает тут ровно то же, что defer в «Гоу». Нельзя не заметить, что программа стала гораздо компактнее, но в многословности Гоу обвинить нельзя —