Руководства по стилю Ruby
Руководство по стилю / синтаксису
Это руководство по стилю Ruby рекомендует стандартные методы, чтобы в реальном мире мы могли писать хороший код. Руководство разделено на несколько разделов.
Содержание:
- Пробелы
- Длина линии
- Комментирование
- Комментарии на уровне файлов / классов
- Функциональные комментарии
- Блок и встроенные комментарии
- Пунктуация, орфография и грамматика
- TODO комментарии
- Закомментированный код
- методы
- Условные выражения
- Синтаксис
- Именование
- Классы
- Исключения
- Коллекции
- Струны
- Регулярные выражения
- Процентные литералы
Пробелы
Отступ:
- Используйте программные вкладки с двумя пробелами.
- Отступ, когда так глубоко, как в случае.
case
when song.name =='Misty'
puts 'Not again!'
when song.duration > 120
puts 'Too long!'
when Time.now.hour > 21
puts "It's too late"
else
song.play
end
kind = case year
when 1850..1889 then 'Blues'
when 1890..1909 then 'Ragtime'
when 1910..1929 then 'New Orleans Jazz'
when 1930..1939 then 'Swing'
when 1940..1950 then 'Bebop'
else 'Jazz'
end
- Выровняйте параметры функции по одной строке или по одному на
# good
def self.create_translation(phrase_id,
phrase_key,
target_locale,
value,
user_id,
do_xss_check,
allow_verification)
...
end
# bad
def self.create_translation(phrase_id, phrase_key, target_locale,
value, user_id, do_xss_check, allow_verification)
...
end
- Отступ последовательных строк в многострочных логических выражениях.
# good
def is_eligible?(user)
Trebuchet.current.launch?(ProgramEligibilityHelper::PROGRAM_TREBUCHET_FLAG) &&
is_in_program?(user) &&
program_not_expired
end
# bad
def is_eligible?(user)
Trebuchet.current.launch?(ProgramEligibilityHelper::PROGRAM_TREBUCHET_FLAG) &&
is_in_program?(user) &&
program_not_expired
end
В соответствии:
- Никогда не покидайте конечные пробелы.
- Используйте пробелы вокруг операторов; после запятых, двоеточий и точек с запятой; и около {и до}.
sum = 1 + 2
a, b = 1, 2
1 > 2 ? true : false; puts 'Hi'
[1, 2, 3].each { |e| puts e }
- Без пробелов после (, [или до],)
some(arg).other
[1, 2, 3].length
Newlines:
- Добавьте новую строку после, если условия охватывают несколько строк, чтобы помочь дифференцировать условия и тело.
if @reservation_alteration.checkin == @reservation.start_date &&
@reservation_alteration.checkout == (@reservation.start_date + @reservation.nights)
redirect_to_alteration @reservation_alteration
end
Длина линии
Держите каждую строку кода на удобочитаемой длине. Если у вас нет причин, оставляйте строки длиной не более 100 символов. Хранение кода, визуально сгруппированного (как ограничение в 100 символов строки) облегчает понимание. Например, вам не нужно прокручивать вперед и назад одну строку, чтобы увидеть, что происходит, - вы можете просмотреть все это вместе.
Вот примеры из нашей кодовой базы, показывающие несколько методов разбиения сложных операторов на несколько строк, каждая из которых <100 символов. Обратите внимание на методы, такие как:
- либеральное использование разрывов строк внутри незакрытого ({[
- методы цепочки, заканчивая незаконченные цепочки с.
- составление длинных строк путем помещения строк рядом друг с другом, разделенных обратной косой чертой, затем новой строкой.
- разрыв длинных логических операторов с переносами строк после таких операторов, как && и ||
scope = Translation::Phrase.includes(:phrase_translations).
joins(:phrase_screenshots).
where(:phrase_screenshots => {
:controller => controller_name,
:action => JAROMIR_JAGR_SALUTE,
})</pre>
<pre name="code" class="ruby">
translation = FactoryGirl.create(
:phrase_translation,
:locale => :is,
:phrase => phrase,
:key => 'phone_number_not_revealed_time_zone',
:value => 'Símanúmerið þitt verður ekki birt. Það er aðeins hægt að hringja á '\
'milli 9:00 og 21:00 %{time_zone}.'
)
if @reservation_alteration.checkin == @reservation.start_date &&
@reservation_alteration.checkout == (@reservation.start_date + @reservation.nights)
redirect_to_alteration @reservation_alteration
end
<% if @presenter.guest_visa_russia? %>
<%= icon_tile_for(I18n.t("email.reservation_confirmed_guest.visa.details_header",
:default => "Visa for foreign Travelers"),
:beveled_big_icon => "stamp" do %>
<%= I18n.t("email.reservation_confirmed_guest.visa.russia.details_copy",
:default => "Foreign guests travelling to Russia may need to obtain a visa...") %>
<% end %>
<% end %>
Эти фрагменты кода гораздо более читабельны, чем альтернативные:
scope = Translation::Phrase.includes(:phrase_translations).joins(:phrase_screenshots).where(:phrase_screenshots => { :controller => controller_name, :action => JAROMIR_JAGR_SALUTE })
translation = FactoryGirl.create(:phrase_translation, :locale => :is, :phrase => phrase, :key => 'phone_number_not_revealed_time_zone', :value => 'Símanúmerið þitt verður ekki birt. Það er aðeins hægt að hringja á milli 9:00 og 21:00 %{time_zone}.')
if @reservation_alteration.checkin == @reservation.start_date && @reservation_alteration.checkout == (@reservation.start_date + @reservation.nights)
redirect_to_alteration @reservation_alteration
end
<% if @presenter.guest_visa_russia? %>
<%= icon_tile_for(I18n.t("email.reservation_confirmed_guest.visa.details_header", :default => "Visa for foreign Travelers"), :beveled_big_icon => "stamp" do %>
<%= I18n.t("email.reservation_confirmed_guest.visa.russia.details_copy", :default => "Foreign guests travelling to Russia may need to obtain a visa prior to...") %>
<% end %>
<% end %>
Комментирование
Несмотря на то, что это неприятно для w0rite, комментарии абсолютно необходимы для обеспечения читабельности нашего кода. Следующие правила описывают, что вы должны прокомментировать и где. Но помните: хотя комментарии очень важны, лучшим кодом является самодокументирование. Давать разумные имена типам и переменным гораздо лучше, чем использовать непонятные имена, которые вы должны затем объяснить в комментариях.
При написании комментариев пишите для своей аудитории: следующий участник, который должен будет понять ваш код. Будьте щедрыми - следующим может быть вы!
Части этого раздела в значительной степени заимствованы из руководств по стилям Google C ++ и Python.
Комментарии уровня файла / класса:
Каждое определение класса должно иметь сопровождающий комментарий, который описывает, для чего он предназначен и как его следует использовать.
Файл, который содержит ноль классов или более одного класса, должен иметь комментарий вверху, описывающий его содержимое.
# Automatic conversion of one locale to another where it is possible, like
# American to British English.
module Translation
# Class for converting between text between similar locales.
# Right now the only conversion between American English -> British, Canadian,
# Australian, New Zealand variations are provided.
class PrimAndProper
def initialize
@converters = { :en => { :"en-AU" => AmericanToAustralian.new,
:"en-CA" => AmericanToCanadian.new,
:"en-GB" => AmericanToBritish.new,
:"en-NZ" => AmericanToKiwi.new,
} }
end
...
# Applies transforms to American English that is common to
# variants of all other English colonies.
class AmericanToColonial
...
end
# Converts American to British English.
# In addition to general Colonial English variations, changes "apartment"
# to "flat".
class AmericanToBritish < AmericanToColonial
...
end
Все файлы, включая файлы данных и конфигурации, должны иметь комментарии на уровне файлов. От
translation/config/colonial_spelling_variants.yml:
List of American-to-British spelling variants.
#
# This list is made with
# lib/tasks/list_american_to_british_spelling_variants.rake.
#
# It contains words with general spelling variation patterns:
# [trave]led/lled, [real]ize/ise, [flav]or/our, [cent]er/re, plus
# and these extras:
# learned/learnt, practices/practises, airplane/aeroplane, ...
sectarianizes: sectarianises
neutralization: neutralisation
...
Функциональные комментарии:
Каждое объявление функции должно иметь комментарии, непосредственно предшествующие ему, которые описывают, что делает функция и как ее использовать. Эти комментарии должны быть описательными («Открывает файл»), а не обязательными («Открыть файл»); комментарий описывает функцию, но не говорит функции, что делать. В целом, эти комментарии не описывают, как функция выполняет свою задачу. Вместо этого, это следует оставить комментариям, вкрапленным в код функции.
Каждая функция должна указывать, какие есть входы и выходы, если она не соответствует всем следующим критериям:
- внешне не виден
- очень короткий
- очевидный
Вы можете использовать любой формат по вашему желанию. В Ruby две популярные схемы документации функций - это TomDoc и YARD. Вы также можете просто написать кратко:
# Returns the fallback locales for the_locale.
# If opts[:exclude_default] is set, the default locale, which is otherwise
# always the last one in the returned list, will be excluded.
#
# For example:
# fallbacks_for(:"pt-BR")
# => [:"pt-BR", :pt, :en]
# fallbacks_for(:"pt-BR", :exclude_default => true)
# => [:"pt-BR", :pt]
def fallbacks_for(the_locale, opts = {})
...
end
Блок и встроенные комментарии:
Последнее место для комментариев - в хитрых частях кода. Если вам нужно объяснить это при следующем обзоре кода, вы должны прокомментировать это сейчас. Сложные операции получают несколько строк комментариев перед их началом. Неочевидные получают комментарии в конце строки.
def fallbacks_for(the_locale, opts = {})
# dup() to produce an array that we can mutate.
ret = @fallbacks[the_locale].dup
# We make two assumptions here:
# 1) There is only one default locale (that is, it has no less-specific
# children).
# 1) The default locale is just a language. (Like :en, and not :"en-US".)
if opts[:exclude_default] &&
ret.last == self.default_locale &&
ret.last != language_from_locale(the_locale)
ret.pop
end
ret
end
С другой стороны, никогда не описывайте код. Предположим, что человек, читающий код, знает язык (хотя и не то, что вы пытаетесь сделать) лучше, чем вы.
Пунктуация, орфография и грамматика:
Обратите внимание на пунктуацию, орфографию и грамматику; читать хорошо написанные комментарии легче, чем плохо написанные.
Комментарии должны быть такими же удобочитаемыми, как и повествовательный текст, с правильной прописной буквой и пунктуацией. Во многих случаях полные предложения более читабельны, чем фрагменты предложений. Более короткие комментарии, такие как комментарии в конце строки кода, иногда могут быть менее формальными, но вы должны соответствовать своему стилю.
Хотя может быть неприятно, когда рецензент кода указывает на то, что вы используете запятую, когда вы должны использовать точку с запятой, очень важно, чтобы исходный код поддерживал высокий уровень ясности и читабельности. Правильная пунктуация, орфография и грамматика помогают с этой целью.
TODO комментарии:
Используйте комментарии TODO для временного кода, краткосрочного решения или достаточно хорошего, но не идеального.
TODO должен включать строку TODO во всех заглавных буквах, за которой следует полное имя человека, который может наилучшим образом предоставить контекст о проблеме, на которую ссылается TODO, в скобках. Двоеточие необязательно. Требуется комментарий, объясняющий, что нужно сделать. Основная цель - создать согласованный формат TODO, в котором можно искать человека, который может предоставить более подробную информацию по запросу. TODO - это не обязательство, что лицо, на которое ссылается, решит проблему. Таким образом, когда вы создаете TODO, вам почти всегда дают имя.
# bad
# TODO(RS): Use proper namespacing for this constant.
# bad
# TODO(drumm3rz4lyfe): Use proper namespacing for this constant.
# good
# TODO(Ringo Starr): Use proper namespacing for this constant.
Закомментированный код:
Никогда не оставляйте закомментированный код в нашей кодовой базе.
методы
Определения методов:
- Используйте def с круглыми скобками, когда есть параметры. Опустите скобки, когда метод не принимает никаких параметров.
def some_method
# body omitted
end
def some_method_with_parameters(arg1, arg2)
# body omitted
end
- Не используйте аргументы по умолчанию. Вместо этого используйте хэш опций.
# bad
def obliterate(things, gently = true, except = [], at = Time.now)
...
end
# good
def obliterate(things, options = {})
default_options = {
:gently => true, # obliterate with soft-delete
:except => [], # skip obliterating these things
:at => Time.now, # don't obliterate them until later
}
options.reverse_merge!(default_options)
...
end
Вызовы метода:
Используйте скобки для вызова метода:
- Если метод возвращает значение.
# bad
@current_user = User.find_by_id 1964192
# good
@current_user = User.find_by_id(1964192)
- Если первый аргумент метода использует круглые скобки.
# bad
put! (x + y) % len, value
# good
put!((x + y) % len, value)
- Никогда не ставьте пробел между именем метода и открывающей скобкой.
# bad
f (3 + 2) + 1
# good
f(3 + 2) + 1
- Опустите скобки для вызова метода, если метод не принимает аргументов.
# bad
nil?()
# good
nil?
- Если метод не возвращает значение (или мы не заботимся о возвращении), скобки не обязательны. (Особенно, если аргументы переполняются несколькими строками, круглые скобки могут добавить удобочитаемость.)
# okay
render(:partial => 'foo')
# okay
render :partial => 'foo'
В любом случае:
- Если метод принимает хэш опций в качестве последнего аргумента, не используйте {} во время вызова.
# bad
get '/v1/reservations', { :id => 54875 }
# good
get '/v1/reservations', :id => 54875
Условные выражения
Условные ключевые слова:
- Никогда не используйте тогда для многострочного, если / если.
# bad
if some_condition then
...
end
# good
if some_condition
...
end
- Запрещены ключевые слова и, или, а не ключевые слова. Это просто не стоит того. Всегда используйте &&, || и! вместо.
- Модификатор if /, если использование в порядке, когда тело простое, условие простое, и все это помещается в одну строку. В противном случае, избегайте модификаторов, если / если
# bad - this doesn't fit on one line
add_trebuchet_experiments_on_page(request_opts[:trebuchet_experiments_on_page]) if request_opts[:trebuchet_experiments_on_page] && !request_opts[:trebuchet_experiments_on_page].empty?
# okay
if request_opts[:trebuchet_experiments_on_page] &&
!request_opts[:trebuchet_experiments_on_page].empty?
add_trebuchet_experiments_on_page(request_opts[:trebuchet_experiments_on_page])
end
# bad - this is complex and deserves multiple lines and a comment
parts[i] = part.to_i(INTEGER_BASE) if !part.nil? && [0, 2, 3].include?(i)
# okay
return if self.reconciled?
- Никогда не используйте, если не с другими. Перепишите их сначала в положительном случае.
# bad
unless success?
puts 'failure'
else
puts 'success'
end
# good
if success?
puts 'success'
else
puts 'failure'
end
- Избегайте, если не с несколькими условиями.
# bad
unless foo? && bar?
...
end
# okay
if !(foo? && bar?)
...
end
- Не используйте круглые скобки вокруг условия if / instance / while, если только условие не содержит присваивания (см. Использование возвращаемого значения = ниже).
# bad
if (x > 10)
...
end
# good
if x > 10
...
end
# ok
if (x = self.next_value)
...
end
Тернарный оператор:
- Избегайте троичного оператора (? :) за исключением случаев, когда все выражения чрезвычайно тривиальны. Тем не менее, используйте тернарный оператор (? :) над конструкциями if / then / else / end для однострочных условных выражений.
# bad
result = if some_condition then something else something_else end
# good
result = some_condition ? something : something_else
- Используйте одно выражение на ветку в троичном операторе. Это также означает, что троичные операторы не должны быть вложенными. Предпочитаю конструкции if / else в этих случаях.
# bad
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
# good
if some_condition
nested_condition ? nested_something : nested_something_else
else
something_else
end
- Избегать многострочного?: (Троичный оператор), используйте вместо него if / then / else / end.
Синтаксис:
- Никогда не используйте для, если вы не знаете точно, почему. Большую часть времени следует использовать итераторы. for реализован в терминах каждого (так что вы добавляете уровень косвенности), но с изюминкой - for не вводит новую область видимости (в отличие от каждой), и переменные, определенные в его блоке, будут видны за ее пределами.
arr = [1, 2, 3]
# bad
for elem in arr do
puts elem
end
# good
arr.each { |elem| puts elem }
- Предпочитать {...} над do ... end для однострочных блоков. Избегайте использования {...} для многострочных блоков (многострочные цепочки всегда безобразны). Всегда используйте do ... end для «потока управления» и «определения метода» (например, в Rakefiles и некоторых DSL). Избегайте конца ... при цепочке.
names = ["Bozhidar", "Steve", "Sarah"]
# good
names.each { |name| puts name }
# bad
names.each do |name| puts name end
# good
names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
# bad
names.select do |name|
name.start_with?("S")
end.map { |name| name.upcase }
Некоторые утверждают, что при использовании {...} многострочная цепочка будет выглядеть нормально, но они должны спросить себя, действительно ли этот код читабелен и можно ли извлечь содержимое блока в изящные методы.
- Избегайте возвращения туда, где не требуется.
# bad
def some_method(some_arr)
return some_arr.size
end
# good
def some_method(some_arr)
some_arr.size
end
- Использовать возвращаемое значение = (назначение) можно, но окружите назначение круглыми скобками.
# good - shows intended use of assignment
if (v = array.grep(/foo/))
...
end
# bad
if v = array.grep(/foo/)
...
end
# also good - shows intended use of assignment and has correct precedence
if (v = self.next_value) =="hello"
...
end
- Используйте || = свободно для инициализации переменных.
# set name to Bozhidar, only if it's nil or false
name ||='Bozhidar'
- Не используйте || = для инициализации логических переменных. (Подумайте, что произойдет, если текущее значение окажется ложным.)
# bad - would set enabled to true even if it was false
enabled ||= true
# good
enabled = true if enabled.nil?
- Избегайте использования специальных переменных в стиле Perl (например, $ 0-9, $ и т. Д.). Они довольно загадочны, и их использование во всех сценариях, кроме однострочных, не рекомендуется. Предпочитайте длинные версии форм, такие как $ PROGRAM_NAME.
- Используйте _ для неиспользуемых аргументов блока.
# bad
result = hash.map { |k, v| v + 1 }
# good
result = hash.map { |_, v| v + 1 }
- Если блок метода принимает только один аргумент, а тело состоит только из чтения атрибута или вызова одного метода без аргументов, используйте сокращение &:.
# bad
bluths.map { |bluth| bluth.occupation }
bluths.select { |bluth| bluth.blue_self? }
# good
bluths.map(&:occupation)
bluths.select(&:blue_self?)
Именование
- Используйте snake_case для методов и переменных.
- Используйте CamelCase для классов и модулей. (Сохраняйте аббревиатуры, такие как HTTP, RFC, XML в верхнем регистре.)
- Используйте SCREAMING_SNAKE_CASE для других констант.
- Имена методов предикатов (методы, которые возвращают логическое значение) должны заканчиваться знаком вопроса. (т.е. массив # пуст?).
- Имена потенциально «опасных» методов (то есть методов, которые изменяют self или аргументы, выход !, и т. Д.) Должны заканчиваться восклицательным знаком. Методы взрыва должны существовать, только если существует метод взрыва. (Подробнее об этом.)
- Имя одноразовых переменных _.
payment, _ = Payment.complete_paypal_payment!(params[:token],
native_currency,
created_at)
Классы
- Избегайте использования переменных класса (@@) из-за их «неприятного» поведения при наследовании.
class Parent
@@class_var ='parent'
def self.print_class_var
puts @@class_var
end
end
class Child < Parent
@@class_var ='child'
end
Parent.print_class_var # => will print "child"
Как вы можете видеть, все классы в иерархии классов на самом деле имеют одну переменную класса. Переменные экземпляра класса обычно предпочтительнее, чем переменные класса.
- Используйте def self.method для определения одноэлементных методов. Это делает методы более устойчивыми к изменениям рефакторинга.
class TestClass
# bad
def TestClass.some_method
...
end
# good
def self.some_other_method
...
end
- Избегайте class << self, за исключением случаев, когда это необходимо, например, одиночные методы доступа и псевдонимы.
class TestClass
# bad
class << self
def first_method
...
end
def second_method_etc
...
end
end
# good
class << self
attr_accessor :per_page
alias_method :nwo, :find_by_name_with_owner
end
def self.first_method
...
end
def self.second_method_etc
...
end
end
- Сделайте отступ публичных, защищенных и приватных методов так же, как и определения методов, к которым они применяются. Оставьте одну пустую строку над ними.
class SomeClass
def public_method
# ...
end
private
def private_method
# ...
end
end
Исключения
- Не используйте исключения для потока управления.
# bad
begin
n / d
rescue ZeroDivisionError
puts "Cannot divide by 0!"
end
# good
if d.zero?
puts "Cannot divide by 0!"
else
n / d
end
- Избегайте спасения класса Исключения.
# bad
begin
# an exception occurs here
rescue Exception
# exception handling
end
# good
begin
# an exception occurs here
rescue StandardError
# exception handling
end
# acceptable
begin
# an exception occurs here
rescue
# exception handling
end
Коллекции
- Используйте Set вместо Array при работе с уникальными элементами. Set реализует коллекцию неупорядоченных значений без дубликатов. Это гибрид интуитивно понятных средств взаимодействия Array и быстрого поиска Hash.
- Используйте символы вместо строк в качестве ключей хеша.
# bad
hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
# good
hash = { :one => 1, :two => 2, :three => 3 }
- Используйте многострочные хэши, когда это делает код более читабельным, и используйте запятые, чтобы гарантировать, что изменения параметров не вызовут посторонние строки различий, когда логика не изменилась иным образом.
hash = {
:protocol => 'https',
:only_path => false,
:controller => :users,
:action => :set_password,
:redirect => @redirect_url,
:secret => @secret,
}
Струны
- Предпочитайте интерполяцию строк вместо конкатенации строк:
# bad
email_with_name = user.name + ' <' + user.email + '<'
# good
email_with_name ="#{user.name} <#{user.email}>"
Кроме того, имейте в виду интерполяцию в стиле Ruby 1.9. Допустим, вы составляете ключи кеша следующим образом:
CACHE_KEY ='_store'
cache.write(@user.id + CACHE_KEY)
Предпочитайте интерполяцию строк вместо конкатенации строк:
CACHE_KEY ='%d_store'
cache.write(CACHE_KEY % @user.id)
- Избегайте использования String # +, когда вам нужно создать большие куски данных. Вместо этого используйте String # <<. Конкатенация изменяет экземпляр строки на месте и всегда быстрее, чем String # +, который создает кучу новых строковых объектов.
# good and also fast
html = ''
html << '<h1>Page title</h1>'
paragraphs.each do |paragraph|
html << "<p>#{paragraph}</p>"
end
Регулярные выражения
- Избегайте использования $ 1-9, так как может быть трудно отследить, что они содержат. Вместо этого можно использовать именованные группы.
# bad
/(regexp)/ =~ string
...
process $1
# good
/(?<meaningful_var>regexp)/ =~ string
...
process meaningful_var
- Будьте осторожны с ^ и $, так как они совпадают с началом / концом строки, а не с окончаниями строки. Если вы хотите сопоставить всю строку, используйте: / A и / z.
string ="some injection\nusername"
string[/^username$/] # matches
string[/\Ausername\z/] # don't match
- Используйте модификатор x для сложных регулярных выражений. Это делает их более читабельными, и вы можете добавить некоторые полезные комментарии. Просто будьте осторожны, так как пробелы игнорируются.
regexp = %r{
start # some text
\s # white space char
(group) # first group
(?:alt1|alt2) # some alternation
end
}x
Процентные литералы
- Используйте% w свободно.
STATES = %w(draft open closed)
- Используйте% () для однострочных строк, которые требуют как интерполяции, так и двойных кавычек. Для многострочных строк предпочитайте heredocs.
# should be '<div class="text">Some text</div>'
# bad - no double-quotes
%(This is #{quality} style)
# should be "This is #{quality} style"
# bad - multiple lines
%(<div>\n<span class="big">#{exclamation}</span>\n</div>)
# should be a heredoc.
# good - requires interpolation, has quotes, single line
%(<tr><td class="name">#{name}</td>)
- Используйте% r только для регулярных выражений, соответствующих более чем одному символу '/'.
# bad
%r(\s+)
# still bad
%r(^/(.*)$)
# should be /^\/(.*)$/
# good
%r(^/blog/2011/(.*)$)
Процентные литералы
- Используйте% w свободно.
STATES = %w(draft open closed)
- Используйте% () для однострочных строк, которые требуют как интерполяции, так и двойных кавычек. Для многострочных строк предпочитайте heredocs.
# should be '<div class="text">Some text</div>'
# bad - no double-quotes
%(This is #{quality} style)
# should be "This is #{quality} style"
# bad - multiple lines
%(<div>\n<span class="big">#{exclamation}</span>\n</div>)
# should be a heredoc.
# good - requires interpolation, has quotes, single line
%(<tr><td class="name">#{name}</td>)
- Используйте% r только для регулярных выражений, соответствующих более чем одному символу '/'.
# bad
%r(\s+)
# still bad
%r(^/(.*)$)
# should be /^\/(.*)$/
# good
%r(^/blog/2011/(.*)$)
Предыдущий: Ruby Literal
Далее: Рубиновые переменные, константы
Новый контент: Composer: менеджер зависимостей для PHP , R программирования