Monday, December 28, 2009

Python: функция super()

Функция super(), как правило, используется для вызова метода, который был бы вызван, если бы не был найден данный метод:
class A(object):
def __init__(self): print "A init"

class B(A):
def __init__(self):
print "B init"
super(B, self).__init__()

>>> x = B()
B init
A init

Функция возвращает прокси-объект, который делегирует вызовы методов нужным классам.
Порядок поиска методов такой же, как и в getattr(), но поиск не учитывает сам класс.

Sunday, December 27, 2009

Port forwarding

"Connecting to the external address of the firewall from a host on the LAN, does not mean the packets will actually pass through its external interface. The TCP/IP stack on the firewall compares the destination address of incoming packets with its own addresses and aliases and detects connections to itself as soon as they have passed the internal interface. Such packets do not physically pass through the external interface, and the stack does not simulate such a passage in any way."

Поэтому тестирование порт-форвардинга из локальной сети может не сработать. Есть и способы пофиксить.

Sunday, December 20, 2009

Настройка беспроводной сети в FreeBSD

После прочтения соответствующего раздела в хэндбуке, у меня осталось несколько вопросов. В частности, почему ifconfig_wlan0="WPA DHCP" может использоваться как для WPA, так и для WEP аутентификации.

На самом деле "WPA" (и "DHCP" тоже) это псевдо параметр, который не передается напрямую ifconfig. При старте сети его наличие указывает на необходимость запуска программы wpa_supplicant(8), которая производит аутентификацию. В этом можно убедиться, заглянув в код /etc/network.subr.

Также в хэндбуке не упоминается о полезной утилите wpa_passphrase, которая генерит хэш пароля, пригодный для вставки в wpa_supplicant.conf.

Monday, December 14, 2009

"NTLD is missing" после установки FreeBSD

Некоторые производители ОС проводят монопольную политику, и только FreeBSD это делает неосознанно - посредством багов в инсталляторе :-)

Время от времени при установке FreeBSD на винт с установленной виндой (в первом разделе), каким то образом херятся загрузочная область этого раздела. В результате при загрузке выдается "NTLDR IS MISSING". Причем, все виндовые файлы на месте. Т.е. их копирование туда не помогает ни разу. Установка grub тоже не помогает - он успешно находит виндовый раздел, но при загрузке та же фигня.

Мистика сцуко.

UPDATE:

Пришлось снова вернуться к этому посту, поскольку данный баг проявился у меня недавно при установке Arch Linux на тот же комп! Недаром у них с FreeBSD исталляторы похожи... Чтобы разобраться в проблеме, проделал установку еще раз, предварительно сохранив начальные сектора диска и виндового раздела командой dd. Установка производилась в уже имеющийся раздел. Несмотря на это, инсталлятор почему то изменил первый сектор, a.k.a. MBR. Предполагаю, что изменяется 4-байтная сигнатура диска, которая используется при загрузке винды. Запись сохраненной копии MBR обратно на диск, естественно, решило проблему. Мораль: бэкап MBR перед установкой OS - суровая необходимость.

Использованные команды:

бэкап:
dd if=/dev/ad4 of=mbr bs=512 count=1

восстановление:
sysctl kern.geom.debugflags=16   #позволяет менять MBR на "живой" системе
dd if=mbr of=/dev/ad4 bs=512 count=1
З.Ы. Для доступа в винду при наличии ошибки "NTLDR IS MISSING" полезным может оказаться загрузочный CD, взятый отсюда.

Tuesday, December 8, 2009

vimtutor

Отличный способ начать освоение vim - vimtutor. Это обычный шелл-скрипт, который запускает собственно Vim с копией туториала. Жаль, что он в свое время мне не попался на глаза :)

ЗЫ. Язык учебника можно задать параметром, e.g.: vimtutor ru. По умолчанию используется английский.

Tuesday, December 1, 2009

UFS2 subdirectory limit

UFS/UFS2, ext2/ex3 ограничивают число папок в отдельно взятой папке значениями 32767 и 32000 соответственно.

Это легко проверить имея одну из этих файловых систем:

