RubyGems — подробно


    Для начала определимся с понятиями:
    RubyGems — фрэймворк для установки и запаковки Ruby библиотек и приложений.
    gem — пакет(файл) с библиотекой или приложением. Имеет стандартизированный вид и расположен в хранилище в сети.
    gem command tool — RubyGems предоставляет утилиту «gem» для работы с gem пакетами из командной строки. Она интегрирована с Ruby и позволяет получать доступ к установленным gem'ам как к библиотекам.

    В чем же предназначение RubyGems?

    До того как появилась RubyGems, для установки новой библиотеки нужно было найти, скачать её, попытаться установить, часто лишь для того, чтобы убедиться в отсутствии нужных зависимостей. Если же библиотека запакована с помощью RubyGems, достаточно попросить RubyGems сделать это за нас и получить установленную, интегрированную библиотеку со всеми нужными зависимостями. В дополнение ко всему утилита gem — платформонезависима, неважно какую ОС вы используете, везде механизм установки библиотек и приложений будет одинаков. Здорово, правда?

    Под катом будут описаны:
    1) Поиск, получение деталей, установка gem's
    2) Доступ документации по установленному gem
    3) Использование установленных gem's
    4) Работа с версиями gem's
    5) Создание собственных gem's



    1. Поиск, получение деталей, установка gem's


    Допустим в вашем текущем проекте генерируется много XML. И где то вы слышали, что есть замечательная библиотека Jim Weirich's Builder library, которая позволит вам создавать XML прямо в коде Ruby.
    Посмотрим, доступна ли она в качестве gem:
    % gem query --details --remote --name-matches build
    *** REMOTE GEMS ***
    AntBuilder (0.4.3)
      Author: JRuby-extras
      Homepage: jruby-extras.rubyforge.org
      AntBuilder: Use ant from JRuby. Only usable within JRuby
    builder (2.1.2)
      Author: Jim Weirich
      Homepage: onestepback.org
      Builders for MarkUp.
      ...

    --details — отображает детали о найденном gem
    --remote — ищет на удалённом хранилище (--locale — поиск на локальной машине)
    --name-matches build — фильтрует gem's по содержанию строки 'build' в имени
    Номер около названия каждого gem, показывает последнюю версию.
    Список всех доступных версий для определённого gem, запустим команду list с опцией --all:
    % gem list --details --remote --all builder
    *** REMOTE GEMS ***
    builder (2.1.2, 2.1.1, 2.0.0, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.0,
    1.0.0, 0.1.1, 0.1.0)
      Author: Jim Weirich
      Homepage: onestepback.org
      Builders for MarkUp.

    Для установки самой последней версии:
    % gem install builder #RubyGems сам выберет последнюю
    По умолчанию (если вы не используете RVM), для установки gem's используются общие системные директории, так что под Unix нужно добавлять sudo перед командой gem.
    Список уже установленных на вашем компьютере gem's:
    gem list
    *** LOCAL GEMS ***
    builder (2.1.2)


    2. Чтение документации по установленному gem


    Мы установили gem builder, возникает вопрос, как с ним работать?
    В большинстве случаев gem содержит документацию, она хранится в /doc директории, например:
    #Узнаем путь где хранятся наши gem's
    % gem environment gemdir
    /usr/local/lib/ruby/gems/1.9.0

    /usr/local/lib/ruby/gems/1.9.0/doc — здесь лежит документация к установленным gem's
    /usr/local/lib/ruby/gems/1.9.0/doc/builder-2.1.2/rdoc/index.html — полный путь к документации gem'а builder в моём случае

    Есть 2 способа читать документацию:
    1. Заходить в директорию с документацией гема и запускать файл index.html
    2. Более простой способ, запустить web сервер, командой % gem server
    По умолчанию он запустится на порту 8808 и будет доступен по ссылке localhost:8808
    В браузере вы увидите документацию на все установленные gem's.
    Путь к директории с gem's и порт могут быть перезаданы с помощью опций -p и -d

    3. Использование установленных gem's



    После установки gem, достаточно написать команду require<имя gem>, чтобы подключить его. Т.е. работа с гемами не отличается от работы с обычными библиотеками.

    # пример генерации XML с помощью установленной нами библиотеки
    require 'builder'
    xml = Builder::XmlMarkup.new(target: STDOUT, indent: 2)
    xml.person(type: "programmer") do
      xml.name do
        xml.first "Dave"
        xml.last "Thomas"
      end
      xml.location "Texas"
      xml.preference("ruby")
    end
    


    4. Работа с версиями gem's


    Что если последняя вышедшая версия используемого вами gem не совместима с той которую вы используете сейчас?
    К счастью, RubyGems позволяет нам одновременно хранить несколько версий gem. Указанные ниже команды установят обе версии builder.
    % gem install builder -v 2.1.2
    % gem install builder -v 1.1.0
    % gem list builder
    *** LOCAL GEMS ***
      builder (2.1.2, 1.1.0)

    #Подключение builder v.1.1.0
    gem 'builder', '= 1.1.0'
    require 'builder'
    xml = Builder::XmlMarkup.new(STDOUT, 2)
    xml.person do
      name("Dave Thomas")
      location("Texas")
    end
    

    Тут доступны ещё несколько трюков:
    gem 'builder' , '> 1' — использовать версию больше чем первую
    gem 'builder' , ''>= 2.2.0', '< 3.0'' — использовать версию больше 2.2.0 и меньше 3.0
    Полный список выражений:
    = идентичная версия
    != неидентичная версия
    > версия больше чем
    < версия меньше чем
    >= большая и равная версия
    <= меньшая или равная версия
    ~> примерно больше чем (подробнее RubyGems docs)


    5. Создание собственных gem's


    Тут всё довольно просто, опишу базовые шаги, подробности можно почитать здесь
    1. написание кода соответсвующего gem структуре
    2. создание файла спецификации (ourgem.gemspec)
    3. создание gem файла
      % gem build mygem.gemspec
    4. размещение созданного гема на сервере rubygems.org
      %gem push mygem.gemspec


    Источники:
    http://docs.rubygems.org/
    Programming Ruby 1.9 3rd Edition
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 21
    • +3
      Для начала не плохо. Но, всю соль вы не раскрыли и боюсь, новых рубистов этим не заманишь и человека не посвященного в ruby не удивишь.

      Я прочитал с удовольствием, спасибо.
      • +1
        Полагаю автор не преследовал цели привлечь этой статьей новых рубистов. Тем не менее, получилось познавательно
      • +1
        Хорошая статья, спасибо. А то всё как-то по кускам узнаешь. А теперь есть целостное представление… хотя бы о гемах :-) Напишите про RVM, гемсетах и bundle?
      • +1
        > получение деталей

        Details по-русски подробности.
      • –2
        «И где то вы слышали, что есть замечательная библиотека ...» — ага, нормальный такой подход к разработке…
        • +2
          спасибо. еще бы отдельную статью о создании своих гемов
        • +1
          1) в ruby 1.8 просто require сделать нельзя, пока не сделаете
          require 'rubygems'
          ;
          2) вовсе не обязательно, а иногда невозможно, сделать
          require 'имя гема'
          (файла может не быть, если не предусмотрено автором гема), но всегда можно сделать
          require 'любой файл из каталога библиотеки гема'
          ;
          3) обязательно надо упомянуть, что rubygems заведует и вопросами построения кода на C etc., если оный требуется для функционирования гема (native extensions).
        • +1
          Еще одно замечание для авторов гемов, — никогда нельзя полагаться на то, что каталог с бинарниками гема находится рядом с каталогом библиотеки гема. В разных операционных системах и в разных версиях/сборках rubygems местоположение может меняться.

          Если нужно знать расположение библиотечных файлов, создайте соответствующий файл (к примеру, lib/yourgem/executor.rb) в библиотеке, и используйте
          LIBPATH = File.expand_path('..', File.dirname(__FILE__)).freeze
          внутри него.

          А из бинарника просто делаете
          require 'rubygems'
          require 'yourgem/executor'
          puts LIBPATH
          .
          • 0
            Спасибо. Можно ждать от вас топик best practices по написанию гемов?
            • 0
              не вижу особого смысла. тут основные подводные камни уже описал :)
              • +6
                Хотя, в принципе, смысл есть. Напишу.
            • +1
              $ gem -v
              1.6.2
              $ gem query --details --remote --name-matched build
              ERROR: While executing gem ... (OptionParser::InvalidOption)
              invalid option: --name-matched
              $ gem query --details --remote --name-matches build

              *** REMOTE GEMS ***

              .......
              • 0
                Спасибо! теперь имею представление о гемах )

                Товарищи Ruby девелоперы, подскажите пожалуйста хорошую книжку новичку в Ruby

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

              Самое читаемое