Разработка

JavaScript и области видимости

Об этой особенности полезно иногда вспоминать.

// глобальная переменная, которую мы попытаемся дальше получить
var bar = 42;

// Мозг предполагает, что до объявления bar в теле функциии глобальный bar будет доступен
function simple_define() {
    alert(bar);
    var bar = 10;
    alert(bar);
}

// Но это не так. Функция выше на самом деле выглядит вот так
function real_define() {
    var bar;
    alert(bar);
    bar = 10;
    alert(bar);
}

// А что же с условиями? Разве они не создают локальные области видимости?
function define_inside_if() {
    if (true) {
        var bar = -10;
    }
    
    alert(bar);
}

// Ну а циклы?
function define_inside_while() {
    do {
        var bar = 10;
    } while (false);
    alert(bar);
}

// И переменные из for?
function define_inside_for() {
    for (var bar = 0; bar < 10; bar++);
    alert(bar);
}

/* 
 * Да. Это особенность js - компилятор собирает все объявления переменных текущей области видимости
 * и выделяет под них все требуемые ресурсы сразу при входе в функцию.
 */
HowTo

Многопоточная компрессия и tar

Сколько можно? 🙂 Ядер все больше и больше, а

$ tar -cjf /mnt/_backup/`date '+%Y-%m-%d_%H-%M-%S'`.tbz2 /home

как работал в один поток, так и работает.

Есть два многопоточных решения:

  • pbzip2 — параллельный bzip
  • pigz — параллельный gzip
$ tar -c /home | pbzip2 -vc -9 -p7 /mnt/_backup/`date '+%Y-%m-%d_%H-%M-%S'`.tbz2

Опцией -p# можно управлять количеством ядер, которые будет использовать архиватор. Нормально — это N-1.

Аналогично и для gzip

$ tar -c /home | pigz -vc -9 -p7 /mnt/_backup/`date '+%Y-%m-%d_%H-%M-%S'`.tbz2

С удивлением открыл для себя, что — в bash по дефолту означает stdout. И

$ tar -cf - file

будет использовать в качестве файла stdout. 🙂

Разработка, HowTo

Firefox: NS_ERROR_FILE_CORRUPTED

Столкнулся сегодня с этой ошибкой в консоли фокса.

Причина проста: повреждение хранилища localStorage. Подробнее можно посмотреть официальную документацию.

Решается удалением файла

webappsstore.sqlite

.

В коде же это исключение так же следует обрабатывать корректно (чтобы не пугать пользователя).

try {
    setLocalStorageItem(key, value);
} catch(e) {
    if(e.name == "NS_ERROR_FILE_CORRUPTED") {
        showMessageSomehow("Sorry, it looks like your browser storage has been corrupted. Please clear your storage by going to Tools -> Clear Recent History -> Cookies and set time range to 'Everything'. This will remove the corrupted browser storage across all sites.");
    }
}

Странно, но в моем случае чистка всего-всего таки не помогла. Помогло ручное удаление файла.

Разработка, HowTo

Разработка на Python с использованием virtualenv

Virtual Environment — полезный инструмент, который позволет держать различные конфигурации зависимостей проектов в разных директориях. Например он решает проблему когда одному приложению требуется версия 1.0 пакета X, а другому — 2.0.

vitrualenv

Главным инструментов будет virtualenv.

$ sudo yum install python-virtualenv

Использование

Создадим окружение

$ cd project_dir
$ virtualenv proj_env

Этими командами мы создадим папку proj_env, которая будет содержать наше новое окружение. В этой папке будет набор скриптов и копия интерпретатора python, который будет использоваться в окружении (окружение использует свой интерпретатор, а не общесистемный).

При создании окружения можно указать, какая версия python нам нужна.

Возможно, что в системе параллельно стоит как python2, так и python3. Выбирать версию при создании окружения мы можем ключем -p. Если ключ не указан, то будет выбрана версия /usr/bin/python.

$ virtualenv -p /usr/bin/python3.4 proj_env

Для того, чтобы попасть в наше новое окружение используем

$ source proj_env/bin/activate

Теперь мы внутри окружения.

Определеить это можно по изменившемуся приглашению:

(proj_env)тут_старое_приглашение_из_$PS1

Все. Мы внутри окружения. Можно ставить зависимости для нашего приложения.

$ pip install flask flask-bootsrap rq rq-scheduler pymysql

Выйти из окружения можно при помощи

$ deactivate

Теперь мы попали обратно в систему с дефолтными интерпретаторами.

Сохранение информации о зависимостях

Опция —no-site-packages отключает использование глобально-установленных пакетов, что может быть полезно (сейчас это дефолтное поведение virtualenv).

Хорошей идей будет сохранить информацию об установленных в окружении пакетов.

{code lang=»shell»]$ pip freeze > requirements.txt[/code]

После развертывание окружения в новой системе можно поднять все пакеты сразу.

$ pip install -r requirements.txt

Не забываем добавить папку окружения в .gitignore.