mkdir tmp; cd /tmp;
for i in $(seq 32767); do mkdir $i; done
...
mkdir: 32766: Too many links
mkdir: 32767: Too many links

(Директория всегда имеет два дефолтных линка: '.' и '..').

Кстати, в ext4 лимит увеличен до 64000.

Saturday, November 28, 2009

Аналоги mysql команд для psql
































mysql psql
SHOW DATABASES l
USE database c database
SHOW TABLES dt
DESCRIBE table
(SHOW COLUMNS FROM table)
d table
SHOW CREATE TABLE table
SELECT DATABASE() SELECT CURRENT_DATABASE()

Thursday, November 19, 2009

Немного про good practices

И Perl, и Python допускают наличие хвостовой запятой в списках и словарях. Но в питоне эта фича может оказаться важнее.

Например, где то в коде есть tuple:


c = (
'Japan',
'United Kingdom',
'Greece',
'Albania',
'Brazil',
'Russia'
);
Редактируя файл, мне захотелось отсортировать страны, благо в vim-е это делается простым выделением и командой :sort. Получаем:


c = (
'Albania',
'Brazil',
'Greece',
'Japan',
'Russia'
'United Kingdom',
);

Случайно забыв про запятую, сохраняем файл.
Никаких нареканий со стороны интерпретатора это не вызовет, т.к. питон автоматически склеивает смежные строки.
IMHO, это некоторое расхождение с питоновским слоганом "Explicit is better than implicit."

В перле все проще - упираемся в ошибку "String found where operator expected".

Thursday, November 12, 2009

Некоторые факты о языке python

В последнее время накопилось большое число заметок о питоне. Решил сделать небольшой brain dump, в напутствие начинающим..

Sunday, November 8, 2009

Про интерполяцию в перле

Для "интерполируемых" конструкций (например, qq{}, qx{}, m{}, etc.) переменные, которые начинаются с "$" или "@" интерполируются. Так написано в man perlop. Но, есть и интересные детали..

Интерполяция имеет место быть и в следующих случаях:
  • print "$a[$i+1]";
  • print "$r->[1]";
  • print "$a[$f->()+1]";
  • print "@a[2..$f->()]";
Суммируя: операторы в отличие от переменных не интерполируются. За исключением случаев, когда интерполяция переменной требует значение от оператора, либо оператор представляет собой разыменование ссылки и за ним следует '[' или '{'.

По моему, неплохое средство обфускации кода :-)

P.S. Ссылка.

Thursday, October 29, 2009

LWP::UserAgent: обработка файлов на лету

Для того, чтобы обработать файл (например zip-архив) без предварительного сохранения, можно открыть контент как in-memory file:
my $response = $ua->get($url);

if ($response->is_success) {
open my $fh, '<', $response->content_ref or die "Open failed: $!";
# do smth with $fh
}
else { die $response->status_line }


Как видно из примера, в качестве 3-го аргумента open в данном случае передается ссылка на скаляр.

Данный прием также довольно удобно применять для построчной обработки текста, сохраненного в скалярной переменной.

Sunday, October 25, 2009

Мелочь, а приятно..

"ftp.mgts.by является официальным зеркалом debian для архитектур i386 и amd64, а так же проектов debian-cd, debian-security, backports.org и debian-volatile".

Соответственно, зеркало можно выбрать на этапе установки debian c netinst. При настроенном гостевом подключении к byfly скорость у меня была в районе 185 KB/s.

Thursday, October 22, 2009

FreeBSD и skype

Ставить skype на FreeBSD - это как-то противоестественно, но иногда приходится. Порт довольно геморройный, и практически всегда вылазят какие то грабли.

На этот раз, например, при запуске вместо нормального текста везде квадратики.

После долгих мытарств нашел фикс для kde4: тулзой qtconfig-qt4 можно  подобрать шрифт, с которым будет нормально отображаться текст (шрифты применяются в real-time).



Update: по состоянию на 2011-02-18, skype-2.0.0.72,1 -- последняя версия работающая под FreeBSD, причем инсталлятор более недоступен на сайте skype.com.

Его надо положить вручную в /usr/ports/distfiles и запустить установку командой:
make TRYBROKEN= install clean

