Вот почти что и всё, что можно сказать об этом! Нет, подождите секундочку… Я же не рассказал вам обо всех этих классах, которые выполняют самые разнообразные вещи: отправляют электронную почту, сохраняют и загружают файлы на ваш компьютер, или же создают окна и кнопки (и даже 3-хмерные миры) и всё прочее! Что ж, попросту имеется настолько много классов, которые вы можете использовать, что мне никак невозможно показать вам их все; я даже не знаю, что большинство из них из себя представляют! А что я могу сказать вам о них, так это то, где можно разузнать о них поподробнее, чтобы вы смогли изучить те из них, которые вы захотите применить в ваших программах. Однако, прежде, чем вы отправитесь на самостоятельное изучение, вам ещё следует узнать о других важных особенностях Ruby, которых нет в большинстве других языков, но без которых я просто не смог бы жить: о блоках и процедурных объектах.
10. Блоки и процедурные объекты
Это определённо одна из самых крутых возможностей Ruby. В некоторых других языках тоже есть такие возможности, хотя они могут называться как-нибудь по- другому (например, замыкания), но в большинстве даже более популярных языков, к их стыду, они отсутствуют.
Так что же это за новая крутая возможность? Это способность принимать блок кода (то есть код между do и end), обёртывать его в объект (называемый процедурным объектом или proc по-английски), сохранять его в переменной или передавать его в метод, а затем исполнять код этого блока, когда бы вы ни пожелали (более одного раза, если хотите). Таким образом, блок напоминает настоящий метод за исключением того, что он не привязан ни к какому объекту (он сам является объектом), и вы можете сохранять его или передавать его как параметр подобно тому, как вы это делаете с любым другим объектом. Думаю, настало время привести пример:
toast = Proc
.new do
puts 'Ваше
здоровье! '
end
toast.call
toast.call
toast.call
Ваше здоровье!
Ваше здоровье!
Ваше здоровье!
Итак, я создал объект proc (это название, полагаю, означает сокращение от «procedure», т. е. «процедура», но гораздо более важно, что оно рифмуется с «block»), который содержит блок кода, затем я с помощью call вызвал proc–объект три раза. Как видите, это очень напоминает метод.
На самом деле, это даже более походит на метод, чем в показанном мной примере, так как блоки могут принимать параметры:
doYouLike = Proc.new do |aGoodThing|
puts 'Я *действительно* люблю '+aGoodThing+'!' end
doYouLike.call 'шоколад' doYouLike.call 'рубин'
Я *действительно* люблю шоколад!
Я *действительно* люблю рубин!
Хорошо, вот мы узнали, что из себя представляют блоки и ргос-и читается: «проки»
[
(Между прочим, вам это не кажется знакомым? Вот-вот, вы уже видели блоки раньше… когда вы изучали итераторы. Но давайте поговорим об этом ещё чуточку попозже.)
Методы, принимающие процедурные объекты
Когда мы передаём процедурный объект в метод, мы можем управлять тем, как, в каком случае или сколько раз мы вызываем ргос-объект. Например, имеется, скажем, нечто, что мы хотим сделать перед и после выполнения некоторого кода:
def doSelflmportantly someProc
puts 'Всем немедленно ЗАМЕРЕТЬ!
Мне нужно кое-что сделать…'
someProc.call
puts 'Внимание всем, я закончил.
Продолжайте выполнять свои дела.'
end
sayHello = Proc.new do
puts 'привет'
end
sayGoodbye = Proc.new do
puts 'пока'
end
doSelflmportantly sayHello
doSelflmportantly sayGoodbye
Всем немедленно ЗАМЕРЕТЬ! Мне нужно кое-что сделать… привет Внимание всем, я закончил. Продолжайте выполнять свои дела. Всем немедленно ЗАМЕРЕТЬ! Мне нужно кое-что сделать… пока
Внимание всем, я закончил. Продолжайте выполнять свои дела.