|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Глава 21. Инструменты разработки для Ruby
Среда разработки включает не только интерпретатор. У каждого хорошего разработчика под рукой всегда есть целый набор средств, облегчающих жизнь. Некоторые из них зависят от языка, другие — нет. Самый важный инструмент — редактор. Основная работа программиста — манипулирование текстом, поэтому выбор редактора (и ваше умение им пользоваться) оказывает огромное влияние на производительность труда. Немаловажно также наличие в нем поддержки конкретного языка или средств настройки. Мы дадим очень краткий обзор распространенных редакторов. Другие инструменты помогают в составлении документации, установке библиотек, отладке и т.д. Мы уже познакомились с библиотекой отладки (не являющейся автономным приложением) в главе 16, а в главе 17 рассказали о системе RDoc. Поэтому здесь мы их касаться не будем. Также в главе 17 шла речь о системе RubyGems с точки зрения разработчика, создающего пакет; теперь же мы станем на место программиста, который пользуется пакетами, созданными другими людьми. Также в этой главе мы рассмотрим программы irb(интерактивный Ruby) и ri(инструмент для чтения документации). И завершим ее кратким обсуждением интегрированных сред разработки (IDE), которые хорошо работают с Ruby. 21.1. Система RubyGemsRubyGems — это не «официальная» система управления пакетами для Ruby, но одна из тех, что пользуются обширной поддержкой со стороны сообщества. В июле 2006 года она еще не входила в стандартный дистрибутив, но может стать его частью в будущем. Мы довольно подробно рассматривали процедуру создания gem- пакета в главе 17. А в этой главе расскажем, как пользоваться пакетами, созданными другими людьми. RubyGems пытается решить несколько основных проблем, как то: простота установки, центральный репозиторий, управление версиями библиотек, управление зависимостями и т.д. Gem-пакеты предоставляют доступ к документации и позволяют легко контролировать, какие библиотеки установлены. Если система RubyGems на вашем компьютере не установлена, зайдите на страницу http://rubyforge.org/projects/rubygems и выполните простые инструкции по загрузке и установке. В дальнейшем RubyGems будет обновляться автоматически. Сам исполняемый файл называется gem. Структура команд похожа на применяемую в cvsи других аналогичных системах, то есть у каждой команды есть подкоманды, а у каждой подкоманды — специфичные для нее параметры. Ниже приведена информация о порядке запуска[18]: RubyGems - развитый менеджер пакетов для Ruby. Ниже приведена краткая справка с указанием на источники дополнительной информации. Порядок запуска: gem -h/--help gem -v/--version gem command [аргументы...] [флаги...] Примеры: gem install rake gem list —local gem build package.gemspec gem help install Более подробные справки: gem help commands показать все команды 'gem' gem help examples показать примеры использования gem help COMMAND вывести справку о команде COMMAND (например, 'gem help install') Дополнительная информация: http://rubygems.ruby forge.org Самые важные команды не вызывают затруднений. Например, чтобы установить библиотеку feedtools, нужно выполнить команду: gem install feedtools Сначала она будет искать gem-пакет локально, а если не найдет, то обратится к серверу Ruby Forge. По умолчанию устанавливается последняя версия (хотя в некоторых случаях вам задают вопрос, какой именно пакет вы хотите установить). Можно и явно указать версию с помощью флага -vили --version. Есть еще несколько флагов, управляющих установкой; подробную информацию дает команда gem help install. Иногда gem-пакет зависит от других пакетов. В таком случае вас спросят, надо ли их устанавливать. Понятно, что, отказавшись от требуемых пакетов, вы не сможете установить и тот, что хотели изначально. Как узнать имя нужного вам пакета? Если он находится на сайте RubyForge, то обычно называется так же, как проект. Например, программа rakeнаходится на странице http://rubyforge.org/projects/rake или просто http://rake.rubyforge.org. поэтому для установки нужно выполнить команду gem install rake. Если вы не располагаете даже такой информацией, попробуйте воспользоваться командой gem search. Если указать часть предполагаемого имени gem-пакета, то будут найдены все пакеты с похожими именами. По умолчанию поиск производится на локальном компьютере; чтобы искать в центральном репозитории, задайте флаг --remote. Например, команда gem search xml --remoteнашла 12 пакетов. Чтобы получить информацию об установленном пакете, введите команду gem specification— она напечатает все содержащиеся в пакете метаданные (в основном содержимое самого файла gemspec). Флаг --remote существует, но пока не реализован. Кроме того, имеется команда деинсталляции uninstall, а также команды queryи list, отчасти перекрывающие друг друга и команду search. Есть и еще много команд (дополнительную информацию вы найдете во встроенной справке или в онлайновой документации). Полезно установить gem-сервер и на своей системе — не в качестве репозитория, из которого другие смогут дистанционно устанавливать пакеты, а как централизованный механизм, позволяющий просматривать в браузере все локально установленные пакеты вместе с документацией. Для запуска gem-сервера просто наберите команду gem_server(обычно сервер работает в фоновом режиме). Указав в адресной строке браузера URL localhost:8808, вы увидите страницу «RubyGems Documentation Index», где в алфавитном порядке перечислены все установленные gem-пакеты со ссылками на документацию в формате rdocи на домашнюю страницу проекта в Web. О системе RubyGems можно еще многое сказать; к тому же она постоянно развивается. Самая актуальная информация представлена на сайте http://rubygems.rubyforge.org. 21.2. Программа RakeУтилита rake— это вариация на тему давно известной в UNIX программы make. Но вместо «странного» синтаксиса make, который все мы знаем и терпеть не можем, в rakeиспользуется код на самом Ruby. Программу написал Джим Вайрих (Jim Weirich); это первый, насколько мне известно, пример формальной реализации языка DSL (domain-specific language — язык предметной области) на Ruby. Есть два варианта написания названия: Rake и rake. Первый - это название инструмента, второй — имя самого исполняемого файла. На мой взгляд, различие несущественное. Нет сомнения, что на дизайн Rake оказала большое влияние программа make, так что терминология одна и та же. Как и раньше, мы говорим о целях, действиях, зависимостях и правилах. Применениям Rake нет числа. Вы можете пользоваться ею для сборки проектов, написанных на С, C++ или Java (или на любом другом языке). Годится она и для генерирования документации с помощью RDoc, развертывания программ, обновления проекта на сайте Ruby Forge и множества других задач. Неудивительно, что на вход Rake подается командный файл (rake-файл), который по умолчанию называется rakefileили Rakefile. Если вы хотите назвать его иначе, укажите имя с помощью флага -fили --rakefile: $ rake # Искать сначала 'rakefile', потом 'Rakefile'. $ rake -f myfile # Использовать файл с именем 'myfile'. Основная «единица работы» в Rake — задание; именуются задания посредством символов Ruby. Предполагается, что в каждом rake-файле есть задание по умолчанию :default— оно будет выполняться, если явно не указано другое имя. $ rake # Выполнить задание по умолчанию. $ rake mytask # Выполнить задание с именем 'mytask'. Внутри rake-файла мы указываем задания с помощью метода task, передавая символ и блок: task :mytask do # ... end Содержимое блока в примере выше опущено. То, что в нем находится, называется действием. В действии можно выполнять произвольный код на Ruby. Для типичных операций предусмотрены готовые методы. Так, метод sh(название которого напоминает об интерпретаторе команд в UNIX) запускает системную команду. Методы cp, mvи rmпредназначены соответственно для копирования, перемещения и удаления файлов. (Как и make, Rake беззастенчиво выдает свое происхождение от UNIX.) Есть и другие подобные команды; дополнительную информацию вы найдете в онлайновой документации на сайте http://docs.rubyrake.org. При желании можете заключать блок в фигурные скобки, но обычно в этом случае интерпретатор Ruby ожидает, что параметры будут заключены в круглые скобки. task(:mytask) { do_something } Рассмотрим более конкретный пример. Предположим, что имеется программа myprog.с, написанная на С, и еще два связанных с ней исходных файла (каждый со своим заголовочным файлом). Иными словами, у нас есть пять исходных файлов: myprog.с sub1.с sub1.h sub2.с sub2.h Мы хотим собрать из них исполняемый файл myprog. Эта процедура состоит из нескольких шагов: откомпилировать все файлы с расширением .с, а затем скомпоновать получившиеся в результате файлы с расширением .о. Начнем с метода file, который определяет зависимости файлов: file "myprog.о" => ["myprog.с"] file "sub1.о" => ["sub1.с", "sub1.h"] file "sub2.o" => ["sub2.c", "sub2.h"] file "myprog" => ["sub1.o", "sub2.o"] Отметим, что метод fileпринимает хэш, который ассоциирует имя файла с массивом имен файлов, от которых он зависит. Теперь перейдем к построению двоичных файлов. Расширим написанный выше код. Если после вызова метода fileуказать блок, то мы сможем ассоциировать с файлом набор действий, которые необходимо выполнить для создания этого файла: file "myprog.о" => ["myprog.с"] do sh "сс -с -о myprog.о myprog.с" end file "sub1.o" => ["sub1.с", "sub1.h"] do sh "сс -с -o sub1.o sub1.c" end file "sub2.o" => ["sub2.c", "sub2.h"] do sh "сс -с -o sub2.o sub2.c" end file "myprog" => ["sub1.o", "sub2.o"] do sh "cc -o myprog myprog.о sub1.o sub2.o" end Здесь имеется некоторое дублирование, но от него можно избавиться. В Rake есть специальный механизм, который называется FileList; он понимает метасимволы (шаблоны) и позволяет работать сразу с несколькими файлами. В данном случае поместим все файлы с расширением .cв список SRC. Константа типа FileListведет себя как массив: SRC = FileList["*.с"] Теперь можно определить действия в цикле, как показано ниже. И обратите внимание, что зависимости здесь не упоминаются — Rake самостоятельно учтет эту информацию, если она была задана в другом месте. SRC.each do |src| obj = src.sub(/.c$/,".о") file(obj) { sh "cc -с -o #{obj} #{src}" } end Однако проще пользоваться правилами. Это еще один механизм Rake, естественно, позаимствованный у make: rule '.о' => '.с' do |target| sh "сс -с -о #{target.name} #{target.source}" end Тут мы наблюдаем небольшое волшебство. Rake устанавливает атрибут source, подставляя расширение имени файла из хэша (в данном случае .oзаменяется на .c). Продолжим сеанс магии. Если затребовать библиотеку rake/clean, то появляются константы cleanи clobber(первоначально пустые) и задания :cleanи :clobber. По сложившейся традиции cleanудаляет временные файлы, a clobber— еще и собранный исполняемый файл. Для этих напоминающих массив констант определен метод include, принимающий маску имени файлов; это неявное использование механизма FileList. Теперь наш rake-файл принимает такой вид: require 'rake/clean' CLEAN.include("*.о") CLOBBER.include("myprog") SRC = FileList['*.с'] OBJ = SRC.ext('o') rule '.o' => '.c' do |t| sh "cc -с -o #{t.name} #{t.source}" end file "hello" => OBJ do sh "cc -o hello #{OBJ}" end file "myprog.o" => ["myprog.c"] file "sub1.o" => ["sub1.c", "sub1.h"] file "sub2.o" => ["sub2.c", "sub2.h"] task :default => ["myprog"] Обратите внимание, что мы не задавали задания «clean» и «clobber» явно. Кроме того, отметим что «clobber» неявно включает операцию «clean». И наконец, мы определили задание defaultдля удобства запуска rake-файла; теперь можно не указывать явно имя задания, осуществляющего компиляцию и сборку. У программы rakeесть несколько параметров командной строки. Иногда желательно протестировать rake-файл, не выполняя никаких (потенциально опасных) операций; для этого служит флаг -nили --dry-run. Флаг -Tвыводит список всех целей в rake-файле. Имеются также флаги, управляющие поиском библиотек, трассировкой, протоколированием и т.д. Программа Rake сложнее, чем я описал в этом разделе (особенно это касается правил). И она продолжает развиваться. Как обычно, самую свежую информацию ищите в онлайновой документации (http://docs.rubyrake.org/). 21.3. Оболочка irbУтилита irb(интерактивный Ruby) уже много лет как включена в дистрибутив Ruby. Можно считать, что это «испытательный стенд» или «площадка для игр», на которой вы опробуете новые приемы и идеи. Работать с irbпросто. После запуска вы получаете приглашение и можете вводить произвольные выражения Ruby. Выражение вычисляется, и печатается результат. Вот пример короткого сеанса: $ irb irb(main):001:0> "cell" + "о" => "cello" irb(main):002:0> 3*79 => 237 irb(main):003:0> Dir.entries(".").size => 17 irb(main):004:0> rand => 0.850757389880155 irb(main):005:0> rand => 0.679879756672551 irb(main):006:0> defined? Foo => nil irb(main):007:0> defined? Object => "constant" irb(main):008:0> quit $ Конечно, это больше, чем калькулятор. При желании можно ввести произвольный код на Ruby: [hal@localhost ch21]$ irb irb(main):001:0> require 'mathn' => true irb(main):002:0> gen = Prime.new => # При установке флага -rвыполняется require, поэтому можно включать код из внешнего файла. Предположим, что вы написали такой файл: # File: foo.rb class MyClass attr_accessor :alpha, :beta def initialize(a, b) @alpha, @beta = a, b end end obj1 = MyClass.new(23,34) obj2 = MyClass.new("abc","xyz") Тогда можно сделать следующее: $ irb -rfoo irb(main):001:0> obj = MyClass.new(88,99) => # Отметим, что хотя обращаться к сущностям, определенным в файле (например, к константе MyClass) мы можем, это не относится к локальным переменным. Локальные переменные доступны только в самом файле, require(выполненное хоть внутри, хоть вне irb) доступа к ним не дает. Новичков часто смущает информация, выводимая irb: $ irb -rfoo irb(main):001:0> puts "hello" hello => nil Позвольте, что тут делает nil? Разумеется, это значение, возвращенное методом puts. Еще один источник недоразумений — метод eval. Взгляните на следующий сеанс: $ irb irb (main) : 001:0> eval("var = 567") => 567 irb(main) :002:0> eval("var") => 567 irb(main):003:0> var => 567 Вас ничего не удивляет? Но давайте запустим следующий сценарий и посмотрим, что произойдет: р eval("var = 567") р eval("var") р var # Results: # 567 # 567 # temp.rb:3: undefined local variable or method 'var' for main:Object # (NameError) У Ruby есть такая особенность: когда вы выполняете eval, а вслед за ним еще один, они в некотором смысле разделяют «общую область видимости». Поэтому к переменной, определенной в первой строке, можно обратиться во второй (вне или внутри irb). Но различие проявляется, когда мы попытаемся обратиться к той же переменной без использования eval. В irbэто работает, а в сценарии мы получаем ошибку. Что происходит? Поведение сценария следует считать более правильным. Не забывайте, что сама программа irbнаписана на Ruby; здравый смысл подсказывает, что она, скорее всего, внутри вызывает eval. Но мы только что убедились, что результат применения evalможет отличаться от того, что мы видим на верхнем уровне, поэтому исполнение кода внутри irbне всегда идентично исполнению такого же кода в сценарии. Об этом не следует забывать, особенно если вы ставите какие-нибудь экзотические эксперименты. Имейте в виду, что irbнастраивается в широких пределах. При запуске она читает все инициализационные файлы, которые может найти, в следующем порядке: • файл ~/.irbrc; • файл .irbrc; • файл irb.rс; • файл _irbrc; • путь, указанный в переменной окружения $irbrc. Инициализационные файлы пишутся на Ruby. В них можно настраивать текст приглашения и многое другое. Подробно эти файлы обсуждаются в книге «Programming Ruby». Ниже мы сделаем лишь несколько замечаний. Если ваша версия Ruby собрана с поддержкой библиотеки GNU readline (обычно так и есть), то вы можете перемещаться по истории команд с помощью клавиш со стрелками вверх и вниз. Еще важнее, что работает механизм завершения по клавише Tab: когда вы набираете начало идентификатора, а затем нажимаете Tab, irbпытается дописать имя идентификатора за вас. Чтобы включить механизм завершения, добавьте в файл .irbrcследующий фрагмент: IRB.conf[:AUTO_INDENT] = true IRB.сonf[:USE_READLINE] = true IRB.conf[:LOAD_MODULES] ||= [] IRB.conf[:LOAD_MODULES] |= ['irb/completion'] В файле .irbrcможет содержаться произвольный код. Например, я часто пользуюсь описанным ниже методом. Для краткости он назван sm(сокращение от «show methods»), а цель — вывести (в алфавитном порядке) список всех методов, которые можно вызывать для данного объекта, за исключением тех, которые он унаследовал от своих предков: def sm(obj) list = obj.methods anc = obj.class.ancestors — [obj.class] anc.each {|a| list -= a.instance_methods } list.sort end Вот пример его использования: irb(main):001:0> str = "hello" => "hello" irb(main):002:0> sm str => ["%", "*", "+", "<<", "<=>", "[]", "[]=", "capitalize", "capitalize!", "casecmp", "center", "chomp", "chomp!", "chop", "chop!", "concat", "count", "crypt", "delete", "delete!", "downcase", "downcase!", "dump", "each", "each_byte", "each_line", "empty?", "gsub", "gsub!", "hex", "index", "insert", "intern", "length", "ljust", "lstrip", "lstrip!", "match", "next", "next!", "oct", "replace", "reverse", "reverse!", "rindex", "rjust", "rstrip", "rstrip!", "scan", "size", "slice", "slice!", "split", "squeeze", "squeeze!", "strip", "strip!", "sub", "sub!", "succ", "succ!", "sum", "swapcase", "swapcase!", "to_f", "to_i", "to_str", "to_sym", "tr", "tr!", "tr_s", "tr_s!", "unpack", "upcase", "upcase!", "upto"] irb(main):003:0> sm String => ["allocate", "new", "superclass"] irb(main):004:0> sm 123 => ["%", "*", "**", "+", "-", "/", "<<", ">>", "[]", "^", "id2name", "power!", "rdiv", "rpower", "size", "to_f", "to_sym, "|", "-"] Программа irbпозволяет запускать подсеансы внутри сеанса, хотя это используется и нечасто. Можно запустить несколько сеансов и переключаться между ними, у каждого сеанса собственный набор привязок. Может быть, вам это и не кажется полезным, но можно, например, задать объект в сочетании с подкомандой irb. Тогда контекстом подсеанса станет этот объект, псевдопеременная selfбудет ссылаться на него, он же станет областью видимости и т.д.: $ irb irb(main):001:0> t0 = Time.now => Mon Jul 31 04:51:50 CDT 2006 irb(main):002:0> irb t0 irb#1(Mon Jul 31 04:51:50 CDT 2006):001:0> strftime("%a %b %c") => "Mon Jul Mon Jul 31 04:51:50 2006" irb#1(Mon Jul 31 04:51:50 CDT 2006):002:0> to_i => 1154339510 irb#1(Mon Jul 31 04:51:50 CDT 2006):003:0> self + 1000 => Mon Jul 31 05:08:30 CDT 2006 irb#1(Mon Jul 31 04:51:50 CDT 2006):004:0> wday => 1 irb#1(Mon Jul 31 04:51:50 CDT 2006):005:0> class SyntaxError: compile error (irb#1):5: syntax error, unexpected $end from (irb#1):5 irb#1(Mon Jul 31 04:51:50 CDT 2006):006:0> self.class => Time irb#1(Mon Jul 31 04:51:50 CDT 2006):007:0> quit => #<IRB::Irb: @scanner=#<RubyLex:0xb7ee8394>, @signal_status=:IN_EVAL, @context=#<IRB::Context:0xb7ee86f0>> irb(main):003:0> quit $ Мы уже убедились в полезности библиотеки ruby-breakpoint(см. главу 16). В сочетании с ней irbстановится мощным средством отладки, поскольку вы можете установить точку прерывания и «оказаться» в сеансе irb. Конечно, это не настоящий отладчик, потому что не позволяет исполнять код в пошаговом режиме. Иногда бывает полезна библиотека xmp. Она принимает предложения на Ruby, исполняет их и помещает возвращаемое значение в комментарий. В книге «Programming Ruby» рассматривается xmp, а также библиотека rtags(которая генерирует файл TAGS для редакторов emacs или vi). У irbесть еще одна приятная особенность, о которой стоит знать. Понятно, что irbумеет анализировать написанный на Ruby код, но лексический анализатор несложно использовать и в других приложениях. Вот простой пример программы, которая открывает саму себя и анализирует собственный код, выводя отсортированный список всех идентификаторов и констант: require 'irb/ruby-lex' file = File.new(__FILE__) parse = RubyLex.new # (file) parse.set_input(file) idents = [] loop do token = parse.token break if token.nil? if token.is_a? RubyToken::TkIDENTIFIER or token.is_a? RubyToken::TkCONSTANT idents << token.name end end p idents.uniq.sort # Выводится: # ["File", "RubyLex", "RubyToken", "TkCONSTANT", "TkIDENTIFIER", "file", # "idents", "loop", "name", "new", "p", "parse", "require", "set_input", # "sort", "token", "uniq"] Насколько мне известно, этот механизм не документирован на английском языке. Но если вам необходим лексический анализатор Ruby, то можете изучить исходный текст и адаптировать его под свои нужды. 21.4. Утилита riСокращение ri, вероятно, означает «Ruby index» или нечто подобное. Это командная утилита для чтения документации, предоставляющая информацию о классах, методах, модулях и т.д. Пример: $ ri each_with_index ------------------------------------------------------------ enumObj.each_with_index {|obj, i| block } -> nil ------------------------------------------------------------ Calls block with two arguments, the item and its index, for each item in enumObj. hash = Hash.new %w(cat dog wombat).each_with_index {|item, index| hash[item] = index } hash #=> {"dog"=>1, "wombat" =>2, "cat"=>0} Отметим, что в ней есть ошибки и странности. Можете сообщать о них (а равно об опечатках и других неточностях), если найдете человека, который сознается в авторстве. Мартин Анкерл (Martin Ankerl) написал графическую утилиту fxri, которая работает устойчиво. Она получает данные от RDoc, как и ri. Кроме того, в ней есть панель, где запущена irb. 21.5. Поддержка со стороны редакторовЛюбой современный редактор должен проявлять дружелюбие по отношению к программистам. Память о двадцатом веке уходит в прошлое, и мы принимаем как должное, что редакторы изменяют свое поведение в зависимости от типа редактируемого файла. Мы ожидаем синтаксической подсветки, автоматического формирования отступов и прочего в том же духе. Программист, пишущий на Ruby, не будет разочарован имеющимся инструментарием. Многие возможности стандартно включены в редактор, другие приходится настраивать. Два прекрасных редактора — это SciTe (на базе виджета редактирования Scintilla) и TextMate (имеется только для Mac OS X). Оба хорошо поддерживают Ruby, но больше я о них ничего сказать не могу. Третий редактор — jEdit, написанный на Java редактор для программистов (www.jedit.com). Роб МакКиннон дополнил его модулем для Ruby (http://rubyjedit.org/). Но в этой книге я не могу задерживаться на его описании. Среди программистов наиболее распространены редакторы vi (или vim) и emacs. Их мы кратко рассмотрим. Исторически для пользователей vim было создано три разных пакета. К счастью, теперь они объединены в пакет vim-ruby. Это набор конфигурационных файлов, поддерживающий синтаксическую подсветку, автоматическое формирование отступов и завершение кода. Кроме того, он позволяет вызывать интерпретатор Ruby прямо из редактора. Если вы работаете с vim версии 7 (как и положено), то этот пакет, вероятно, уже установлен. (Если же по какой-то неуважительной причине вы все еще используете версию 6.x, то самое время провести обновление.) Но может оказаться, что пакет не активирован (возможно, в целях обратной совместимости). Тогда нужно его активировать, добавив в файл .vimrcследующие строки: set nocompatible syntax on filetype on filetype indent on filetype plugin on Есть также по меньшей мере две реализации сворачивания кода для Ruby. На мои взгляд, любая методика сворачивания, которая требует вставлять в код специальные комментарии или символы, не оптимальна. Хороший механизм сворачивания должен анализировать код и распознавать в нем классы, модули, методы и т.д. Такую реализацию для vim написал Маурицио Фернандес (http://eigenclass.nrg/hiki.rb?Usable+Ruby+folding+for+Vim). В принципе есть много причин не любить редактор vim; одна из самых основательных — язык vimscript. Хорошая новость — теперь есть возможность программировать поведение vim на Ruby! И плохая… она неважно документирована. Если хотите узнать подробнее, рекомендую для начала набрать команду :help ruby в vim. Дополнительная информация имеется на странице http://wiki.rubygarden.org/Ruby/page/show/VimRubyInterface. Наконец, загляните на сайт http://vim/org; может быть, там появилось что-то новенькое. Еще один популярнейший в мире редактор — emacs. Вообще-то называть его редактором не вполне правильно. Это, скорее, миниатюрная операционная система, которая заодно позволяет и редактировать тексты. Одно из главных достоинств emacs — поразительная расширяемость; пользователь программирует его поведение на диалекте языка Lisp (elisp). Язык elisp мощнее, чем vimscript, но читать написанные на нем программы не менее сложно (правда, по другой причине). Я сам не работаю с emacs, но очень уважаю тех, кто им пользуется. Не могу почти ничего сказать о поддержке Ruby в emacs; отсылаю вас на wiki-страницу RubyGarden (http://wiki.rubygarden.org/Ruby/page/show/EmacsExtensions). 21.6. Интегрированные среды разработкиМожно спорить с тем, что компания Borland со своим языком Turbo Pascal (в середине 1980-х годов) стала праотцом всех современных интегрированных сред разработки (IDE), но без сомнения Borland сделала идею популярной. Кто бы ни стоял у ее истоков, идея IDE в обозримом будущем никуда не денется. В центре IDE обычно стоит мощный редактор, знающий обо всех особенностях синтаксиса языка. Такие средства, как синтаксическая подсветка и автоматическое формирование отступов, стали стандартными. Обычно включают также отладчик и средства управления проектом. Все чаще в среду интегрируются механизмы тестирования и сопряжение с системой управления версиями. Трудно проводить осмысленное сравнение IDE. Все они похожи и все в чем-то различаются. Выбор такой же личный и субъективный, как при покупке автомобиля. Я попытался провести небольшое исследование, чтобы помочь вам принять решение: • Одна из самых важных для Ruby сред — FreeRIDE. Она «заточена» специально под Ruby и всецело контролируется разработчиками, входящими в сообщество пользователей этого языка. В число основных авторов входят Рич Килмер (Rich Kilmer), Курт Гиббс (Curt Hibbs) и Лоран Жуллиар (Laurent Julliard), но есть и много других. Как и в случае любого крупного проекта с открытыми исходными текстами, разработка ведется медленно. Получить самую свежую информацию и загрузить программу можно на сайте http://freeride.rubyforge.org. • Одно из самых последних решений — программа Komodo производства компании ActiveState. Это мощная, полнофункциональная среда, но имейте в виду, что продукт коммерческий. Полную информацию можно найти на странице http://www.activestate.com/Products/Komodo/. • Если вы поклонник Eclipse, то должны знать о существовании Ruby Development Tool (RDT). Это набор подключаемых модулей для поддержки Ruby на платформе Eclipse. Детали изложены на странице http://sourceforge.net/projects/rubyeclipse. • ArachnoRuby — еще один коммерческий продукт; автор Лотар Шольц (Lothar Scholz). Набор функций достаточно полон, но в июле 2006 года он работал еще не так устойчиво, как другие IDE. Дополнительную информацию ищите на странице http://wwwruby-ide.com/ruby/ruby_ide_and_ruby_editor.php. • Наконец, есть еще RDE, Ruby Development Environment. Работает неплохо, достаточно мощная и бесплатная. Но только на платформе Windows. В таблице 21.1 перечислены характеристики различных IDE. Таблица 21.1. Сравнение пяти IDE для Ruby
Естественно, это лишь отправная точка для ваших собственных изысканий. Для настоящего сравнения потребовалась бы сотня страниц (а к моменту завершения работы данные уже устарели бы). В таблице рассматриваются только три платформы: семейство Linux/UNIX, семейство Win32 и Mac OS X. Когда мы пишем «все», имеются в виду только эти платформы. 21.7. ЗаключениеВ этой главе мы рассмотрели ряд инструментов, облегчающих жизнь программисту на Ruby. К числу общеупотребительных относятся интерактивная оболочка для Ruby irb, инсталлятор RubyGems и утилита чтения документации ri. Мы также дали обзор модулей для поддержки Ruby, которые подключаются к редакторам. Наконец, мы вкратце упомянули некоторые IDE с поддержкой Ruby. Но самый главный инструмент — это не программы, а люди, то есть все сообщество пользователей Ruby. Это и есть тема следующей (и последней) главы. Примечания:1 Огромное спасибо (яп.) 18 Программа печатает эту информацию на английском языке. Для удобства читателей приводим русский перевод. — Прим. перев. |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|