После этого на 8.1 + KDE4 установился и запустился без проблем (!) Единственное дополнительное действие, которое понадобилось - указать записывающее устройство. По умолчанию стояло почему то cd, надо mic:
mixer -S =rec mic

Thursday, October 8, 2009

Perl: передача параметров при загрузке модуля

При загрузке модуля с помощью use, можно передать ему произвольные параметры:


package TestPackage;
use Other::Package 'param1', 'param2';

При этом вызывается метод import подгружаемого модуля, с переданными параметрами:


package Other::Package;
sub import {
my($class, @params) = @_;}
 
Может оказаться полезным, если надо инициализировать какие то переменные модуля.

perl segfault

Интерпретатор перла не идеален :-)

% perl -e '$x = []; push @$x, eval { $x = 1; return $x }'
Segmentation fault: 11

% perl -e 'print unpack ("p*", "1.2.3.4")'
Segmentation fault: 11

% perl -e 'sub foo { /(?{ return })/ } for (1..100) { foo }'
Segmentation fault: 11

Wednesday, October 7, 2009

Улыбнуло

Ссылко
Вкратце. Как инвертировать знак числа, примеры из жизни.

Вариант I: 

  1. private function opposite(number:Number):Number
  2.         {
  3.                 if (number < 0)
  4.                 {
  5.                         number = Math.abs(number);
  6.                 }
  7.                 else
  8.                 {
  9.                         number = -(number);
  10.                 }
  11.                 return number;
  12.         }
Вариант II:

  1. int x = numberToInvertSign;
  2. boolean pos = x > 0;
  3. for(int i = 0; i < 2*Math.abs(x); i++){
  4.    if(pos){
  5.       numberToInvertSign--;
  6.    }
  7.    else{
  8.       numberToInvertSign++;
  9.    }
  10. }
Вариант III (особо зачотный) :

  1. switch (i)
  2. {
  3.   case 1: return -1;
  4.   case 2: return -2;
  5.   case 3: return -3;
  6.   // ... etc, you get the proper pattern
  7. }
Правильный ответ (на всякий случай): return number * -1



Tuesday, October 6, 2009

До чего дошел прогресс

Обзавелся для работы ноутом Dell Vostro A860.
Как оказалось, для соединения его с другим компом вполне себе подходит прямой кабель (обжатый с двух сторон по стандарту EIA/TIA-568B).
И нафиг был изначально этот гемор с кроссоверами ?

Tuesday, September 29, 2009

mysql: команда pager

Если в консольном клиенте mysql задать pager, результат будет отправляться не на экран, а на stdin указанной программе. Чем это может быть полезно?


  1. Просмотр, редактирование и сохранение результатов запроса. Можно использовать vim или less:
    mysql> pager vim -



  2. Проверить идентичность результатов можно используя утилиту md5 (md5sum):

    mysql> pager md5
    PAGER set to 'md5'
    mysql> SELECT CURDATE(), CURTIME();
    d24e22e4e2d33dfda9f01ba934b7676a



  3. Отменить пейджер можно командой nopager.

Wednesday, September 23, 2009

Zen of Python and Perl mantras

Знакомство с питоном как правило начинается с "The Zen of Python":
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Кстати, исходный код модуля this содержит пример кодировки ROT13 ;)

У Perl-а тоже есть свои слоганы, причем автор самых известных — создатель языка:
There's more than one way to do it. — Larry Wall
Easy things should be easy, and hard things should be possible. — Larry Wall
Do what I mean.
The three principle virtues of a programmer are Laziness, Impatience, and Hubris.
If C is the Swiss Army Knife of programming languages, Perl is the Swiss Army Chainsaw.

Sunday, September 20, 2009

Парадокс?

Для того, чтобы действительно хорошо программировать на Perl, к примеру, недостаточно просто программировать на Perl.
Надо бы еще ознакомиться с СPython, etc. (чем больше, тем лучше).

Иными словами, важно быть разносторонним программистом. Зная о подходах к решению проблемы в других языках, можно их приспособить к нужному языку.

Perl: выбор случайных элементов из списка с учетом веса

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

