» » » » Хэл Фултон - Программирование на языке Ruby

Хэл Фултон - Программирование на языке Ruby

На нашем литературном портале можно бесплатно читать книгу Хэл Фултон - Программирование на языке Ruby, Хэл Фултон . Жанр: Программирование. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале litmir.org.
Хэл Фултон - Программирование на языке Ruby
Название: Программирование на языке Ruby
ISBN: -
Год: -
Дата добавления: 3 июль 2019
Количество просмотров: 402
Читать онлайн

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту readbookfedya@gmail.com для удаления материала

Программирование на языке Ruby читать книгу онлайн

Программирование на языке Ruby - читать бесплатно онлайн , автор Хэл Фултон
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
1 ... 88 89 90 91 92 ... 156 ВПЕРЕД
Перейти на страницу:

С каждым днем все больше приверженцев завоевывает методология экстремального программирования (Extreme Programming — XP), поощряющая, среди прочего, раннее тестирование и постоянную переработку (рефакторинг).

XP — технология, не зависящая от языка, хотя к некоторым языкам она, возможно, более приспособлена. Разумеется, на наш взгляд, в Ruby рефакторинг реализуется проще, чем во многих языках, но это субъективное мнение. Однако, наличие библиотеки Test::Unit (и других) позволяет «поженить» Ruby и XP. Эта библиотека облегчает автономное тестирование компонентов, она функциональна богата, проста в использовании и доказала свою полезность в ходе разработки эксплуатируемых в настоящее время программ на Ruby. Мы горячо поддерживаем рекомендуемое XP раннее и частое тестирование, а тем, кто желает воплотить этот совет в Ruby, предлагаем ознакомиться с Test::Unit. (ZenTest — еще один отличный пакет, включающий некоторые возможности, которые в Test::Unit отсутствуют.)

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

Конференция comp.lang.ruby

Архив приложений Ruby

rubyforge.org

ruby-doc.org

Есть и другие полезные ресурсы, особенно для тех, кто говорит по-японски. Трудно перечислять онлайновые ресурсы в печатном издании, поскольку они постоянно изменяются. Поисковая машина — ваш лучший друг.

11.3. Динамические механизмы

Скайнет осознал себя в 2:14 утра по восточному времени 29 августа 1997 года.

Терминатор 2, Судный День

Многие читатели имеют опыт работы со статическими языками, например С. Им я адресую риторический вопрос: «Можете ли вы представите себе написанную на С функцию, которая принимает строку, рассматривает ее как имя переменной и возвращает значение этой переменной?»

Нет? А как насчет того, чтобы удалить или заменить определение функции? А перехватить обращения к несуществующим функциям? Или узнать имя вызывающей функции? Или автоматически получить список определенных пользователем элементов программы (например, перечень всех написанных вами функций)?

В Ruby все это возможно. Такая гибкость во время выполнения, способность опрашивать и изменять программные элементы во время выполнения намного упрощают решение задач. Утилиту трассировки выполнения, отладчик, профилировщик — все это легко написать на Ruby и для Ruby. Хорошо известные программы irb и xmp, используя динамические возможности Ruby, творят это волшебство.

К подобным возможностям нужно привыкнуть, их легко употребить во вред. Все эти идеи появились отнюдь не вчера (они стары по крайней мере так же, как язык LISP) и считаются «проверенными и доказанными» в сообществах пользователей Scheme и Smalltalk. Даже в языке Java, который так многим обязан С и C++, есть некоторые динамические средства, поэтому мы ожидаем, что со временем их популярность будет только расти.

11.3.1. Динамическая интерпретация кода

Глобальная функция eval компилирует и исполняет строку, содержащую код на Ruby. Это очень мощный (и вместе с тем опасный) механизм, поскольку позволяет строить подлежащий исполнению код во время работы программы. Например, в следующем фрагменте считываются строки вида «имя = выражение», затем каждое выражение вычисляется, а результат сохраняется в хэше, индексированном именем переменной.

