1.4.4 Сборка мусора
Управлять памятью на низком уровне трудно и чревато ошибками, особенно в таком динамичном окружении, какое создает Ruby. Наличие механизма сборки мусора — весомое преимущество. В таких языках, как C++, за выделение и освобождение памяти отвечает программист. В более поздних языках, например Java, память освобождается сборщиком мусора (когда объект покидает область видимости).
Явное управление памятью может приводить к двум видам ошибок. Если освобождается память, занятая объектом, на который еще есть ссылки, то при последующем доступе к нему объект может оказаться в противоречивом состоянии. Так называемые
Сборка мусора влечет за собой некоторое снижение производительности. Модуль GC предоставляет ограниченные средства управления, позволяющие программисту настроить его работу в соответствии с нуждами конкретной программы. Можно также определить чистильщика (finalizer) объекта, но это уже тема для «продвинутых» (см. раздел 11.3.14).
1.5. Потренируйте свою интуицию: что следует запомнить
Надо честно признаться: «все становится интуитивно ясным после того, как поймешь». Эта истина и составляет суть данного раздела, поскольку в Ruby немало особенностей, отличающих его от всего, к чему привык программист на одном из традиционных языков.
Кто-то из читателей решит, что не нужно зря тратить время на повторение известного. Если вы из их числа, можете пропустить разделы, содержание которых кажется вам очевидным. Программисты имеют неодинаковый опыт; искушенные пользователи С и Smalltalk воспримут Ruby совсем по-разному. Впрочем, мы надеемся, что внимательное прочтение последующих разделов поможет многим читателям разобраться в том, что же такое Путь Ruby.
1.5.1. Синтаксис
Синтаксический анализатор Ruby сложен и склонен прощать многие огрехи. Он пытается понять, что хотел сказать программист, а не навязывать ему жесткие правила. Но к такому поведению надо еще привыкнуть. Вот перечень того, что следует знать о синтаксисе Ruby.
• Скобки при вызове методов, как правило, можно опускать. Все следующие вызовы допустимы:
foobar
foobar()
foobar(a,b,c)
foobar a, b, с
• Коль скоро скобки необязательны, что означает такая запись: x у z
? Оказывается, вот что: «Вызвать метод y
, передав ему параметр z
, а результат передать в виде параметра методу x
.» Иными словами, x(y(z))
. Это поведение в будущем изменится. См. обсуждение поэтического режима в разделе 1.6 ниже.
• Попробуем передать методу хэш:
my_method {а=>1, b=>2}
Это приведет к синтаксической ошибке, поскольку левая фигурная скобка воспринимается как начало блока. В данном случае скобки необходимы:
my_method({а=>1, b=>2})
• Предположим теперь, что хэш — единственный (или последний) параметр метода. Ruby снисходительно разрешает опускать фигурные скобки:
my_method(а=>1, b=>2)
Кто-то увидит здесь вызов метода с именованными параметрами. Это обманчивое впечатление, хотя никто не запрещает применять подобную конструкцию и в таком смысле.
• Есть и другие случаи, когда пропуски имеют некоторое значение. Например, на первый взгляд все четыре выражения ниже означают одно и то же:
x = y + z
x = y+z
x = y+ z
x = y +z
Но фактически эквивалентны лишь первые три. В четвертом же случае анализатор считает, что вызван метод у
с параметром +z
! И выдаст сообщение об ошибке, так как метода с именем у
не существует. Мораль: пользуйтесь пробелами разумно.
• Аналогично x = y*z
— это умножение у
на z
, тогда как x = y *z
— вызов метода у
, которому в качестве параметра передается расширение массива z
.
• В именах идентификаторов знак подчеркивания _
считается строчной буквой. Следовательно, имя идентификатора может начинаться с этого знака, но такой идентификатор не будет считаться константой, даже если следующая буква прописная.
• В линейной последовательности вложенных предложений if
применяется ключевое слово elsif
, а не else if
или elif
, как в некоторых других языках.
• Ключевые слова в Ruby нельзя назвать по-настоящему зарезервированными. Если метод вызывается от имени некоторого объекта (и в других случаях, когда не возникает неоднозначности), имя метода может совпадать с ключевым словом. Но поступайте так с осторожностью, не забывая, что программу будут читать люди.
• Ключевое слово then
(в предложениях if
и case
) необязательно. Если вам кажется, что с ним программа понятнее, включайте его в код. То же относится к слову do
в циклах while
и until
.
• Вопросительный и восклицательный знаки не являются частью идентификатора, который модифицируют, — их следует рассматривать как суффиксы. Таким образом, хотя идентификаторы chop
и chop!
считаются различными, использовать восклицательный знак в любом другом месте имени не разрешается. Аналогично в Ruby есть конструкция defined?
, но defined
— ключевое слово.
• Внутри строки символ решетки #
— признак начала выражения. Значит, в некоторых случаях его следует экранировать обратной косой чертой, но лишь тогда, когда сразу за ним идет символ {
, $
или @
.
• Поскольку вопросительный знак можно добавлять в конец идентификатора, то следует аккуратно расставлять пробелы в тернарном операторе. Пусть, например, имеется переменная