Ruby

Sep 26, 2012 22:50

Ковырял я тут очень хорошую библиотеку: grit, позволяющую читать гит-репозиторий из руби напрямую.

Она хорошо написана, документирована, работает. Но, блин, внутри торжество ООП головного мозга. Нет, это, конечно, не джава головного мозга, но ООП.



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

В гите файлы упаковываются внутри в pack-и. К этим pack-ам есть индексы в которых хранится информация о том, какие SHA1 есть в pack. Есть API в виде итератора: PackStorage#each_entry.

Что это за @size, спрашиваю я себя? А это надо искать в другом месте и вовсе не в with_idx, а в init_pack, которая вызывается в конструкторе. А там как раз творится то, что я бы чрезмерным усложнением простых вещей. Городится огород из указателя, чудесного файл-аксессора FileWindow и прочих перебрасываний управления из файла в файл с выворачиванием наизнанку с помощью yield

На самом деле там написано ровно это:

{ok, I} = file:open(filename:join([Repo, "objects/pack", IndexName++".idx"]), [raw,binary,read]),
{ok, <<>>} = file:read(I, 8),
Version = case Sig of
<<8#377, "tOc">> when Ver == 2 -> 2;
_ -> 1
end,
GlobalOffset = case Version of 1 -> 0; 2 -> 8 end,
FanOutCount = 256,
IdxOffsetSize = 4,
{ok, BinOffsets} = file:pread(I, GlobalOffset, FanOutCount*IdxOffsetSize),
IndexOffset = GlobalOffset + FanOutCount*IdxOffsetSize,
Offsets = [0] ++ [Offset || <> <= BinOffsets],
EntryCount = lists:last(Offsets),
Entries = case Version of
1 ->
{ok, ShaOnes} = file:pread(I, IndexOffset, 24*EntryCount),
[{hex(SHA), Offset} || <> <= ShaOnes]
end,
file:close(I),
% ?D({add_to_index,IndexName, Indexes}),
Index = #index{name = IndexName, objects = Entries},

Читая огромные исходники ffmpeg-а и сравнивая их с ООП кодом, я пришел к выводу, что простой, линейный, дублирующийся код, с копипастами зачастую удобнее в чтении, чем весь из себя объектный и распиленный по кускам.

Ладно, у руби есть оправдание: там открытые классы и нормальная практика манкипатчить код вместо честного патча. Эта практика имеет некоторое право на жизнь, однако она всё таки заводит в тупик.

Но, блин, такой уровень абстракций в таком простом коде - это мне кажется всё таки перебор.

erlang, программирование

Previous post Next post
Up