В perlfaq5 содержится простой до безобразия однострочник, который выбирает случайную строку в файле:
rand($.) < 1 && ($line = $_) while <>;

Этот алгоритм применим к задаче. Все что нам надо - это сделать выбор объектов с большим весом более вероятным:
sub pickAnObject {
my ($hObjects) = @_; # хэш, связывающий ID объекта и его вес
my ($total, $result);

while (my ($objectID, $weight) = each %$hObjects) {
rand($total += $weight) < $weight and $result = $objectID;
}
return $result;
}


Алгоритм хорошо подходит для случаев, когда число элементов невелико.

Thursday, September 10, 2009

bash prompt с человеческим лицом

Давненько я не твикал свой bash prompt. Вот недавно увидел прикольную фичу.
Часто в приглашении выводится значение, которое вернула последняя команда. Можно пойти дальше, и вместо числа выводить ":)" при успешном завершении и ":(" при неуспешном. (Более экспрессивный вариант: ^_^ и O_O). Для этого в PS1 можно вставить такую функцию:


function smiley () {
local status=$?
if [ $status -eq 0 ]; then
echo ':)'
else
echo ":( $status"
fi
}
Пример PS1 (вместо $COLOR* надо подставить последовательности для нужного цвета):


PS1="$COLOR1$(smiley) u@h $COLOR2w $ $JOBS_COLOR$(printJobs)$NO_COLOR"
Выглядит это примерно так:

:) doer@coyote /usr/home/doer $ (j:3)

Можно смайлики выводить разными цветами, наподобие этого:


PS1="`if [ $? = 0 ]; then echo [e[33m]^_^[e[0m]; else echo [e[31m]O_O[e[0m]; fi` u@h $COLOR2w $ $JOBS_COLOR$(printJobs)$NO_COLOR"

Улучшения/предложения приветствуются.

Tuesday, September 8, 2009

О языках программирования

Язык программирования, как инструмент,  должен подходить и соответствовать образу мышления программиста, использующего его. Только в этом случае он становится превосходным.

Исходя из этого я (когда-нибудь) остановлюсь на Python-е :-)

Saturday, September 5, 2009

Исключения (exceptions) в Перле

В Перле нет исключений, т.е. они не являются частью языка. Но, исключения можно успешно имитировать простой связкой eval + die.

