shikhalev.org

Последние записи

ТехнологииПрограммированиеRubyБёрдвотчингПрирода

2023.11.13 • Иван Шихалев

INat::Get — ранняя альфа

Скриншот репозитория

— Я зделяль. ©

Итак, прошу любить и жаловать — INat::Get — софтина для по­лу­че­ния и обработки данных с iNaturalist. Основное изначальное пред­наз­на­че­ние — подбивать всякую статистику для про­ек­тов на том же iNaturalist’е, но варианты использования гораздо шире.

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

Зачем?

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


Читать далее »

iNaturalist

ТехнологииПрограммированиеRubyПубликации«Системный администратор»Web

2020.01.11 • Иван Шихалев

Rack — основа веб-фреймворков в Ruby

Оригинал этой статьи опубликован в журнале «Системный администратор» №5 (150) за май 2015. Прошу обратить внимание на год — какие-то моменты могут расходиться с современными версиями языка и библиотек…


Библиотека Rack — простой объектный интерфейс для написания веб-приложений.

Слово «rack» в английском языке имеет множество значений, включая такие, как «пытка» и «разрушение»… Однако, надо полагать, название рассматриваемой библиотеки произошло от другой группы смыслов: «стойка», «штатив», «каркас» и т.д. Rack обеспечивает простой и в то же время удобный интерфейс, обеспечивающий взаимодействие между веб-сервером и приложением, позволяя программисту сосредоточиться исключительно на логике последнего.

Этот интерфейс достаточно низкоуровневый и не ограничивает разработчика каким-либо заранее заданным способом организации приложения и высокоуровневыми абстракциями. Соответственно, он и не предоставляет таких абстракций — это уже дело фреймворков, которые работают поверх него: Rails, Sinatra и других.


Читать далее »

Rack

ТехнологииПрограммированиеRubyПубликации«Системный администратор»

2016.03.09 • Иван Шихалев

Средства самопознания в Ruby

Оригинал этой статьи опубликован в журнале «Системный администратор» №1-2 (146-147) за февраль 2015.


Что программа может знать о самой себе?

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

В данной статье я планирую рассмотреть те средства «самопознания», которые доступны для программ на Ruby.


Читать далее »

интроспекцияметапрограммирование

ТехнологииПрограммированиеRubyПубликации«Системный администратор»

2016.01.27 • Иван Шихалев

Мета­программи­ро­вание в Ruby: разбор примера

Оригинал этой статьи опубликован в журнале «Системный администратор» №12 (145) за декабрь 2014.


Добавление собственных абстракций в объектную модель — это просто. И интересно.

Авторы книги «Programming Ruby: The Pragmatic Programmers’ Guide» называют метапрограммированием расширение и изменение абстракций языка (тогда как собственно программирование пользуется теми, что есть). Конечно, можно поспорить о том, что считать такой абстракцией, а что нет, однако нельзя не заметить, что в современных динамических языках, таких как Ruby или, например, Python, легко делаются некоторые вещи, которые в классических языках находились именно на языковом уровне и жестко определялись компилятором. Тут можно вспомнить, для примера, декораторы, о которых я писал в сентябре прошлого года1. И сейчас мы рассмотрим нечто подобное. В процессе я буду делать обобщающие отступления, переходя от частного примера к общим принципам программирования в Ruby.

  1. Статья «Декораторы в Ruby». «Системный администратор» № 9 (130), сентябрь 2013. Стр. 68–71. 


Читать далее »

метапрограммирование

ТехнологииПрограммированиеRubyПубликации«Системный администратор»

2015.04.04 • Иван Шихалев

Ruby и многозадачность

Оригинал этой статьи опубликован в журнале «Системный администратор» №3 (136) за март 2014.


В статье рассматриваются основные средства работы с потоками (threads) и процессами в языке и стандартной библиотеке Ruby

Немного о терминологии: англоязычный термин «thread» на русский переводится в двух вариантах — как «поток» и как «нить». Второй вариант точнее и не вызывает неоднозначности с потоками данных (streams), однако первый уже прижился в качестве основного. Кроме того, есть еще производные термины и варианты вроде «многонитевость» (или «многонитность»), но они мне не встречались и, честно говоря, режут глаз. Поэтому я буду использовать «поток».

Прежде, чем перейти к описаниям имеющегося инструментария, хотелось бы заметить, что Ruby создавался не как специальный язык параллельного программирования, при этом во время его создания и становления многозадачность уже стала привычной и необходимой. Из этих двух посылок, в об­щем-то, можно вывести текущую картину: никаких специфических концепций мы в нем не увидим, только поддержку привычной для всех языков общего назначения модели с некоторыми нюансами реализации.


Читать далее »

многозадачностьмногопоточностьоптимизация

ТехнологииПрограммированиеRubyПубликации«Системный администратор»

2015.04.01 • Иван Шихалев

Блоки и контекст в Ruby

Оригинал этой статьи опубликован в журнале «Системный администратор» №1–2 (134–135) за январь–февраль 2014.


Что стоит за конкретным идентификатором в данном окружении

Давайте разберемся с программным контекстом в Ruby: какие переменные и другие объекты доступны в конкретном месте программы, и как интерпретатор их ищет? Что обозначает конкретный идентификатор, откуда он берется? Почему отсюда, а не оттуда? И чему, наконец, в этом трижды перекинутом блоке будет равен self?

Ruby очень гибок и позволяет переопределить так много, что, образно выражаясь, вы можете выстрелить себе в ногу из самой этой ноги. Картечью.


Читать далее »

замыканияконтекст

ТехнологииПрограммированиеRubyПубликации«Системный администратор»

2015.03.31 • Иван Шихалев