parameters = {}


ARGF.each do |line|

 name, expr = line.split(/s*=s*/, 2)

 parameters[name] = eval expr

end

Пусть на вход подаются следующие строки:

а = 1

b = 2 + 3

с = 'date'

Тогда в результате мы получим такой хэш: {"а"=>1, "b"=>5,"с"=>"Mon Apr 30 21:17:47 CDT 2001n"}. На этом примере демонстрируется также опасность вычисления с помощью eval строк, содержимое которых вы не контролируете; злонамеренный пользователь может подсунуть строку d= 'rm *' и стереть всю вашу дневную работу.

В Ruby есть еще три метода, которые интерпретируют код «на лету»: class_eval, module_eval и instance_eval. Первые два — синонимы, и все они выполняют одно и то же: интерпретируют строку или блок, но при этом изменяют значение псевдопеременной self так, что она указывает на объект, от имени которого эти методы вызваны. Наверное, чаще всего метод class_eval применяется для добавления методов в класс, на который у вас имеется только ссылка. Мы продемонстрируем это в коде метода hook_method в примере утилиты Trace в разделе 11.3.13. Другие примеры вы найдете в динамических библиотечных модулях, например delegate.rb.

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

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

Можно инкапсулировать текущую привязку в объект с помощью метода Kernel#binding. Тогда вы сможете передать привязку в виде второго параметра методу eval, установив контекст исполнения для интерпретируемого кода.

def some_method

 а = "local variable"

 return binding

end


the_binding = some_method

eval "a", the_binding # "local variable"

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

def some_method

 return binding

end


the_binding = some_method { puts "hello" }

eval "yield", the_binding # hello

11.3.2. Метод const_get

Метод const_get получает значение константы с заданным именем из модуля или класса, которому она принадлежит.

str = "PI"

Math.const_get(str) # Значение равно Math::PI.

Это способ избежать обращения к методу eval, которое иногда считается неэлегантным. Такой подход дешевле с точки зрения потребления ресурсов и безопаснее. Есть и другие аналогичные методы: instance_variable_set, instance_variable_get и define_method.

Метод const_get действительно работает быстрее, чем eval. В неформальных тестах — на 350% быстрее, хотя у вас может получиться другой результат. Но так ли это важно? Ведь в тестовой программе на 10 миллионов итераций цикла все равно ушло менее 30 секунд.

Истинная полезность метода const_get в том, что его проще читать, он более специфичен и лучше самодокументирован. Даже если бы он был всего лишь синонимом eval, все равно это стало бы большим шагом вперед.

11.3.3. Динамическое создание экземпляра класса, заданного своим именем

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

Правильный способ — воспользоваться методом const_get, который мы только что рассмотрели. Имена всех классов в Ruby — константы в «глобальном» пространстве имен, то есть члены класса Object.

classname = "Array"


klass = Object.const_get(classname)

x = klass.new(4, 1) # [1, 1, 1, 1]

А если имена вложены? Как выясняется, следующий код не работает:

class Alpha

 class Beta

  class Gamma

   FOOBAR =237

  end

 end

end


str = "Alpha::Beta::Gamma::FOOBAR"

val = Object.const_get(str) # Ошибка!

Дело в том, что метод const_get недостаточно «умен», чтобы распознать такие вложенные имена. Впрочем, в следующем примере приведена работающая идиома:

# Структура класса та же


str = "Alpha::Beta::Gamma::FOOBAR"

val = str.split("::").inject(Object) {|x,y| x.const_get(y) } # 237

Такой код встречается часто (и демонстрирует интересное применение inject).

11.3.4. Получение и установка переменных экземпляра

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

class MyClass

 attr_reader :alpha, :beta


 def initialize(a,b,g)

  @alpha, @beta, @gamma = a, b, g

 end

end

1 ... 88 89 90 91 92 ... 156 ВПЕРЕД
Перейти на страницу:
Комментариев (0)