eval { 
open my $fh, '>', $file or die "Could not open file! $!";
};
if( $@ ) { # catch and handle error }

Блоки eval { ... } могут быть вложенными. И, если вызывать die() без аргумента, то используется текст предыдущей ошибки с добавлением строки "t...propagated" (+ номер строки скриптa + "n"):

eval {
eval {
eval {
open my($fh), ">", "/etc/passwd" or die "$!"
};
if( $@ ) { die }
};
if ( $@ ) { die }
};
if( $@ ) { print "Error: $@" }

Error: Permission denied at -e line 3.
...propagated at -e line 4.
...propagated at -e line 6.

Строка - не всегда удобный способ передачи информации об ошибке. Аргументом die() может быть ссылка, а значит и объект. Если вызов происходит внутри блока eval, $@ будет содержать ссылку/объект, содержащий нужную информацию об ошибке. В этом случае правда придется перегружать оператор '"' (для объекта), чтобы необработанные ошибки выводились нормальной строкой.

Monday, August 31, 2009

Perl: как определить, из какого модуля импортирована функция

Как известно, при загрузке модуля с помощью use может происходить автоматический импорт функций или переменных в текущее пространство имен. Я не буду сейчас судить, насколько это хорошая практика программирования, но иногда требуется определить, из какого модуля импортирована функция.

В этом нам поможет модуль Devel::Peek. Делаем дамп ссылки на интересующую функцию и смотрим параметр GVGV::GV:

$ perl -MEncode -MDevel::Peek -e 'Dump &encode'
...
GVGV::GV = 0x284a9d48 "Encode" :: "encode"
...
В качестве альтернативы можно использовать Sub::Identify.

Если нет возможности установить эти модули, можно использовать такой подход: последовательно добавляем () ко всем выражениям use Module, пока не получим ошибку "Undefined subroutine ...".

Кстати, интересно, почему в пропиареную Perl Best Practices не включена хорошая практика: всегда использовать синтаксис use Module LIST вместо use Module, явно перечисляя имена импортируемых функций.

Sunday, August 30, 2009

Об аутентификации в mysql

MySQL снова удивил.
Допустим, нам надо добавить пользователя и разрешить ему доступ с любого хоста. По памяти набираю:

CREATE USER 'user'@'%' IDENTIFIED BY 'pass';
GRANT ALL PRIVILEGES ON mybd.* TO 'user'@'% WITH GRANT OPTION;

Вроде бы все ок. Тестируем с локального хоста, получаем 'Access denied'.

С паролями все ОК - хэш в таблице `user` совпадает с PASSWORD('pass'). В чем же дело ?

Таблица `user` сортируется перед использованием. Причем сперва по полю 'Host', потом 'User'.
Просмотр таблицы идет до первой подходящей записи. Поэтому в примере выше будет использоваться
запись ''@localhost а не 'user'@'%'. Для того чтобы можно было зайти с любого хоста, придется добавить
еще одну запись:

GRANT ALL PRIVILEGES ON mydb.* TO 'user'@'localhost' WITH GRANT OPTION;

Интересно, используется ли подобный алгоритм в других СУБД. Если кто в курсе - черкните в комменты.

Saturday, August 29, 2009

How::Do::I::Alias::This::Package::Name

Простой способ создания алиасов для перловых классов с именами типа Really::Long::Package::Names::You::Cant::Remember

use Really::Long::Package::Names::You::Cant::Remember;
sub MyRemember () { 'Really::Long::Package::Names::You::Cant::Remember' }

my $object = MyRemember->new; 

Достоинства этого метода:
  1. Никаких заморочек с нэймспейсами.
  2. Алиас подставляется на этапе компиляции (constant function), т.е. потерь в производительности нет.
  3. Ну и меньше печатания :-)
See also: aliased

На заметку (bash)

Чтобы заныкать какую-нить длинную команду (или просто текст) в history не выполняя её, набираем команду и нажимаем
ESC, # (или Ctrl-A, #, Enter). Впоследствии можно вернуться к этой команде, удалить знак комментария вначале и выполнить её.

Wednesday, August 26, 2009

Садистские упражнения

В предыдущем посте я писал, как меня напрягают админы использующие для частных сетей (с выходом в инет)
произвольные адреса. Как и следовало ожидать, в вопросах администрирования у таких "спецов" тоже несколько своеобразный подход. Несколько примеров, замеченных мной на РЕАЛЬНЫХ рабочих серверах.

Sunday, August 23, 2009

Perl: short-circuit operators

Логические short-circuit операторы - это те, которые определяют истинность выражения, вычисляя наименьшее число операндов, достаточное для определения значения выражения. Это отличает их от операторов, которые вычисляют значение всех элементов в выражении (например, & и | в Java).

В Perl такими операторами являются:&& , and , || и or. Пример:

open my $fh, '<', "input.txt" or die $!;


В отличие, например, от C, в Perl данные операторы возвращают не 0 или 1, а последнее вычисленное значение. Это позволяет писать выражения вроде:

$home = $ENV{HOME} || (getpwuid($<))[7] || die "You're homeless!n";


Возвращаемое значение определяется аналогично также в Python/Ruby/Javascript (но не в PHP %). Подробнее тут.

Индукция

Что можно сказать о "системном администраторе", между прочим неплохо оплачиваемом, который назначает в локальной офисной сети адреса 172/8? Как минимум:
  1. C данным документом он явно не знаком. И вообще не задавался вопросом, а какие собственно IP-адреса принято назначать локальным сетям.


  2. В анамнезе скорей всего будет присутствовать офисная или домашняя сеть 172.16/12. (Или 172/8, настроенная такими же псевдоадминами).

Thursday, August 20, 2009

Perl: прототипы встроенных функций

Функция sprintf при передаче ей массива в качестве аргумента ведет себя не так, как printf:
sub test1 { printf @_        }
sub test2 { print sprintf @_ }

