Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
class << platypus # ...end• При передаче блока итератору есть тонкое различие между фигурными скобками (
{}do-endmymethod param1, foobar do ... end# Здесь do-end связано с mymethod.mymethod param1, foobar { ... }# А здесь {} связано с именем foobar, предполагается, что это метод.• Традиционно в Ruby однострочные блоки заключают в фигурные скобки, а многострочные — в скобки do-end, например:
my_array.each { |x| puts x }my_array.each do |x| print x if x % 2 == 0 puts " четно." else puts " нечетно." endendЭто необязательно и в некоторых случаях даже нежелательно.
• Помните, что строки (strings) в некотором смысле двулики: их можно рассматривать как последовательность символов или как последовательность строчек (lines). Кому-то покажется удивительным, что итератор
eacheacheach_lineeach_bytesorteach_index• Замыкание (closure) запоминает контекст, в котором было создано. Один из способов создать замыкание — использование объекта
Procdef power(exponent) proc {|base| base**exponent}endsquare = power(2)cube = power(3)a = square.call(11) # Результат равен 121.b = square.call(5) # Результат равен 25.с = cube.call(6) # Результат равен 216.d = cube.call(8) # Результат равен 512.Обратите внимание, что замыкание «знает» значение показателя степени, переданное ему в момент создания.
• Однако помните: в замыкании используется переменная, определенная во внешней области видимости (что вполне допустимо). Это свойство может оказаться полезным, но приведем пример неправильного использования:
$exponent = 0def power proc {|base| base**$exponent}end$exponent = 2square = power$exponent = 3cube = powera = square.call(11) # Неверно! Результат равен 1331.b = square.call(5) # Неверно! Результат равен 125.# Оба результата неверны, поскольку используется ТЕКУЩЕЕ# значение $exponent. Так было бы даже в том случае, когда# используется локальная переменная, покинувшая область# видимости (например, с помощью define_method).с = cube.call(6) # Результат равен 216.d = cube.call(8) # Результат равен 512.• Напоследок рассмотрим несколько искусственный пример. Внутри блока итератора
timesxclosureclosure = nil # Определим замыкание, чтобы его имя было известно.1.times do # Создаем новый контекст. x = 5 # Переменная x локальная в этом блоке, closure = Proc.new { puts "В замыкании, x = #{x}" }endx = 1# Определяем x на верхнем уровне.closure.call # Печатается: В замыкании, x = 5Обратите внимание, что переменная x, которой присвоено значение 1, — это новая переменная, определенная на верхнем уровне. Она не совпадает с одноименной переменной, определенной внутри блока. Замыкание печатает 5, так как запоминает контекст своего создания, в котором была определена переменная
x• Переменные с именами, начинающимися с одного символа
@class Myclass @x = 1 # Переменная экземпляра класса. @y = 2 # Еще одна. def mymethod @x = 3 # Переменная экземпляра. # Заметим, что в этой точке @y недоступна. endendПеременная экземпляра класса (
@yMyclassClassClassObject
