В Linux Mint Cinnamon с помощью комбинации клавиши Win и стрелок можно прижать окно влево/вправо/вверх/вниз, чтобы оно занимало половину экрана или его четверть.
Это позволяет обойтись без консольного мультиплексора типа tmux, если нужно просто разместить рядом две консоли одного размера.
перевод статьи Mary Rose Cook “Git in six hundred words”
Представим, что у вас есть каталог alpha, содержащий файл number.txt, в котором записано слово “first”.
Запустите git init
для превращения каталога alpha в Git-репозиторий.
Выполните git add number.txt
для добавления файла number.txt в индекс (на сцену). Индекс – это список всех файлов, за которыми Git следит. Он отображает имена файлов в их содержимое. Сейчас в нем содержится соответствие number.txt->first
. Запуск команды add
также добавляет в базу данных Git blob-объект, содержащий строку “first”.
Выполните git commit -m first
. В результате будут сделаны три вещи:
git add number.txt
.Выполните команду git clone . ../beta
. В результате будет создан новый каталог beta, являющийся Git-репозиторием.
Перейдите в каталог beta. Измените содержимое файла number.txt на на “second”. Выполните команды git add number.txt
и git commit -m second
. Будет создан объект-коммит, содержащий указатель на своего родителя, первый коммит. После команды commit
ветка main будет указывать на второй коммит.
Вернитесь в каталог alpha. Выполните команду git remote add beta ../beta
. В результате репозиторий beta будет считаться удаленным репозиторием для alpha.
Выполните команду git pull beta master
.
На самом деле при этом выполнятся две команды. Первая из них git fetch beta master
. В результате в репозиторий alpha будут скопированы объекты второго коммита из репозитория beta. Запись в alpha о ветке master в beta будет указывать на второй коммит. Команда обновляет указатель FETCH_HEAD, чтобы показать, что ветка master была загружена из репозитория beta.
Вторая команда, неявно выполняющася при git pull
, – это git merge FETCH_HEAD
. Эта команда:
merge
может просто изменить ветку master, чтобы он указывала на второй коммит. Далее команда merge
обновляет индекс, чтобы его содержимое соответствовало второму коммиту, и обновляет рабочий каталог, чтобы он соответствовал индексу.Выполните команду git branch red
. В результате будет создана ветка red, которая будет указывать на второй коммит.
Выполните команду git checkout red
. Перед этой командой HEAD указывал на ветку master, теперь указывает на ветку red. Ветка red является теперь текущей.
Измените содержимое файла numbers.txt на “third” и выполните команды git add numbers.txt
и git commit -m third
.
Выполните команду git push beta red
. В результате в репозитории alpha будут найдены объекты, соответствующие третьему коммиту, и они будут скопированы в репозиторий beta. В репозитории beta появится ветка red, указывающая на третий коммит.
перевод статьи Borislav Hadzhiev “Why does list.append() return None in Python”
Метод list.append()
возвращает None
, потому что он изменяет первоначальный список. В Python большинство методов, изменяющих объект, в котором они определены ,возвращают None
.
a_list = ['bobby', 'hadz']
a_list.append('.')
a_list.append('com')
print(a_list) # ['bobby', 'hadz', '.', 'com']
Метод list.append()
добавляет элемент в конец списка. Этот метод возвращает None
, так как он изменяет (мутирует) исходный список.
В Python действует соглашение о том, что методы, изменяющие исходный объект, возвращают
None
.
Если вам нужно получить новый список путем добавления элемента к существующему списку, то используйте оператор сложения +
.
a_list = ['bobby', 'hadz']
new_list = a_list + ['com']
print(new_list) # ['bobby', 'hadz', 'com']
print(a_list) # ['bobby', 'hadz']
Оператор сложения
+
, стоящий между двух списков, объединяет их в один список.
Отметим, что при этом первоначальный список остается неизменным.
Также для получения нового списка добавлением к списку нового значения можно использовать метод list.append()
вместе с булевым оператором or
.
a_list = ['bobby', 'hadz']
new_list = a_list.append('com') or a_list
print(new_list) # ['bobby', 'hadz', 'com']
print(a_list) # ['bobby', 'hadz', '.', 'com']
Выражение x or y
возвращает левое значение, если он истинно, и правое значение в противном случае.
Метод list.append()
добавляет элемент в конец списка и возвращает None
, поэтому конструкция a_list.append('com') or a_list
возвращает список a_list
(уже с добавленным в него новым элементом).
Две переменные сохраняют один и тот же список (одно и то же место в памяти), поэтому изменение в одной переменной будут применяться и к другой переменной.
Еще один вариант получения нового списка с добавленным элементом – использовать оператор распаковки итерируемого объекта.
a_list = ['bobby', 'hadz']
new_list = [*a_list, 'com']
print(new_list) # ['bobby', 'hadz', 'com']
print(a_list) # ['bobby', 'hadz', '.', 'com']
Оператор *
позволяет “распаковать” итерируемый объект в последовательность элементов в вызовах функций, списковых включениях (list comprehensions) и выражениях-генераторах.
example = (*('a', 'b'), 'c')
print(example) # ('a', 'b', 'c')
Можно сказать, что мы распаковываем элементы списка и передаем их в качестве значений, разделенных запятыми, для создания нового списка.
После распаковки существующего списка можно добавить в него одно или несколько значений, записывая их через запятую.
Не пытайтесь присвоить результат вызова append()
, insert()
или extend()
какой-либо переменной, так как методы, изменяющие первоначальный объект, как правило возвращают None
.
Для того, чтобы увидеть тип значения, которое возвращает метод, можно в IDE навести на него указатель мыши.
Если метод возвращает None
, то он при выполнении изменит сам объект. Напротив, если метод возвращает значение, отличное от None
, то обычно он вернет новый объект, оставляя первоначальный без изменения.
На ноуте была активирована предустановленная ОС Windows 10.
echo "deb http://repo.yandex.ru/yandex-disk/deb/ stable main" | sudo tee -a /etc/apt/sources.list.d/yandex-disk.list > /dev/null && wget http://repo.yandex.ru/yandex-disk/YANDEX-DISK-KEY.GPG -O- | sudo apt-key add - && sudo apt-get update && sudo apt-get install -y yandex-disk
yandex-disk setup
sudo apt install git
git config --global user.name "Andrey Popov"
git config --global user.email andpop@mail.ru
sudo apt-get install libncursesw5-dev
./configure
Если все нормально прошло, то компилируем и устанавливаем:
make
sudo make install
colorscheme
в ~/.config/vifm/vifmrc.Дистрибутив зависит от версии Ubuntu (ставил для Ubuntu 22.04): https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
# Update the list of packages
sudo apt-get update
# Install pre-requisite packages.
sudo apt-get install -y wget apt-transport-https software-properties-common
# Download the Microsoft repository GPG keys
wget -q "https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb"
# Register the Microsoft repository GPG keys
sudo dpkg -i packages-microsoft-prod.deb
# Update the list of packages after we added packages.microsoft.com
sudo apt-get update
# Install PowerShell
sudo apt-get install -y powershell
# Start PowerShell
pwsh
sudo apt install htop
sudo apt-get install zsh
curl -L http://install.ohmyz.sh | sh
chsh -s /bin/zsh
После рестарта системы оболочкой по умолчанию станет Zsh.
sudo apt-get install fonts-powerline
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
plugins=(npm composer sudo web-search zsh-syntax-highlighting git zsh-autosuggestions history-substring-search)
sudo apt update && sudo apt upgrade -y
sudo apt install php8.1
sudo apt install php8.1-curl
sudo apt install php8.1-xml
sudo apt install php8.1-mbstring
sudo apt update
sudo apt install curl php-mbstring git unzip
cd ~
curl -sS https://getcomposer.org/installer -o composer-setup.php
Затем убедитесь, что хэш установщика совпадает с хэшем SHA-384 для последней версии установщика на странице Composer Public Keys / Signatures. Скопируйте хэш с этой страницы и сохраните его в качестве переменной командной строки:
HASH=544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061
Теперь выполните следующий PHP скрипт, чтобы убедиться, что скрипт установки безопасен для запуска:
php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Вы должны увидеть следующий вывод:
Installer verified
Чтобы выполнить глобальную установку composer, используйте следующую команду, которая выполнит загрузку и установку Composer в качестве общесистемной команды composer в каталоге /usr/local/bin:
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
composer global require "squizlabs/php_codesniffer=*"
sudo apt-get install ruby-full build-essential zlib1g-dev
echo '# Install Ruby Gems to ~/gems' >> ~/.zshrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.zshrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
sudo apt-get -y install shutter
sudo apt install sqlite3
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
source ~/.zshrc
nvm list-remote
nvm install v18.2.0
Утилита-аналог cat
с усовершенствованным интерфейсом.
sudo apt install bat
mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat
По умолчанию утилита доступна как batcat
. После создания ссылки и перезагрузки можно будет запускать как bat
.
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
jammy stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
В шестой команде jammy – это версию Ubuntu для Linux Mint 21. Для проверки работы Docker выполним команду:
sudo docker run hello-world
Добавляем себя в группу docker
:
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
sudo apt install -y python3-pip
sudo apt install build-essential libssl-dev libffi-dev python3-dev
sudo apt install -y python3-venv
sudo apt install vim
У нас Vim уже был установлен. Ставим библиотеку для переключения раскладки клавиатуры:
sudo apt-get install build-essential
sudo apt-get install cmake
mkdir ~/xkb-switch && cd ~/xkb-switch && git clone https://github.com/grwlf/xkb-switch.git .
sudo apt-get install libxkbfile-dev
mkdir build && cd build
cmake ..
make
sudo make install
sudo ldconfig
xkb-switch --help
vim-plug
:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
Установим локаль ru_RU.utf8:
sudo apt-get install language-pack-ru
Обновим локаль в системе:
sudo update-locale LANG=ru_RU.UTF-8
Далее нужно перезайти в систему и командой locale
проверить текущую локаль.
Глава 13 “Бикультурализм” из книги Д. Спольски “Джоэл о программировании”
К данному моменту у Windows и UNIX функционально стало больше сходства, чем различий. Здесь и там поддерживаются одни и те же основные метафоры программирования, от командной строки до GUI и веб-серверов; они построены вокруг примерно одной и той же совокупности системных ресурсов, включая почти идентичные файловые системы, память, сокеты, процессы и потоки. Базовый набор сервисов каждой из этих операционных систем почти не ограничивает разнообразия создаваемых приложений.
Остались лишь культурные различия. Да, мы все принимаем пищу, но они там деревянными палочками едят сырую рыбу с рисом, а мы здесь едим руками куски молотой коровы на хлебе. Культурные различия не означают, что американские желудки не могут переваривать суши или что японские желудки не могут переварить биг-мак, и не означают также, что не может быть множества американцев, которые едят суши, или множества японцев, которые едят бургеры, но они означают, что у американца, впервые спустившегося по трапу самолета в Токио, возникает ошеломляющее чувство, что это место необычно, и никакое философствование о том, что в глубине мы все одинаковы, мы любим, работаем, поем и умираем, не может отменить того обстоятельства, что американцы и японцы никогда не смогут понастоящему привыкнуть к тому, как устроены туалеты в другой стране.
Каковы культурные различия между программистами UNIX и Windows? Есть много деталей и тонкостей, но по большей части они сводятся к одному: в культуре UNIX ценится код, который полезен другим программистам, а в культуре Windows ценится код, который полезен непрограммистам. Конечно, это большое упрощение, но ведь это действительно большая разница, для кого мы программируем – для программистов или конечных пользователей! Все остальное – комментарии.
Нередко провоцирующий полемику Эрик С. Рэймонд (Eric Raymond) написал большую книгу под названием «The Art of UNIX Programming» (Addison-Wesley, 2003), подробно исследовав в ней эту культуру. Можно купить бумажное издание и прочесть его либо, если взгляды и принципы Рэймонда слишком «антиидиотарны» для вас и вы не хотите платить ему денег, почитайте ее в Интернете бесплатно, сохранив уверенность, что автор не получит от вас ни копейки за свой тяжелый труд.
Рассмотрим простой пример. В культуре программирования под UNIX высоко ценятся программы, которые могут вызываться из командной строки, принимать аргументы, контролирующие самые различные аспекты их поведения, и результат работы которых может быть получен в виде регулярно форматированного обычного текста, доступного для чтения машиной. Такие программы ценятся, потому что программистам легко включать их в другие программы или более крупные программные системы. Один маленький пример: в культуре UNIX есть важная ценность, которую Рэймонд называет «молчание – золото», означающая, что, если программа успешно выполнила в точности то, что вы ей сказали, она не должна вообще ничего выводить. Неважно, что вы сделали – ввели команду из 300 символов для создания файловой системы, или скомпилировали и установили сложный программный пакет, или отправили пилотируемый космический корабль на Луну. Если выполнение прошло успешно, считается, что не надо выводить ничего. Если снова появляется подсказка командной строки, пользователь заключает из этого, что все OK.
Это важная ценность в культуре UNIX, потому что вы программируете для других программистов. Как отмечает Рэймонд, «болтливые программы обычно плохо взаимодействуют с другими программами». Напротив, в культуре Windows вы программируете для тетушки Мардж, и тетушку Мардж можно оправдать, если она считает, что программу, которая ничего не вывела, потому что успешно отработала, нельзя отличить от программы, которая ничего не вывела, потому что произошел сбой, или программы, которая ничего не вывела, потому что не поняла ваш запрос.
Аналогично в культуре UNIX ценятся программы, не выходящие из текстового режима. Там недолюбливают GUI, если не считать раскраски, явно нанесенной поверх текстового режима, и не любят двоичные форматы файлов. Это вызывается тем, что программировать взаимодействие с текстовым интерфейсом гораздо проще, чем, скажем, взаимодействие с GUI, что почти невозможно делать в отсутствие некоторых прочих условий, типа встроенного языка сценариев.
Здесь мы снова сталкиваемся с тем, что культура UNIX ценит код, полезный другим программистам, что редко бывает целью при программировании в Windows . Это не значит, что все UNIX-программы разрабатываются исключительно для программистов. Далеко не так. Но культура ценит то, что полезно программистам, и этим кое-что объясняется.
Предположим, что у нас есть UNIX-программист и Windows-программист и оба они получили задание создать одинаковое приложение для конечного пользователя. UNIX-программист создаст базовое приложение командной строки или с текстовым интерфейсом и, может быть, с некоторым опозданием и нехотя построит GUI над этим базовым приложением. В результате основные операции этого приложения станут доступны другим программистам, которые смогут вызывать программу из командной строки и получать ее результаты в текстовом виде.
Программист Windows скорее всего начнет с GUI и, может быть, с некоторым опозданием добавит язык сценариев, автоматизирующий действие GUI. Это естественно для культуры, в которой 99,999% пользователей никоим образом не являются программистами и не испытывают желания стать ими.
Есть большая группа Windows-программистов, которые пишут код преимущественно для других программистов: это собственно команда Windows внутри Microsoft. Они стремятся к тому, чтобы создать API для вызова из языка C, реализующий функциональность, а затем создавать GUI приложения, обращающиеся к этому API. Любое действие, которое можно осуществить из интерфейса пользователя Windows, можно выполнить также через интерфейс программирования, вызываемый практически из любого языка программирования.
Например, собственно Microsoft Internet Explorer представляет собой лишь крошечную программу размером 89 Кбайт, служащую оболочкой для десятков очень мощных компонентов, свободно доступных квалифицированным Windows-программистам и в большинстве своем обладающих гибкостью и мощью. К сожалению, поскольку программистам недоступен исходный код этих компонентов, последние можно использовать только такими способами, которые были предварительно рассмотрены и разрешены разработчиками компонент в Microsoft, что не всегда может удовлетворить другого программиста. Кроме того, иногда обнаруживаются ошибки, в которых обычно виноват тот, кто обращается к API, и которые трудно или невозможно отладить в отсутствие исходного кода.
Тенденция UNIX-культуры предоставлять исходный код делает ее средой, для которой легче разрабатывать приложения. Любой разработчик приложений для Windows может рассказать вам, как он потратил четыре дня на исправление ошибки, потому что полагал, что объем памяти, возвращаемый функцией LocalSize, будет таким же, как размер памяти, которую он изначально запросил в LocalAlloc, или про какую-нибудь другую ошибку, которую он исправил бы в десять минут, будь ему доступен исходный код библиотеки. В качестве иллюстрации Рэймонд сочиняет занятную историю, в которую вполне может поверить всякий, кто имел дело с библиотеками в двоичном формате.
Теперь вы видите, в чем суть этих религиозных споров. UNIX лучше, потому что при отладке можно зайти в библиотеки. Windows лучше, потому что тетушка Мардж может увидеть подтверждение того, что ее почта действительно отправлена. На самом деле ни та, ни другая системы не лучше. В них просто разные системы ценностей.
В UNIX главная ценность – облегчить жизнь другим программистам, а в Windows главная ценность – облегчить жизнь тетушке Мардж.
Рассмотрим еще одно культурное различие. Рэймонд пишет: «Классическая документация UNIX пишется телеграфным стилем, но она полная… Этот стиль предполагает активного читателя, способного сделать очевидные и неупомянутые выводы из сказанного и обладающего достаточной уверенностью в себе, чтобы доверять этим выводам. Внимательно читайте каждое слово, потому что едва ли вам дважды станут повторять одно и то же». Боже мой, подумал я, ведь фактически он рекомендует молодым программистам продолжать писать никому не понятные страницы руководства.
С конечными пользователями такое не проходит. Рэймонд может называть это «сверхупрощающим высокомерием», но в культуре Windows признано, что конечные пользователи не любят читать, и если они снизойдут до того, чтобы прочесть вашу документацию, то прочтут только самое необходимое, и вам придется давать объяснения еще и еще раз… Отличительной чертой хорошего файла подсказки Windows является то, что средний читатель может изучать любую тему в отдельности, для чего ему не требуется знание каких-либо других тем.
Как же получилось, что базовые ценности оказались разными? Это еще одно достоинство книги Рэймонда: он уходит глубоко в историю и эволюцию UNIX и вооружает молодых программистов знанием всего исторического опыта культуры, начиная с 1969 года. Когда создавалась UNIX и формировались ее культурные ценности, конечного пользователя не существовало. Компьютеры были дороги, процессорное время было дорого, и знания о компьютерах сводились к тому, как программировать. Неудивительно, что образовавшаяся культура ценила то, что было полезно другим программистам.
Напротив, Windows создавалась с единственной целью: с выгодой продать как можно больше экземпляров. Мириады экземпляров. «Компьютер на каждом рабочем столе и в каждом доме» – вот что было прямой задачей разработчиков Windows, определяло их повестку дня и базовые ценности. Легкость использования непрограммистами была единственным способом получить доступ на каждый рабочий стол и в каждый дом, и потому «юзабилити Uber alles» стало культурной нормой. Программисты как целевая группа рассматривались на самом последнем месте.
Культурный раскол настолько глубок, что UNIX, по сути, никогда не претендовала на настольные системы. Тетушка Мардж фактически не сможет пользоваться UNIX, а неоднократные попытки создать для UNIX красивый интерфейс, с которым тетушка Мардж сможет работать, полностью провалились, потому что эти попытки делались программистами, насквозь пропитанными UNIX-культурой.
Например, UNIX поддерживает принцип разделения политики и механизма, исторически идущий от разработчиков X. Он прямо привел к расколу в пользовательских интерфейсах; договориться во всех деталях о том, каким должен быть UI настольной машины, толком никогда не могли, и считается, что это нормально, потому что в этой культуре ценится разнообразие. А вот для тетушки Мардж совершенно неприемлемо использовать в разных программах разные интерфейсы для копирования и вставки.
Вот таково положение через 20 лет после того, как разработчики UNIX начали попытки приладить к своим системам приличный интерфейс пользователя, когда глава крупнейшего поставщика Linux высказывает мнение, что домашним пользователям следует работать в Windows. Я слышал утверждения экономистов о том, что Кремниевую долину невозможно было бы воспроизвести, скажем, во Франции, потому что французская культура так жестоко наказывает неудачников, что предприниматели стараются не рисковать. Возможно, то же справедливо в отношении Linux: она может никогда не стать настольной операционной системой, потому что в ее культуре ценятся вещи, препятствующие этому.
Доказательством служит OS X: компания Apple все-таки создала UNIX для тетушки Мардж, но только потому, что инженеры и менеджеры Apple были прочно связаны с культурой конечного пользователя (которой я захватнически присвоил название «культуры Windows», хотя исторически она возникла в Apple). Они отказались от фундаментальной нормы культуры UNIX – построения вокруг интересов программиста. Они даже переименовали главные каталоги – полная ересь! – и стали употреблять обычные английские слова, например «applications» и «library» вместо «bin» и «lib».
Рэймонд делает попытку сравнить и противопоставить UNIX и другие операционные системы, и это самая слабая часть прекрасной в остальных отношениях книги, потому что он не знает предмета, о котором ведет речь. Как только он заговаривает о Windows, обнаруживается, что источником его знаний программирования для Windows оказываются по большей части газеты, а не опыт программирования в Windows. Ну и пусть, он – не Windows-программист, и простим ему это. Как это характерно для человека, глубоко знающего одну культуру, он знает, что ценится в его культуре, но плохо различает те части его культуры, которые универсальны (убиение старушек, аварийное завершение программ: всегда плохо), и те, которые относятся только к программированию для программистов (сырая рыба, аргументы командной строки: смотря для кого).
Есть очень много монокультурных программистов, которые, как типичный американский парень, никогда не выезжавший за пределы Сент-Пол, штат Миннесота, не ощущают разницы между ценностями, принадлежащими некой культуре, и базовыми человеческими ценностями. Я очень часто встречал UNIX-программистов, издевавшихся над программированием в Windows и считавших Windows варварством и глупостью. Рэймонд слишком часто попадает в ловушку пренебрежительного отношения к ценностям других культур без учета их истоков. Такой фанатизм довольно редко встречается среди программистов Windows, которые в целом ориентированы на решение задачи и свободны от идеологических предрассудков. Во всяком случае Windows-программисты признают недостатки своей культуры и прагматически говорят: «Видите ли, чтобы продать текстовый процессор как можно большему числу людей, его надо научить выполняться на их компьютерах, а если из-за этого приходится хранить настройки в Гнусном Реестре, а не в элегантных файлах ~/.rc, то тут уж ничего не поделаешь».
Мир UNIX пышет самодовольством культурного превосходства, пропаганды и поклонения карме Slashdot, тогда как мир Windows более практичен («да, что делать, надо же на жизнь зарабатывать»), и поэтому культура UNIX чувствует себя осажденной, не способной вырваться из серверной стойки и области хобби на широкие просторы настольных машин. Это высокомерие слабости – самый большой недостаток книги «The Art of UNIX Programming», хотя сам по себе он не столь велик.
В целом в книге настолько много чрезвычайно интересного и глубокого проникновения во многие аспекты программирования, что можно вытерпеть отдельные дурно попахивающие идеологические эскапады ради возможности многое почерпнуть из нее относительно всеобщих идеалов.
Я действительно рекомендую эту книгу разработчикам, к какой бы культуре они ни принадлежали, на любой платформе, с любыми задачами, потому что очень многие из провозглашаемых в ней ценностей являются универсальными. Когда Рэймонд указывает, что формат CSV хуже, чем формат /etc/passwd, он думает тем самым добавить очков UNIX против Windows, но знаете что? Он прав. /etc/passwd действительно проще разбирать, чем CSV, и, прочтя его книгу, вы узнаете почему и станете лучше как программист.