test1 "%s", "ok"; # prints "ok"
test2 "%s", "ok"; # prints "2"

Всё потому, что sprintf в отличие от printf имеет прототип $@:
perl -le 'print "$_ - ".prototype $_ for ("CORE::sprintf", "CORE::printf")'
CORE::sprintf - $@
CORE::printf -


Соответственно, свой первый аргумент sprintf использует в скалярном контексте. Эта особенность упоминается в perldoc:

Unlike printf, sprintf does not do what you probably mean when you pass it an array as your first argument. The array is given scalar context, and instead of using the 0th element of the array as the format, Perl will use the count of elements in the array as the format, which is almost never useful.


Как вариант, вторую функцию можно переписать так:
sub test2 { print sprintf shift, @_ }

Wednesday, August 19, 2009

Любопытство

Недавно получил простой вопрос - где логически находится DNS-resolver (e.g. это часть приложения, часть операционной системы, etc.)? Я как то сходу и не ответил, т.к. системным программированием не занимался. Но как человек любопытный, решил немного покопаться в манах своей рабочей FreeBSD.

Thursday, August 13, 2009

рабочее

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

Оказывается этому даже учат в умных книжках, типа "Code Complete", которой я никогда не читал.
Тут более подробно об этом подходе.

Saturday, August 8, 2009

dyndns

Понадобилось мне привязать к своему домашнему компу (с динамическим IP) доменное имя.
Как оказалось, это легко сделать используя ресурсы вроде dyndns.com. Согласно доке на сайте, настройка сводится к следующим пунктам:

  1. Настраиваем сервис, к которому нужно получить доступ.
  2. Настраиваем форвардинг портов (если надо).
  3. Тестируем доступность сервиса извне.
  4. Создаем аккаунт на dyndns.com, выбираем доменное имя.
  5. Устанавливаем клиента для обновления нашей DNS-записи.
В качестве клиента я установил ddclient. A тут можно даже автоматически сгенерить для него конфиг. Лепота...

Sunday, July 26, 2009

Unix pipes: наводим красоту

Что такое pipe я думаю знают все пользователи unixlikes.
С помощью утилиты pv (pipe viewer) можно визуализировать поток данных через пайп, а также узнать пропускную способность и ETA.

Используется pv аналогично cat:

pv access.log | gzip > access.log.gz
611MB 0:00:11 [58.3MB/s] [=> ] 15% ETA 0:00:59

tar -cf - . | pv -s $(du -sb . | awk '{print $1}') | gzip > out.tgz
253MB 0:00:05 [46.7MB/s] [> ] 1% ETA 0:04:49




Saturday, July 25, 2009

Perl: особенности работы с хэшами

Для каждого хэша в скрипте существует единственый итератор, который совместно используется функциями each, keys и values. Он позволяет данным функциям отслеживать, где именно в хэше они находятся. Сброс итератора происходит автоматически, когда весь хэш прочитан или при вызове keys и values.

Типичный пример обхода хэша:
while (my ($key, $value) = each %hash) {
...
}


Если внутри цикла написать keys %hash, то цикл превратится в бесконечный (keys даже в void-контексте сбросит внутренний итератор хэша).

Вместо keys, кстати, можно написать Data::Dumper::Dumper(%hash) - эффект будет тот же. Поэтому, внутри цикла each не стоит вызывать какие-либо функции, которые так или иначе используют данный хэш.

Friday, July 10, 2009

wifi это зло

На работе стала обрываться wi-fi сеть. Железо: D-link DWA-510 на FreeBSD 7.2.
Перепробовал все режимы, каналы и всю прочую хрень из man ifconfig - нифига. Сеть появляется периодами на 5-10 минут и пропадает. Помогло только перетягивание компа на 3 метра по направлению к точке доступа.

Хотя даже на новом месте соотношение сигнал/шум показывает S:N -88:-95, т.е. 7 dB. Я подозреваю, что это далеко не оптимальное значение, но вроде все работает.

