Опубликован: 27.01.2016 | Уровень: для всех | Доступ: платный
Лекция 4:

Rails — приправленный Ruby

Строки и методы

Нашим основным инструментом для изучения Ruby будет Rails консоль, которая является утилитой командной строки для работы с Rails приложениями, мы впервые видели ее в Разделе 2.3.3. Сама консоль построена на интерактивном Ruby (irb), и таким образом, имеет доступ ко всей мощности языка Ruby. (Как мы увидим в Разделе 4.4.4, консоль также имеет доступ и к Rails окружению.) Запустите консоль в командной строке следующим образом:

$ rails console
Loading development environment
>>

По умолчанию консоль запускается в окружении разработки (development environment), которое является одним из трех отдельных окружений определенных в Rails (другие — тестирование и производство (test и production)). Это различие не будет иметь важного значения в этой главе, мы узнаем больше об окружениях в Разделе 7.1.1.

Консоль это замечательный инструмент обучения, и вы можете чувствовать себя свободно при ее использовании — не волнуйтесь, вы (вероятно) ничего не сломаете. При использовании консоли, нажмите Ctrl-C, если вы застряли, или Ctrl-D для выхода из консоли в целом. На протяжении оставшейся части этой главы, вы, возможно, найдете полезным консультироваться с Ruby API. Она упакована (возможно, даже слишком упакована) информацией, например, чтобы узнать больше о строках Ruby вы можете посмотреть в Ruby API вступление для String класса.

Комментарии

Ruby комментарии начинаются со знака фунт # (также называемого"знаком хэша" или, более поэтично, "октоторпом") и распространяются до конца строки. Ruby (и, следовательно, Rails) игнорирует комментарии, но они полезны для читателей (а зачастую и для самого автора!). В коде

 # Returns the full title on a per-page basis.
  def full_title(page_title)
    .
    .
    .
  end

первая строка является комментарием с указанием цели последующего определения функции.

Обычно, вам не нужно включать комментарии в консольные сессии, но в учебных целях, я в дальнейшем буду включать некоторые комментарии, например:

$ rails console
>> 17 + 42   # Сложение целых чисел
=> 59

Если вы, двигаясь по этому разделу, будете набирать или копипастить команды в вашу консоль, вы можете, конечно, опустить комментарии, если хотите; консоль будет игнорировать их в любом случае.

Строки

Строки это, вероятно, наиболее важная структура данных для веб-приложений, так как веб-страницы, в конечном счете, состоят из строк символов отправленных с сервера на браузер. Давайте начнем изучение строк с консолью, в этот раз запустив ее командой rails c, что является сокращением для rails console:

$ rails c
>> ""         # Пустая строка
=> ""
>> "foo"      # Не пустая строка
=> "foo"

Это string literals (буквальная (литеральная) строка) (также, забавно называемая текстовая строка), созданная с использованием двойной кавычки ". Консоль печатает результат вычисления каждой строки, который, в случае буквальной (литеральной) строки, и есть сама строка.

Мы можем также объединить строки + оператором:

>> "foo" + "bar"    # Конкатенация строк
=> "foobar"

Здесь результатом оценки выражения "foo" plus "bar" является строка "foobar".2Для того чтобы узнать больше о происхождении "foo" и "bar"—и, в частности, возможной не-связанности "foobar" с "FUBAR"—см. Jargon File entry on "foo".

Другой способ создания строк — через интерполяцию с помощью специального синтаксиса #{}:3Программисты, знакомые с Perl или PHP могут сравнить это с автоматической интерполяцией переменных со знаком доллара в выражениях вроде "foo $bar"

>> first_name = "Michael"    # Присвоение переменной
=> "Michael"
>> "#{first_name} Hartl"     # Интерполяция строки
=> "Michael Hartl"

Здесь мы присвоили значение "Michael" переменной first_name а затем интерполировали ее в строку "#{first_name} Hartl". Мы также можем присвоить имя обеим строкам:

>> first_name = "Michael"
=> "Michael"
>> last_name = "Hartl"
=> "Hartl"
>> first_name + " " + last_name    # Конкатенация с пробелом
=> "Michael Hartl"
>> "#{first_name} #{last_name}"    # Эквивалентная интерполяция
=> "Michael Hartl"

Отметим, что последние два выражения являются эквивалентными, но я предпочитаю интерполированную версию; добавление одного пробела " " кажется мне немного неуклюжим.

Вывод на экран

Для того чтобы вывести на экран (print, напечатать) строку обычно используют Ruby функцию puts (произносится "put ess", от "put string"):

>> puts "foo"     # вывести на экран строку
foo
=> nil

Метод puts работает с побочным эффектом: выражение puts "foo" выводит строку на экран, а затем возвращает буквально ничего: nil это особое обозначение Ruby для "вообще ничего". (В дальнейшем, я буду иногда опускать => nil часть для простоты.)

Использование puts автоматически добавляет символ новой строки \n к выводу; связанный print метод — нет:

# выводит на экран строку (тоже что и puts, но без символа новой строки):
>> print "foo"
foo=> nil
>> print "foo\n"  # То же что и puts "foo"
foo
=> nil