Распределенный Ruby

Оригинал этой статьи опубликован в журнале «Системный администратор» №12 (133) за декабрь 2013.


Технология распределенного Ruby, или dRuby (Dis­­t­­ri­­bu­­ted Ruby), позволяет вызывать методы объектов, находящихся в другом процессе и/или на другом компьютере. При этом установка соединения, передача необходимых данных и тому подобное — скрыты от программиста, и использование удаленных объектов мало чем отличается от работы с объектами, заданными внутри программы.

Это не единственная технология RPC, доступная при про­­г­­рам­­ми­­ро­­ва­­нии на Ruby, однако более универсальные средства, такие как CORBA или XML-RPC, более сложны в использовании и требуют бо́льших накладных расходов (кроме того, поддержка CORBA не входит в стандартную библиотеку Ruby, соответственно, в сопровождении требует дополнительного внимания к совместимости версий и т.д.). В общем, если не требуется взаимодействие с программами, написанными на других языках, dRuby — очень хороший выбор, а с чем его едят и как правильно готовить, мы и рассмотрим в данной статье.


Читать далее »

RPCdRubyсериализациясети

ТехнологииПрограммированиеRubyПубликации«Системный администратор»

2015.03.30 • Иван Шихалев

Декораторы в Ruby

Оригинал этой статьи опубликован в журнале «Системный администратор» №9 (130) за сентябрь 2013.


Как известно, в языке Python существует красивый механизм декораторов, расширяющих функционал объекта без изменения интерфейса. Это довольно мощное средство, попользоваться им удобно и приятно. Но вот проблема: наш язык программирования — Ruby!

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

… … …

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


Читать далее »

метапрограммирование

ТехнологииПрограммированиеRuby

2015.03.29 • Иван Шихалев

Немного о dRuby

DRbObject не является DRbUndumped

Что это значит? Это значит, что если мы передаем посредством dRuby из процесса A процессу B объект, принадлежащий процессу C, при работе с ним B будет обращаться непосредственно к C. Если сможет, конечно, ведь легко может статься, что и B и C имеют доступ к A, но не имеют друг к другу. Тогда получим исключение.

Впрочем, нет никаких проблем заставить A проксировать этот объект для B: obj.extend(DRbUndumped) на стороне A — и дело в шляпе.

Как проверить доступность DRbObject?

Встроенного метода, проверяющего, что объект DRbObject в действительности живой и готов к работе, почему-то нет. Но его легко написать:

class DRb::DRbObject

  def available?
    self.respond_to? :class
  rescue DRb::DRbConnError
    false
  end

end

Здесь мы пользуемся тем, что: а) DRb::DRbObject#respond_to? всегда обращается к удаленному объекту, а не проверяет сам себя; б) метод class определен у каждого объекта, т.е. при доступности вызов вернет true; и в) при недоступности генерируется вполне конкретное исключение.

Это все, может быть, неочевидное, но вполне нормальное поведение. А вот следующее наблюдение мне представляется багом…

К какому сервису относится объект?

Предположим, у нас один процесс поднимает несколько сервисов DRb. Ну, например, один основной на TCP, а второй — управляющий на UnixSockets (см. мой гем drctrl). А затем обращается по DRb куда-то наружу и передает туда undumped-объект… Так вот: объект этот будет привязан не к тому протоколу, по которому идет обращение, а к последнему запущенному сервису.

Чтобы это исправить, нужно вручную выставить свойство DRb::primary_server… Впрочем, в своем геме я сегодня это учел и исправил.

RPCdRubyграбли

ТехнологииПрограммированиеRuby

2015.02.07 • Иван Шихалев

Четыре простеньких гема

Вот, наваял… Ссылки рядом с названием ведут на GitHub и RubyGems соответственно.

set_version[gh][rg]

Развитие идеи, ранее начатой в геме is-build — автонумерация билдов. Теперь, если указать флаг „git: true“, изменения в файле версий сразу же закоммитятся. Это довольно существенный момент, поскольку вручную я регулярно забывал это делать, в результате изменение версии попадало в какой-нибудь левый последующий коммит.

В планах — сделать то же самое для Mercurial и SVN.

current_spec[gh][rg]

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

wflt[gh][rg]

У интерпретатора Ruby есть прекрасная опция — „-w“ — показывать предупреждения. Для разработки очень полезно выставить ее по умолчанию, дабы писать «чисто» и обращать внимание на потенциальные проблемы сразу.

Однако, предупреждения — это именно потенциальные проблемы, а не ошибки, и зачастую выдаются в случаях, когда код на самом деле правильный. Кроме того, предупреждения выдаются и на чужой код — в установленных гемах. Сообщения не по делу ужасно раздражают и сводят на нет психологическую пользу от контроля кода. Данный гем предназначен для того, чтобы их фильтровать. В принципе фильтры могут быть самые разные — для проверки используется «волшебный» оператор „===“, а в частности в репозиторий включен пример конфига, отфильтровывающий предупреждения в чужих исходниках, находящихся где-то внутри /usr.

drctrl[gh][rg]

А этот гем уже посерьезней, хотя и тоже маленький. Он предназначен для управления скриптами, предоставляющими сервисы Distributed Ruby, и работает как такой же сервис, но только локально — через unix domain sockets. Позволяет останавливать и перезапускать сервисы.

В дальшейшем, возможно, добавятся еще какие-то управляющие функции того же рода.

Краткие инструкции на плохом английском можно прочитать в README-файлах на GitHub. Более подробная документация ждет своего часа.

PS. Все четыре гема требуют версии Ruby не ниже 2.0 — пора «закопать стюардессу».

GemsdRubyадминистрированиеверсионность