Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
my_array.each do |x| some_actionendFile.open(filename) { |f| some_action }Именованные параметры будут поддерживаться в последующих версиях Ruby, но на момент работы над этой книгой еще не поддерживались. В языке Python они называются ключевыми аргументами, сама идея восходит еще к языку Ada.
Методы могут принимать переменное число аргументов:
receiver.method(arg1, *more_args)В данном случае вызванный метод трактует
more_argsdef mymethod(a, b, *с) print a, b с.each do |x| print x endendmymethod(1,2,3,4,5,6,7)# a=1, b=2, c=[3,4,5,6,7]В Ruby есть возможность определять методы на уровне объекта (а не класса). Такие методы называются синглетными; они принадлежат одному-единственному объекту и не оказывают влияния ни на класс, ни на его суперклассы. Такая возможность может быть полезна, например, при разработке графических интерфейсов пользователя: чтобы определить действие кнопки, вы задаете синглетный метод для данной и только данной кнопки.
Вот пример определения синглетного метода для строкового объекта:
str = "Hello, world!"str2 = "Goodbye!"def str.spell self.split(/./).join("-")endstr.spell # "H-e-l-l-o-,- -w-o-r-l-d-!"str2.spell # Ошибка!Имейте в виду, что метод определяется для объекта, а не для переменной. Теоретически с помощью синглетных методов можно было бы создать систему объектов на базе прототипов. Это менее распространенная форма ООП без классов [5]. Основной структурный механизм в ней состоит в конструировании нового объекта путем использования существующего в качестве образца; новый объект ведет себя как старый за исключением тех особенностей, которые были переопределены. Тем самым можно строить системы на основе прототипов, а не наследования. Хотя у нас нет опыта в этой области, мы полагаем, что создание такой системы позволило бы полнее раскрыть возможности Ruby.
1.4. Динамические аспекты Ruby
Ruby — динамический язык в том смысле, что объекты и классы можно изменять во время выполнения. Ruby позволяет конструировать и интерпретировать фрагменты кода в ходе выполнения статически написанной программы. В нем есть хитроумный API отражения, с помощью которого программа может получать информацию о себе самой. Это позволяет сравнительно легко создавать отладчики, профилировщики и другие подобные инструменты, а также применять нетривиальные способы кодирования.
Наверное, это самая трудная тема для программиста, приступающего к изучению Ruby. В данном разделе мы вкратце рассмотрим некоторые следствия, вытекающие из динамической природы языка.
1.4.1. Кодирование во время выполнения
Мы уже упоминали директивы
loadrequire#includeКод можно строить и интерпретировать по частям. В качестве несколько искусственного примера рассмотрим приведенный ниже метод
calculatedef calculate(op1, operator, op2) string = op1.to_s + operator + op2.to_s # Предполагается, что operator - строка; построим длинную # строку, состоящую из оператора и операндов. eval(string) # Вычисляем и возвращаем значение.end@alpha = 25@beta = 12puts calculate(2, "+",2) # Печатается 4puts calculate(5, "*", "@alpha") # Печатается 125puts calculate("@beta", "**", 3) # Печатается 1728Вот та же идея, доведенная чуть ли не до абсурда: программа запрашивает у пользователя имя метода и одну строку кода. Затем этот метод определяется и вызывается:
puts "Имя метода: "meth_name = getsputs "Строка кода: "code = getsstring = %[def #{meth_name}n #{code}n end] # Строим строку.eval(string) # Определяем метод.eval(meth_name) # Вызываем метод.Зачастую необходимо написать программу, которая могла бы работать на разных платформах или при разных условиях, но при этом сохранить общий набор исходных текстов. Для этого в языке С применяются директивы
#ifdefif platform == Windows action1elsif platform == Linux action2else default_actionendКонечно, за такое кодирование приходится расплачиваться некоторым снижением производительности, поскольку иногда условие вычисляется много раз. Но рассмотрим следующий пример, который делает практически то же самое, однако весь платформенно-зависимый код помещен в один метод, имя которого от платформы не зависит:
if platform == Windows def my_action