Строки в одинарных кавычках

Все примеры до сих пор использовали строки в двойных кавычках, но Ruby также поддерживает строки в одиночных кавычках. Для многих целей оба типа строк практически идентичны:

>> 'foo'          # Строка в одиночных кавычках
=> "foo"
>> 'foo' + 'bar'
=> "foobar

Хотя есть важное отличие; Ruby не будет интерполировать строки в одиночных кавычках:

>> '#{foo} bar'     # Строки в одиночных кавычках не позволяют делать интерполяцию
=> "\#{foo} bar"

Обратите внимание, как консоль возвращает значения с использованием строк в двойных кавычках, которые требуют обратной косой черты, чтобы маскировать специальные символы, такие как #.

Если строки в двойных кавычках могут делать все то же, что и одиночно закавыченные, и могут интерполировать, какой смысл в одиночных кавычках? Они часто бывают полезны, потому что они действительно буквальные, и хранят в точности такие символы, как вы вводите. Например, "обратный слэш" (бэкслэш) — символ специальный в большинстве систем, например, буквальной новой строке \n. Если вы хотите чтобы переменная содержала буквально обратный слэш, в одиночных кавычках это сделать проще:

>> '\n'       # Буквальная комбинация 'бэкслэш n'
=> "\\n"

Как и с символом # в нашем предыдущем примере, Ruby необходимо маскировать обратный слэш; посредством дополнительного бэкслэша, внутри строки в двойных кавычках, буквальный бэкслэш представлен двумя бэкслэшами. Для небольшого примера, как этот, это небольшое спасение, но если есть много элементов, которые нужно маскировать, это может реально помочь:

>> 'Newlines (\n) and tabs (\t) both use the backslash character \.'
=> "Newlines (\\n) and tabs (\\t) both use the backslash character \\."

Объекты и передача сообщений

Все в Ruby, включая строки и даже nil, является объектом. Мы увидим технический смысл этого выражения в Разделе 4.4.2, но я не думаю, что кто-нибудь когда-нибудь понял объекты, прочитав определение в книге, вы должны создать свое интуитивное понимание объектов, видя множество примеров.

Проще описать, что объекты делают, на какие сообщения реагируют. Объект, типа строки, например, может реагировать на сообщение length, которое возвращает количество символов в строке:

>> "foobar".length        # Передача сообщения "length" строке
=> 6

Как правило, сообщения, которые передаются объектам, это методы, которые являются функциями, определенными для этих объектов.4 Строки также реагируют на empty? метод:

>> "foobar".empty?
=> false
>> "".empty?
=> true

Обратите внимание на знак вопроса в конце empty метода. Это конвенция Ruby обозначающая, что возвращаемое значение — boolean (булево, логика): true (истина) или false (ложь). Булевые особенно полезны для управления потоком:

>> s = "foobar"
>> if s.empty?
>>   "The string is empty"
>> else
>>   "The string is nonempty"
>> end
=> "The string is nonempty"

Булевы также могут быть объединены с помощью && ("и"), || ("или"), и ! ("не") операторов:

>> x = "foo"
=> "foo"
>> y = ""
=> ""
>> puts "Both strings are empty" if x.empty? && y.empty?
=> nil
>> puts "One of the strings is empty" if x.empty? || y.empty?
"One of the strings is empty"
=> nil
>> puts "x is not empty" if !x.empty?
"x is not empty"
=> nil

Поскольку все в Ruby является объектом, следовательно, nil тоже является объектом, поэтому он тоже может отвечать на методы. Одним из примеров является to_s метод, который может конвертировать практически любой объект в строку:

>> nil.to_s
=> ""

Это, конечно, кажется, пустой строкой, что мы можем проверить, цепочкой сообщений, передаваемых к nil:

>> nil.empty?
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.empty?
>> nil.to_s.empty?      # Сцепление сообщений
=> true

Здесь мы видим, что nil объект сам по себе не реагирует на empty? метод, но nil.to_s реагирует.

Вот специальный метод для проверки на nil-ность, о котором вы могли догадаться:

>> "foo".nil?
=> false
>> "".nil?
=> false
>> nil.nil?
=> true

Код

puts "x is not empty" if !x.empty?

также показывает альтернативное использование ключевого слова if Ruby позволяет писать утверждение, которое вычисляется только тогда, когда оператор, следующий за if это истина. Есть дополнительное ключевое слово unless которое работает по той же схеме:

>> string = "foobar"
>> puts "The string '#{string}' is nonempty." unless string.empty?
The string 'foobar' is nonempty.
=> nil

Стоит отметить, что nil объект уникален, тем, что это единственный объект Ruby, который является ложью в булевом контексте, кроме, непосредственно, false:

>> if nil
>>   true
>> else
>>   false        # nil является false
>> end
=> false

В частности, все другие объекты Ruby являются true, даже 0:

>> if 0
>>   true        # 0 (и все остальные кроме nil и самой false) является true
>> else
>>   false
>> end
=> true
Вадим Обозин
Вадим Обозин

Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора?

Акбар Ахвердов
Акбар Ахвердов
Россия, г. Москва
Артём Зайцев
Артём Зайцев
Украина, ДНР