UPDATE:  тут приводятся примерные значения по SNR (Signal to Noise Ratio): 
  • > 40dB SNR = Excellent signal (5 bars); always associated; lightning fast.
  • 25dB to 40dB SNR = Very good signal (3 - 4 bars); always associated; very fast.
  • 15dB to 25dB SNR = Low signal (2 bars); always associated; usually fast.
  • 10dB to 15dB SNR = Very low signal (1 bar); mostly associated; mostly slow.
  • 5dB   to 10dB SNR = No signal; not associated; no go.
Если верить этому, мое соединение по-прежнему в красной зоне. Кто пользуется вайфаем - поделитесь своими цифрами (freebsd: ifconfig ral0 list scan, linux: iwconfig).

Wednesday, July 8, 2009

Условное включение элементов в список в Perl

Оригинальный способ включения элементов в список на основе некоторых условий:
my @list = (
($element1) x !!$condition1,
($element2) x !!$condition2,
($element3) x !!$condition3,
);

Очень даже лаконично. Однако надо учитывать, что значение, например, $element1 вычисляется в любом случае (даже если $condition1 дает FALSE).
Еще один зачОтный пример, перекликающийся с первым, - альтернатива тернарному "?:" :
$a = $ok ? $b : $c;
$a = ($c, $b)[!!$ok];

Thursday, July 2, 2009

странности в FreeBSD ports

Решил намедне скачать сырцы mysql6. Как известно, делается это командой make fetch в директории порта:
# cd /usr/ports/databases/mysql60-server && make fetch

В результате вывалилось следующее:
===>  mysql-server-6.0.11 cannot install: MySQL versions mismatch: mysql50-client is installed and wanted version is mysql60-client.
*** Error code 1
Stop in /usr/ports/databases/mysql60-server.

Похоже на баг системы портов.
Если запустить с установленной переменной окружения NO_IGNORE, то работает (в этом конкретном случае):
# NO_IGNORE= make fetch

В некоторых случаях понадобится установить и TRYBROKEN.
А если и это не помогает, придется выколупывать URL из Makefile-а и качать wget-ом.

Wednesday, June 24, 2009

MySQL: хранимые процедуры

Некоторые "особенности" работы с функциями/процедурами/триггерами в MySQL.

  1. Внутри блока BEGIN-END должен соблюдаться следующий порядок :
    BEGIN
    DECLARE variables;
    DECLARE cursors;
    DECLARE conditions;
    DECLARE handlers;
    ...
    END;

  2. Если какая-то команда (например PREPARE) не допускается в функции (триггере), то вызвать из неё процедуру, содержащую такую команду также не получится.


  3. PREPARE/EXECUTE не работает с локальными переменными - только глобальные переменные (типа @a, @b).

    Это работать не будет:
    DECLARE sql VARCHAR(32) DEFAULT 'SELECT 1';
    PREPARE stmt FROM sql;

    То же самое относится и к EXECUTE .. USING ..


  4. FETCH [cursor_name] INTO .. не работает с глобальными переменными.  (!?)

    Это работать не будет:
    FETCH mycursor INTO @a;

  5. PREPARE не может использоваться для объявления курсора.


  6. COMMIT не может использоваться в функциях и триггерах (соответственно, см п.2).


  7. Тело процедуры нельзя изменить с помощью ALTER PROCEDURE. Для этого надо последовательно выполнить DROP PROCEDURE и CREATE PROCEDURE.

Thursday, June 18, 2009

Perl: дебаг LWP::UserAgent и семейства

Довольно часто при использовании LWP (LWP::Useragent, WWW::Mechanize, etc.) возникает необходимость просмотра/анализа HTTP-заголовков. Для firefox есть плагин - Live HTTP Headers. А в этой заметке я расскажу, как получить нечто подобное в Perl.

Cредствами самого LWP::UserAgent, печатать HTTP-заголовки можно так:

use LWP::UserAgent;
my $ua = LWP::UserAgent->new();

$ua->add_handler(
"request_send",
sub {
my $r = shift;
print "==>n", $r->as_string;
return;
},
);
$ua->add_handler(
"response_done",
sub {
my $r = shift;
print "<==n", $r->status_line, "n", $r->headers->as_string, "n";
},
);

$ua->get("http://google.com");


В результате получаем:
==>
GET http://google.com
User-Agent: libwww-perl/5.834

