• Часто бывает необходимо присвоить переменной значение лишь в том случае, когда у нее еще нет никакого значения. Поскольку «неприсвоенная» переменная имеет значение nil
x = x || 5
или сокращенно x ||= 5
. Имейте в виду, что значение false
, а равно и nil
, будет при этом перезаписано.• В большинстве языков для обмена значений двух переменных нужна дополнительная временная переменная. В Ruby наличие механизма множественного присваивания делает ее излишней: выражение x, y = y, x
x
и y
.• Четко отличайте класс от экземпляра. Например, у переменной класса @@foobar
@foobar
заново создается в каждом объекте класса.• Аналогично метод класса ассоциирован с тем классом, в котором определен; он не принадлежит никакому конкретному объекту и не может вызываться от имени объекта. При вызове метода класса указывается имя класса, а при вызове метода экземпляра - имя объекта.
• В публикациях, посвященных Ruby, часто для обозначения метода экземпляра применяют решеточную нотацию. Например, мы пишем File.chmod
chmod
класса File
, и File#chmod
для обозначения метода экземпляра с таким же именем. Эта нотация не является частью синтаксиса Ruby. Мы старались не пользоваться ей в этой книге.• В Ruby константы не являются истинно неизменными. Их нельзя изменять в теле методов экземпляра, но из других мест это вполне возможно.
• Ключевое слово yield
yield
не означает, что нужно получить результат или вернуть значение. Скорее, речь идет о том, чтобы уступить процессор для работы.• Составные операторы присваивания +=
-=
и пр. — это не методы (собственно, это даже не операторы). Это всего лишь «синтаксическая глазурь» или сокращенная форма записи более длинной формы. Поэтому x += y
значит в точности то же самое, что x = x + y
. Если оператор +
перегружен, то оператор +=
«автоматически» учитывает новую семантику.• Из-за того, как определены составные операторы присваивания, их нельзя использовать для инициализации переменных. Если первое обращение к переменной x
x += 1
, возникнет ошибка. Это интуитивно понятно для программистов, если только они не привыкли к языку, в котором переменные автоматически инициализируются нулем или пустым значением.• Такое поведение можно в некотором смысле обойти. Можно определить операторы для объекта nil
nil
, мы получим желаемый результат. Так, метод nil.+
, приведенный ниже, позволит инициализировать объект типа string
или Fixnum
, для чего достаточно вернуть аргумент other
. Таким образом, nil + other
будет равно other
.def nil.+(other)
other
end
Мы привели этот код для иллюстрации возможностей Ruby, но стоит ли поступать так на практике, оставляем на усмотрение читателя.
• Уместно будет напомнить, что Class
Object
— это класс. Мы попытаемся прояснить этот вопрос в следующей главе, а пока просто повторяйте это как мантру.• Некоторые операторы нельзя перегружать, потому что они встроены в сам язык, а не реализованы в виде методов. К таковым относятся =
..
, ...
, and
, or
, not
, &&
, ||
, !
, !=
и !~
. Кроме того, нельзя перегружать составные операторы присваивания (+=
, -=
и т.д.). Это не методы и, пожалуй, даже не вполне операторы.• Имейте в виду, что хотя оператор присваивания перегружать нельзя, тем не менее возможно написать метод экземпляра с именем fоо=
x.foo = 5
). Можете рассматривать знак равенства как суффикс.• Напомним: «голый» оператор разрешения области видимости подразумевает наличие Object
::Foo
— то же самое, что Objеct::Foo
.• Как уже говорилось, fail
raise
.• Напомним, что определения в Ruby исполняются. Вследствие динамической природы языка можно, например, определить два метода совершенно по-разному в зависимости от значения признака, проверяемого во время выполнения.
• Напомним, что конструкция for (for x in а)
each
. Любой класс, в котором такой итератор определен, можно обходить в цикле for
.• Не забывайте, что метод, определенный на верхнем уровне, добавляется в модуль Kernel
Object
.• Методы установки (например, fоо=