virtualenverapper

Еще один полезный инструмент (скорее для разработчиков, а не для деплоя), который позволяет обращаться со со множеством окружений и переключаться между ними.

$ sudo yum install python-virtualenvwrapper

Применение

Добавляем в .bashrc

export WORKON_HOME=~/.envs
source /usr/bin/virtualenvwrapper.sh

Теперь можно создавать окружения.

$ mkvirtualenv proj_env

Активировать окружения.

$ workon proj_env

Выходить из окружения можно так же как это делалось в кготом virtualenv.

$ deactivate

Удалять окружения.

$ rmvirtualenv proj_env

При этом все папки окружений будет расположены в одном месте: папке, которая задана через $WORKON_HOME.

Дополнительные команды

Есть несколько дополнительных команд

  • lsvirtualenv — покажет список созданных окружений
  • cdvirtualenv — перейдет непосрественно в папку окружения
  • cdsitepackages — переведет в site-packages выбранного окруженияч
  • lssitepackages — сделает ls для папки site-packages

Посмотреть полный список команд.

autoenv

Утилита позволяет активировать окружение при входе в папку, и деактивировать при выходе.

$ git clone git://github.com/kennethreitz/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
linux

Tmux — лучшая альтернатива screen

Довольно долго пытался пересесть с GNU Screen на tmux, но вот только сдерживало несколько вещей в нем.
На сайте проекта можно найти описание всех фич, я же опишу лишь те, которые для меня оказались самыми полезными.

  • Улучшенная модель отрисовки (да-да screen периодически подключивал)
  • Содержимое терминала не теряется, когда мып ользуемся редакторами (открыли vim, закрыли, история осталась а месте и можно прокрутить до нее)
  • Конфигурирование на лету

C-b

Ага. Это сочетание клавишь из vim.

Переключим tmux на работу с C-a

set-option -g prefix C-a

Задержка между контрольными клавишами C-b и непосредственным вводом команды (например n).

Решается просто

set -s escape-time 0

Сочетание клавиш для управления tmux внутри tmux

Бывает такое, что приходится внутри tmux запустить вложенную сессию tmux. Значит надо как-то пробросить этой вложенной сессии команды. Например C-a a command

bind-key a send-prefix

Начинаме считать окна с 1, а не 0

Это удобно, так как 0 находится где-то на отшибе. И к нему надо тянуться.

set -g base-index 1

Агрессивный ресайз терминалов

Дефолтно при подключении к сессии нескольких клиентов рамер окна выбирается по размеру самого маленького клиента. Это неинтересно. Поэтому позволим терминалу для каждого клиента иметь собственный размер.

setw -g aggressive-resize on

После завершения команды можно ввести другую команду не нажимая C-b

Для меня эта проблема была самой неприятно. Воспроизвести ее просто: нужно на готом tmux создать два региона.

C-b "

А затем переключаться между ними.

C-b Up Down Up Down

Вы заметите, что нажав один раз C-b, а потом быстро нажимая вверх-вниз окна переключаются.

Это неприятно когда пытаешься переключить вкладку и начать тут же вводить что-то.

За такое поведение отвечает repeat-time

repeat-time time
  Allow multiple commands to be entered without pressing
  the prefix-key again in the specified time milliseconds
  (the default is 500).  Whether a key repeats may be set
  when it is bound using the -r flag to bind-key.  Repeat
  is enabled for the default keys bound to the resize-pane
  command.

Можно отключить repeat для команд переключения между панелями и окнами просто переобъявив команду без флага -r. Например так:

bind-key Up select-pane -U

Но я же предпочитаю эту фичу отключить вовсе.

set-option -g repeat-time 0

Базовый ~/.tmux.conf

# C-b не подходит - так как используется в vim
set-option -g prefix C-a
bind-key C-a last-window

# Начинам нумерацию окон с 1
set -g base-index 1

# Добавляем отзывчивости в реакции на команды
set -s escape-time 0

# Отключаем ожидание дополнительных команд
set-option -g repeat-time 0

# Или можно забиндить команды отдельно отключая repeat только для нужных
#bind-key Up select-pane -U

# Цветовая схема
set -g status-bg black
set -g status-fg white
set -g status-left ""
set -g status-right "#[fg=green]#H"

# Ресайзим содержимое окна индивидуально для каждого клиента
setw -g aggressive-resize on

# Позволим пробрасывать команды внутрь вложенной сессии tmux
# при помощи  C-a a <command>
bind-key a send-prefix

# Мониторинг активности
#setw -g monitor-activity on
#set -g visual-activity on

# Пример использования команды оболочки в статусной строке
#set -g status-right "#[fg=yellow]#(uptime | cut -d ',' -f 2-)"

# Подсвечиваем активное окно
set-window-option -g window-status-current-bg green

За кадром осталось использование tmuxinator для запуска tmux c определенной заранее раскладкой окон.

Ну и еще про настройку можно почитать в Arch-wiki.