<==
301 Moved Permanently
Cache-Control: public, max-age=2592000
Connection: close
Date: Wed, 29 Sep 2010 20:11:29 GMT
Location: http://www.google.com/
Server: gws
Content-Length: 219
Content-Type: text/html; charset=UTF-8
Expires: Fri, 29 Oct 2010 20:11:29 GMT
Client-Date: Wed, 29 Sep 2010 20:11:29 GMT
Client-Peer: 74.125.232.20:80
Client-Response-Num: 1
Title: 301 Moved
X-XSS-Protection: 1; mode=block

==>
GET http://www.google.com/
User-Agent: libwww-perl/5.834
...



Для разнообразия, еще один способ с использованием модуля Aspect:

use Aspect;

my $pointcut = call 'LWP::UserAgent::send_request';

before {
print "==>n", shift->params->[1]->as_string;
} $pointcut;

after {
my $resp = shift->return_value;
print "<==n", $resp->status_line, "n", $resp->headers->as_string, "n";
} $pointcut;

my $ua = LWP::UserAgent->new();
$ua->get("http://google.com");


В результате печатается то же самое.

Wednesday, June 17, 2009

калькулятор в unix

В любой unix-системе есть много чего, что можно заюзать в качестве калькулятора.
Вот несколько примеров:

  1. bc. Без аргументов запускается интерактивный калькулятор.  Можно использовать и так: echo "2^32-1" | bc

  2. Интерпретаторы (awk, perl, python, ruby, etc). Можно использовать как в интерактивном режиме, так и для одиночных выражений. Мне лично удобней python :)

  3. javascript. В адресной строке браузера можно вычислить выражение указав его после псевдопротокола javascript:, например javascript:5%2. В консоли браузера можно писать только выражение.

  4. mysql. SELECT 1024 + POW(2, 10);

  5. vim, bash, expr. Подходят для целочисленных вычислений.

  6. ...

Wednesday, May 13, 2009

Правильное обновление портов в FreeBSD

Хорошая привычка - просматривать файл /usr/ports/UPDATING перед апгрейдом софта из портов в FreeBSD. Иногда это может сэкономить кучу времени. Как написано в самом файле:
You should get into the habit of checking this file for changes each time
you update your ports collection, before attempting any port upgrades.

Для автоматизации этого действия я использую следующий алиас:
alias updatePorts 'portsnap fetch update &&
perl -0777 -F"(?=nd+:n)" -wane "print @F[1,2]" /usr/ports/UPDATING'

Первая команда собственно обновляет порты, а вторая выводит две последние записи из файла /usr/ports/UPDATING.

Thursday, April 16, 2009

Как реализовать Singleton в Perl

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

Чтобы создать Singleton-класс в Perl, можно воспользоваться модулем Class::Singleton. Этот модуль предоставляет метод instance, при вызове которого возвращается один и тот же объект, заботливо сохраненный в глобальной переменной отнаследованного класса:
package MyConfig;
use base 'Class::Singleton';
...

# в основной программе
my $conf1 = MyConfig->instance(); # создан объект MyConfig
my $conf2 = MyConfig->instance(); # тот же самый объект


Еще один распространный способ - сохранение объекта в объявленной с помощью my локальной переменной, доступной из конструктора. (Начиная с версии Perl 5.10, для этого также можно использовать state):


package MyConfig;

{
my $singleton;
sub instance {
unless (defined $singleton) {
my $class = shift;
my $self = {};
$singleton = bless $self, $class;
}
return $singleton;
}
}


Этот метод отлично подходит, если класс не наследуется. В противном случае лучше использовать Class::Singleton.

Monday, February 16, 2009

Неопределенное поведение в Perl

В Perl, как и в C, встречаются случаи неопределенного поведения. Классический пример - изменение переменной дважды в одном выражении, e.g.

perl -le '$i=10; print ++$i + ++$i + ++$i' # печатает 37

Сюда же можно отнести:


  • "my" с модификатором, например: my $x if 1;

  • Использование функции sort() в скалярном контексте

  • 1<<32, если тип integer имеет размер 32 бита

  • и т.д.