Sunday, December 26, 2010
О маразме некоторых преподавателей информатики
Итак, дело дошло до зачёта. Мне там выпал билетик про каноническую форму перестановок. Программу этот <censored> принял, но его придирки были фееричненькие. Там критиковать их было, наверное, бессмысленно (всё равно такие не лечатся, да и вообще — на зачёте себе дороже), так что раскритикую здесь. В пух и прах.
Friday, December 24, 2010
Sort of introduction to J.
Let's consider just one example. Suppose we wanna investigate the sequence of first digits of powers of 2. (1,2,4,8,16,32,64,128,256,...) The question is: what's the frequency of the digit 7? (You can find via search engines several versions of this problem: this, for example.)
Using J, we can find (well, estimate) the answer in one line:
(+%~(#&I.&(7=<.&(10^1|(10^.2)&*&i.)))) 1000000 0.05799The exact answer is
.
That follows from the equidistribution theorem.
So, what does this mess of symbols mean?
Monday, December 20, 2010
GPS & Ruby: dealing with performance bottlenecks
For tests I've used 2.7MB .nmea file. It contains about 5 thousand GPRMC sentences from which about 3 thousand contain useful information.
The first version of readNMEA function takes about 0.87 seconds (on my Asus EeePC 1001P) to make an array of GPRMC class instances. How can we improve that?
Firstly, access to the elements of an array (by index) is faster than access to the elements of a hash (by key). Thus using old-style regular expressions decreases the time from 0.87 to 0.72 seconds:
Monday, December 13, 2010
И ещё чуть-чуть о программизме.
Вот. Теперь немного о самом LISP. При исключительно императивном программировании код выглядит... эм... не то чтобы ужасно, но непомерно раздуто. Скажем, доступ к i-му элементу вектора vec записывается как (aref vec i) , а присваивание ему значения a — (setf (aref vec i) a). Однако не стоит думать, что это сказывается на скорости программирования. Отнюдь! Дело в том, что в си-подобных языках при стандартной постановке пальцев очень много работы отводится мизинцу: доступ к элементу массива — [ ], блок кода — {}, присваивание — =, разделение операторов — ; . Поэтому я всегда использую нечто нестандартное, и скорость печати вследствие этого снижается. В LISP же в основном используются только латинские буквы, дефис и чёртова уйма скобочек, так что никакой особой распальцовки не требуется.
А может, я отстал от жизни, и у сегодняшних "программистов" (да-да, в кавычках) наипопулярнейшей комбинацией клавиш является Ctrl-Space. (Об этом меня заставил задуматься тот факт, что вчера на турнире по программированию я решил задачу на Java, не писав на ней до этого ни разу и пользуясь лишь автодополнением, предоставляемым Eclipse.)
Помнится, как-то раз попал в плацкартном вагоне в одно купе с одним
90;аким "программистом". Тот кодил в какой-то конторе уже лет 5 (на C#, ЕМНИП) и тем не менее, как выяснилось, не знал о существовании Python, который сейчас, в общем-то, весьма активно используется в веб-разработке. И при этом (NB!) жаловался, что наскучила ему разработка, понимаешь. Как будто втемяшили себе в голову, что окромя мейнстримовых языков (то бишь "святой троицы" C++, C#, Java) и не существует ничего =/ Брр.
Tuesday, December 7, 2010
clisp && sbcl
Изначально я установил только CLISP и довольно долго был уверен, что этого мне будет достаточно. Ан нет: эта штука генерирует весьма тормозной байткод. Для работы в интерактивном режиме лучше CLISP ничего не придумаешь, а вот для исполнения программ, связанных с перебором... это полная жуть. Казалось бы, чего тут такого — перебрать все перестановки 10 элементов? Каких-то там 3628800 итераций, фи. А на CLISP этот перебор отнял секунд 15 времени (и это при том, что я несколько советов из книжки "ANSI Common LISP" для оптимизации заюзал). Жуть.
В общем, поставил я SBCL. Результаты превзошли все ожидания: большинство написанных мной функций стали выполняться быстрее раз эдак в 10-15 и теперь по скорости сравнимы с сишным кодом. Единственное, что пришлось поменять в коде, так это вызовы функций, связанных с регулярными выражениями (установил cl-ppcre). Ну оно и к лучшему, PCRE рулят =) (В CLISP встроены только POSIX-регулярки, насколько я понял.)
Monday, December 6, 2010
В продолжение обзора ЯП
(defun generate-continued-fraction (lst) (loop with sexp = (list '+ (first lst) (list '/ 1 (second lst))) for num in (rest (rest lst)) do (loop for to-change = sexp then (third to-change) until (atom (third to-change)) finally (setf (third to-change) (list '+ (third to-change) (list '/ 1 num)))) finally (return sexp)))
Ну а чё, работает же даже:
(generate-continued-fraction '(2 1 2 1 1 4 1)) (+ 2 (/ 1 (+ 1 (/ 1 (+ 2 (/ 1 (+ 1 (/ 1 (+ 1 (/ 1 (+ 4 (/ 1 1))))))))))))
Но вот о производительности такой функции лучше не думать, особенно с учётом того, что потом ещё и eval вызывается. На любом обычном языке мне б и в голову, наверное, не взбрело подобный бред писать, написал бы что-нибудь навроде
(defun continued-fraction (lst) (loop with rlst = (reverse lst) with frac = (pop rlst) for num in rlst do (setf frac (+ num (/ 1 frac))) finally (return frac)))
Так что надо порядок в голове наводить... %-)
Saturday, November 27, 2010
Почему не следует изучать OCaml.
1) отсутствие ad-hoc полиморфизма. Если вы (вдруг) не понимаете сути этого словосочетания, поясняю: представьте себе, что vkontakte.ru писался бы изначально на OCaml-е. И был бы там какой-нибудь счётчик типа int — а хер ли, любительский же проект, каким фигом он там зашкалит за два миллиарда? А вот когда он приблизится к своему пределу, окажется, что просто int на int64 не поменяешь: надо рефакторить всё к чёртовой матери, потому что конструкция a := !a + 1 уже не будет работать, надо писать a := Int64.add !a 1L — потому что функция (+) определена только для int.
2) примерно такие же пироги с массивами и строками: обращение к элементу массива — a.(i), к элементу строки — s.[i] — то бишь по гибкости OCaml даже C++ уступает, в котором хоть шаблоны есть. Для моей функции может быть неважно, массив ей дают или строку: один хер последовательность ведь! Мне что, два варианта писать, что ли?
3) из отсутствия нормального полиморфизма напрямую следует убогость всей стандартной библиотеки: скажем, String.concat для List-ов существует, а для Array-ев — чёрта с два, либо свой велосипед пиши, либо перегоняй Array в List (за O(длина_массива), разумеется). П***ец, одним словом.
Tuesday, November 23, 2010
Нумерология
(Пояснение для нематмеховцев)
Единственный некоммерческий автобус, на котором можно доехать от студгородка до метро без пересадок — 210-й. Ходит он, между прочим, от Кировского завода (тут ещё такое совпадение, что я родом из Кирова, но это не особо удивляет, ибо от коммуняг чёртова уйма одинаковых названий осталась).
Так вот, типичный путь от зданий универа на Ваське до этого самого Кировского завода таков: 1 станция по 3-й линии, потом 2 станции по 2-й линии и 3 станции по 1-й линии. Адовая симметрия. А потом в идеале оттуда на 210-м до общаги (тоже: 2-1-0), но это редко получается, чаще приходится на 200-м и 359-м ездить =(
Sunday, November 21, 2010
Theorems graph.
In my opinion, it's really fucking convenient to be able to answer the question "for what the hell do I need this theorem?!" at a glance (In fact, this question is just a rephrasing of "why the hell should I know its proof?!": you know about the lazy evaluation concept, don't you?). It's especially helpful right before exams (and especially for me 'cause I've got the damn habit to devote no more than three days to an exam preparation ^____^).
By the way, GraphViz tools were used to plot this graph. If you wanna look at the source or modify it, you can download it from here.
And yeah, for the sake of showing you how devilishly horrible automatically generated graphs might be: http://llvm.org/docs/UsingLibraries.html
Saturday, November 13, 2010
GPS & Ruby: Introduction
In this post I'm gonna acquaint you with the NMEA format used in GPS receivers. Actually, you can read about that in details here, for example. In fact, it's a proprietary one but it's too old to not to be reverse-engineered :-)
We're gonna use just one type of NMEA sentence, namely GPRMC.
Friday, November 12, 2010
just to clarify
There're several (and at least three worth to mention) reasons to proceed in that way. Firstly, because such posts are gonna appear soon (frankly speaking, I don't think anything I've written until now could be ascribed to this category). Next, it seems to me like a chance to improve my English and at the same time to reach a wider audience (yep, I'm damn selfish). And last but not least — who knows, maybe my posts will be really helpful/interesting for some people? :-)
Thursday, November 11, 2010
Digma M1
Из минусов можно отметить разве что то, что нет работы по Bluetooth, присоединяется только по USB (ну а хрен ли вы хотели от столь дешёвой шняги? :-) )
Из плюсов — внутри всобачен нехилый магнит, так что шнягу можно прикрепить к любому железному элементу одежды/сумки/whatever.
Немного о настройке: чтобы устройство работало под Linux, надо лишь настроить создаваемый системой последовательный порт (у меня это /dev/ttyUSB0). Если ничего подобного при подключении не появляется — google pl2303. Так вот, надо поставить minicom и там, поковырявшись в настройках, выставить скорость 4800 бод и сохранить настройки (уж в псевдографическом интерфейсе разобраться можно даже без мануала, я гарантирую это). В общем-то всё, должно работать. (При успешной настройке команда "sudo cat /dev/ttyUSB0" должна выводить нечто читабельное. Чтобы читабельное стало ещё и осмысленным, нужно вытащить девайс на открытое пространство и подождать несколько минут, пока ищутся спутники.)
Saturday, November 6, 2010
D.
Язык сам по себе прекрасен. Я недостатков для себя не нашёл, разве что отсутствие чего-нибудь вроде C#-ского "implicit operator". То есть для написания какой-нибудь абстрактной хрени навроде реализации арифметики поля частных над кольцом гауссовых целых чисел — самое то.
Но вот как только дело доходит до сугубо прикладных задач, начинается лютый гемор. Потому что, скажем, нет нормальных биндингов к SQLite или хотя б PostgreSQL. Дико. Что ужаснуло, так это то, что язык per se содержит все новомодные штуковины (delegates, lambda functions, UTF-8/16/32 строки, ассоциативные массивы, slices, ...), а вот библиотеки, к нему прилагающиеся, за временем явно не поспевают.
Tuesday, October 26, 2010
I'll be back...
C# меня ужасает своей негибкостью.
Во-первых, нет никакого аналога привычному scanf (или cin - кому как), и массивы приходится считывать какими-то извращенскими методами (разбивание строки методом Split и последующее конвертирование элементов массива строк в массив того_что_мне_нужно. То есть - лишняя память и угрызения совести, потому что можно же сделать лучше, чёрт возьми...)
Но это ещё цветочки.
Во-вторых, какая-то нахальная политика в плане перегрузки операторов. А именно: я не могу перегрузить operator+=, operator-= и всё в таком духе. Видите ли, компилятор позаботится, применив перегруженный operator+/operator-. Нет, ну нихера себе забота! operator+ создаёт новый объект, который никому нафиг не сдался: если операцию можно проводить in-place, то это нехилая потеря производительности. И это не пустая болтология, человек вот по этой ссылке утверждает, что падение в скорости работы доходило до 50 раз!!! Дикость. И самая жесть в том, что никто это менять не собирается, судя по ответу Microsoft в том треде. А дело было ещё в 2005 году.
Sunday, October 24, 2010
Выбор между Java и C#
Для решения всяких мелких (а порой и не очень) прикладных задач я обычно использую Python/Ruby. Однако после поступления в универ понадобилось нечто среднее между ними и С++, ибо:
1) в компьютерных классах попросту нет этих самых Python/Ruby;
2) всё-таки нужна производительность. Увы, скриптовые языки в этом плане от С++ отстают на порядок. Основной помехой в этом, наверное, является. концепция "всё что угодно есть объект". Теоретически — это изумительно: ах, вы только поглядите, у числа "2" вон сколько методов! А в Ruby on Rails и вовсе чёрт-те что можно творить, скажем, 2.hours вернёт 7200, а 7200.from_now вернёт время, которое будет через два часа. Так что вообще можно писать 2.hours.from_now. Изящно? А то! Но когда эти числа-объекты используются при перемножении матриц, весь их объектный характер нахрен никому не сдался, а лишние память и время жрутся.
А отчего же не продолжать использовать С++? Дело в том, что:
1) его стандартная библиотека содержит мало что. После использования Python кажется, что там вообще почти ничего нету. Java в этом плане великолепна.
2) непонятно, когда наконец выйдет новый стандарт, содержащий в себе кучу вкусностей — C++0x. А я тащусь от лямбда-функций, замыканий и всего такого. Кроме того, в стандарте С++ нет такой стандартнейшей (сорри за каламбур) вещи, как Dictionary (хэш-таблица). И меня убивает, когда только из-за этого к алгоритму добавляется логарифмический множитель.
Возможные варианты перехода — С#, Java, Delphi. Последний отпадает моментально, потому что... Да хотя бы потому, что мне лень эти проклятые begin-end-ы писать. Так что остаются первые два.
Так вот, результаты сравнения Java и C# (большое спасибо английской Википедии):
Java привлекает своей офигенной по размеру стандартной библиотекой. Прям как Python, идущий "с батарейками". Также здорово, что имена методов пишутся с маленькой буквы (я ж лентяй, шифт нажимать влом). Т.е. System.out.println мне нравится куда больше, чем System.Console.WriteLine.
Однако C# содержит вещи, без которых кодинг — тоска зелёная. Как можно жить без operator overloading, вы мне скажите, а?! Среди приятных вещей (в отличие от Java) также есть properties (ням-ням-ням!), лямбда-функции и замыкания, а также комплексные числа (начиная с .NET 4.0).
Так что, несмотря на всю свою нелюбовь к Microsoft и .NET, я пришёл к выводу, что пришла пора учить C#. Вот так вот.
Sunday, October 17, 2010
[c++] век живи — век учись...
//make all characters in the list uppercase list::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { *pos = toupper(*pos); }
Note that the preincrement operator (prefix ++) is used here. This is because it might have better performance than the postincrement operator. The latter involves a temporary object because it must return the old position of the iterator. For this reason, it generally is best to prefer ++pos over pos++.Так-то!
Friday, September 24, 2010
О достаточности буквы ы и <Shift>
...теперь про изображения. Конечно, можно и тупо все байты в кучу 'ы' и 'Ы' перегнать, но это же так скучно, правда?..
Так что предлагаю рассмотреть следующий язык для рисования чёрно-белых изображений. Представим себе черепашку (как в Лого Мирах, лол), которая начинает из верхнего левого угла картинки идти вниз (для определённости) с поднятым пером. Введём следующие команды:
ы - поворот против часовой стрелки на 90°
Ы - прохождение на один пиксел в текущем направлении.
Теперь смотрите. Если мы натыкаемся на "ыыыы" в исходной строке (естественно, окружённую не 'ы'), будем считать это командой "инвертировать состояние пера": действительно, поворот на 360° — совершенно бессмысленное занятие, так что лучше бы эта подпоследовательность что-нибудь значила.
Аналогично, бессмысленную команду "ыыыыыыыы" задействуем в качестве команды окончания рисунка.
Т.е.: если менее 4 'ы' подряд — всё ОК, 4 'ы' - инвертирование пера, от 4 до 7 'ы' включительно - инвертирование пера + поворот (заметим, что поскольку поворот не меняет состояние рисунка, эти два действия можно выполнять в любой последовательности, так что двусмысленность отсутствует), 8 'ы' и более - завершаем выполнение программы.
*фух, выдохнул*
Sunday, September 5, 2010
[Real World Haskell] Йоу, я осилил третью главу =)
На последнее задание (13-е) угробил несколько часов. Требовалось написать алгоритм построения выпуклой оболочки по Грэхему. Код жуткий, но работает =)))
import Data.List (sortBy, minimumBy) -- 10 -- data Direction = DirLeft | DirRight | DirStraight deriving (Eq, Show) data Point = Point { xcoord :: Double, ycoord :: Double } deriving (Eq, Show) minus (Point x1 y1) (Point x2 y2) = Point (x1-x2) (y1-y2) cross (Point x1 y1) (Point x2 y2) = x1*y2 - x2*y1 -- 11 -- dirTriple :: Point -> Point -> Point -> Direction dirTriple a b c | crossprod < 0 = DirRight | crossprod > 0 = DirLeft | otherwise = DirStraight where crossprod = (b `minus` a) `cross` (c `minus` b) -- 12 -- dirListTriple :: [Point] -> [Direction] dirListTriple (x:y:z:xs) = [dirTriple x y z] ++ dirListTriple (y:z:xs) dirListTriple _ = [] -- 13 -- comparePointsByPos (Point x1 y1) (Point x2 y2) | cmpYResult == EQ = compare x1 x2 | otherwise = cmpYResult where cmpYResult = compare y1 y2 mostBottomLeft x = minimumBy comparePointsByPos x sortByAngle p ps = p: (sortBy cmpByAngle (filter isNotMin ps)) ++ [p] where findCos x = (xcoord x - xcoord p)/(sqrt (distSqPoints p x)) distSqPoints (Point x1 y1) (Point x2 y2) = (x2-x1)**2+(y2-y1)**2 isNotMin x = x/=p cmpByAngle a b | cmpCosRes /= EQ = cmpCosRes | otherwise = compare (distSqPoints p a) (distSqPoints p b) where cmpCosRes = compare (findCos b) (findCos a) sortPoints ps = sortByAngle p ps where p = mostBottomLeft ps convexHull a = init (reverse (__convexHull (reverse (take 2 zs)) (drop 2 zs))) where zs = sortPoints a __convexHull (t1:t2:ts) (x:xs) | dirTriple t2 t1 x == DirRight = __convexHull (t2:ts) (x:xs) | otherwise = __convexHull (x:t1:t2:ts) xs __convexHull ys _ = ys -------------------------------------------------------------------------------- plist = [(Point 100 50), (Point 110 70), (Point 110 40), (Point 112 55), (Point 120 100), (Point 125 70), (Point 128 10), (Point 129 50), (Point 139 91), (Point 140 45), (Point 145 75), (Point 150 60), (Point 160 35), (Point 165 45), (Point 170 45), (Point 180 60), (Point 200 30), (Point 210 55)] main = putStr (show (convexHull plist))
Monday, August 16, 2010
CHDK — "прокачиваем" Canon-овские мыльницы.
CHDK == Canon Hacker Development Kit. Суть этой приблуды в том, чтобы обеспечить доступ ко всем возможным настройкам фотоаппарата.
Если с английским совсем плохо — зайдите на chdk.clan.su Официальная же wiki находится по адресу chdk.wikia.com
Преимущества следующие:
a. Enhanced ways of recording images - you can capture still pictures in RAW format (as well as JPEG), and for video images you can have increased recording time and length (1 hour or 2 GB), and a greatly increased range of compression options.
- b. Additional data displays on the LCD screen - histogram, battery life indicator, depth of field, and many more.
- c. Additional photographic settings that are not available on the camera by itself - longer exposure times (up to 65 seconds), faster shutter speeds (1/25,000 sec, and faster in some cases), automatic bracketing of exposure, etc.
- d. The ability for the camera to run programs ('scripts', written in a micro-version of the BASIC language) stored on the memory card - these programs allow you to set the camera to perform a sequence of operations under the control of the program. For example, a camera can be programmed to take multiple pictures for focus bracketing, or take a picture when it detects that something in the field of view moves or changes brightness.
- e. The ability to take a picture, or start a program on the memory card, by sending a signal into the USB port - you can use the USB cable to take a picture remotely.
- f. The ability to do a number of other more useful (and fun) things, such as act as a mini file browser for the memory card, let you play games on the LCD screen, etc.
Для автоматической загрузки со своей старенькой 16GB SDHC воспользовался этой инструкцией.
Русский язык во всех новых менюшках, между прочим, поддерживается, так что тем, кто не в ладах с английским, бояться нечего =)
Friday, July 23, 2010
Wednesday, July 21, 2010
[небольшой хак] WiFi в МФТИ
Однако можно получить инет и без всяких логинов и паролей. Логика следующая: поскольку соединение как-то должно держаться (причём по всем протоколам, а не только в браузере), юзера как-то нужно запоминать. Единственный возможный вариант — идентифицировать клиента по его MAC-адресу, не так ли?
Вроде бы в таком подходе нет ничего плохого, но на самом деле есть один нюанс: MAC-адреса wifi-адаптеров можно выставлять программно (например, в linux это делается примерно так: ifconfig wlan0 hw ether XX:XX:XX:XX:XX:XX).
Так вот, как выяснилось, сессия сохраняется в течение некоторого времени, даже если клиент вышел из сети. Поэтому (упрощённый) алгоритм действий таков:
1) сканим сетку nmap-ом с ключом -sP
2) повторяем п. 1) спустя несколько минут
3) смотрим разницу результатов (для этого существуют такие вещи, как diff)
4) видим, какие MAC-и вышли из сети, и живёхонько меняем MAC-адрес своего адаптера. Если тот юзер был залогинен на wlan.mipt.ru, у вас тоже будет инет.
Впрочем, честно говоря, для инета лучше использовать телефон. А описанный выше метод полезен лишь тогда, когда надо что-то слить из локалки (в которой, btw, много всякого добра валяется).
Tuesday, June 22, 2010
Need for s... tatistics.
Взять, скажем, сайт edu-43.kirov.ru.
Что доступно извне? Изображения с гистограммами, отображающими количество сдавших в каждой из школ (от 0 до 9 вкл., 10-19 и т.д.; 100-балльники занимают отдельный столбик).
Пример:
Чего хочется? Ну, например, список школ, в которых есть люди, написавшие от 80 до 100 баллов, м? Любопытно же, какие школы рулят в плане конкретного предмета.
На самом деле скрипт пишется просто, единственной загвоздкой было то, как узнать, наличествует ли столбик в конкретной позиции.
Наиболее адекватным решением выглядит такое: смотрим цвет некоторого конкретного пиксела картинки, который однозначно соответствует наличию столбца. Как нетрудно догадаться, такими пикселами являются те, которые расположены прямо над чёрной линией горизонтальной оси.
Для простоты конвертируем png в bmp, у него спецификация крайне проста, из-за чего можно выяснить то, что нужно, не используя никаких библиотек для работы с изображениями (тупо вычисляем номер нужного нам байта).
Если кому интересно, исходник выложил здесь. Там есть ещё что допиливать (например, выдача названий ОУ вместо их кодов), но мне уже лень.
Пример работы для такого предмета, как биология:
100 points:Отталкиваясь от этого, можно и немного дальше проанализировать. Скажем, 940018 — это лицей №21, там учится некая Ксюша, которая на всерос по биологии ездила (между прочим, призёр), так что ежу понятно, у кого 100 баллов...
"940018"
90 and more points:
"860009, 940030, 940064"
80 and more points:
"520001, 530010, 550011, 550013, 560001, 570010, 590008, 590009, 600003, 610011, 630009, 640007, 660003, 660004, 670001, 670007, 670008, 690004, 710002, 720014, 740006, 770001, 810006, 840007, 850006, 850017, 870001, 870004, 880007, 880010, 900001, 900003, 910006, 910007, 910008, 920003, 930004, 930007, 940012, 940023, 940036, 940037, 940040, 940052, 940056, 940067, 940069, 940076, 940210"
P.S.: что-то как-то сумбурненько получилось, ну да ладно))
Автобусы и правила Кирхгофа.
Tuesday, June 8, 2010
[на будущее] как составляются шкалы для ЕГЭ
The Theory and Practice of Item Response Theory — введение в тему.
Диссертация создателя ЕГЭ В.А. Хлебникова.
Thursday, June 3, 2010
Занятная статистика
Киров. Май, 2010 год. 30 мая 2010 года в 10-00 часов произошла авария на основном магистральном интернет-канале в направлении Нижнего Новгорода. В 16.00 часов на том же направлении был поврежден резервный интернет-канал, в связи с чем доступ к ресурсам внешнего Интернета для жителей Кировской области был временно недоступен.
К ликвидации аварийной ситуации приступили немедленно, однако восстановить резервный канал удалось только к 22-30 часам 30 мая 2010 года, с этого времени доступ к сети был частично восстановлен.
Saturday, May 29, 2010
libxml-ruby1.9.1 и Unicode
parser = XML::HTMLParser.string((IO.read 'page.html'),выводит 80, а если то же самое, только вместо первой строки —
:encoding => XML::Encoding::UTF_8)
doc = parser.parse
obj = doc.find('//tr/td/font[@color="#cc0000"]')
content = obj.first.content.force_encoding("UTF-8")
p content.index "не найден"
parser = XML::HTMLParser.file('page.html',, выводит nil?
:encoding => XML::Encoding::UTF_8)
Переезд на Ruby 1.9.1
Вообще говоря, Ruby я увлёкся недавно — около месяца тому назад. Особенно меня философия Rails привлекла, да и сам язык довольно красив.
В процессе освоения 1.8, который идёт в Дебиане по умолчанию, столкнулся с пиздецом в виде строк, которые почему-то ведут себя тупо как последовательности байтов. После Питона (в котором, надо сказать, проблемы с Юникодом тоже были немалые) с этим ужасом работать невозможно.
Поэтому поставил ruby1.9.1. После этого попытался запустить Rails. (Естественно, поставил его gem-ом, чтоб поновее был.)
Во-первых, пришлось вручную сделать ln -s /usr/bin/ruby1.9.1 /usr/bin/ruby и для rake точно так же, иначе неудобно работать.
Во-вторых, кучу библиотек за собой ruby1.9.1 почему-то не потянул. А зря: пришлось вручную потом apt-cache-м искать нужные пакеты (libopenssl-ruby1.9.1, ruby1.9.1-dev, libsqlite3-ruby1.9.1, libxml-ruby1.9.1, возможно, ещё какие-то понадобятся...)
В-третьих, старые проекты пришлось немного модифицировать. А именно, в config/environment.rb заменить версию рельсов, а также переименовать session_key в key; потом запустить rake rails:update (так надёжней, хотя возможно, что достаточно просто переименовать application.rb в application_controller.rb).
В-четвёртых, пришлось заюзать костыль: http://gist.github.com/339265
В-пятых, пришлось немножко подправить код из-за следующего:
Ruby 1.9 introduces an incompatible syntax change for conditional statements such as 'if' and 'case/when'. Previously a colon could be used as a shorthand for a 'then' statement
Немного о блоге
Изначально блог был just for fun. Однако со временем его стиль сменился в сторону публицистического (и даже матерные слова теперь заменяются всякой #&*^!*), ибо я осознал, что подобных мне психопатов на этом шарике не так уж мало, как казалось ранее.
Аудитория делится на две основные составляющие (исхожу из данных StatCounter и впиленной в blogger статистики):
а) всякие любопытные личности типа тебя (кстати, среди них можно выделить и особо упоротых, которые мой никнейм зачем-то в поисковик вбивают — всё равно всё, что там можно найти, было давно и неправда). И вообще, если ты сейчас это читаешь, то тебе явно делать нефиг. А ну брысь матан учить! (ну или ещё чем полезным займись, если весь матан уже заботал(-а))
б) пришедшие с Google/Yandex (другими поисковиками в этой стране, похоже, и не пользуются). Эти радуют больше, потому что своим существованием показывают, что всякая муть, которую я строчу, кому-то и вправду полезна.
Такие дела.