Руководства по стилю Ruby

Содержание
  1. Руководство по стилю/синтаксису Это руководство по стилю Ruby рекомендует стандартные методы, чтобы в реальном мире мы могли писать хороший код. Руководство разделено на несколько разделов. Пробел Отступ NewLines Длина строки Комментарий Комментарии на уровне файла/класса Комментарии к функциям Блокирующие и встроенные комментарии Пунктуация, орфография и грамматика Комментарии TODO Закомментированный код Методы Определения методов Вызовы методов Условные выражения Условные ключевые слова Тернарный оператор Синтаксис Именование Классы Исключения Коллекции Строки Регулярные выражения Процентные литералы Whitespace Используйте программные вкладки с два пробела-отступ. Отступ, если такой же глубокий, как регистр. casewhen song.name == 'Misty' put ' Только не снова! ', Когда song.duration> 120 ставит' Too long! ', когда Time.now.hour> 21 ставит "Уже слишком поздно", иначе song.playendkind = case year, когда 1850..1889, затем' Blues ', когда 1890..1909, затем' Ragtime ', когда 1910..1929, затем' New Orleans Jazz ', когда 1930..1939, затем' Swing ', когда 1940..1950, затем' Bebop 'else' Jazz 'end Выровнять параметры функции либо все включено та же строка или по одной на # gooddef self.create_translation (фраза_id, фраза_key, target_locale, значение, user_id, do_xss_check, allow_verification) ... end # baddef self.create_translation (фраза_ид, фраза_ключ, целевой_локал, значение, user_id, do_xss_check, allow_verification) ... конец Отступать следующие строки в многострочных логических выражениях. // пользователь) Trebuchet.current.launch? (ProgramEligibilityHelper :: PROGRAM_TREBUCHET_FLAG) && is_i n_program? (пользователь) && program_not_expiredend Никогда не оставляйте конечные пробелы. Используйте пробелы вокруг операторов; после запятых, двоеточий и точек с запятой; и вокруг {и до}. sum = 1 + 2 a, b = 1, 2 1> 2? истина: ложь; помещает 'Hi' [1, 2, 3] .each {| e | помещает e} Без пробелов после (, [или перед],) some (arg) .other [1, 2, 3] .length Новые строки: Добавьте новую строку после if, условия охватывают несколько строк, чтобы помочь различать условия и тело. if @servations_alteration.checkin == @ Booking.start_date && @ Booking_alteration.checkout == (@ Booking.start_date + @ Booking.nights) redirect_to_alteration @reservation_alteration конец Длина строки Сохраняйте длину каждой строки кода читаемой. Если у вас нет причины, используйте строки длиной менее 100 символов. Сохранение кода, визуально сгруппированного вместе (в соответствии с ограничением строки в 100 символов), упрощает понимание. Например, вам не нужно прокручивать одну строку вперед и назад, чтобы увидеть, что происходит — вы можете просматривать все это вместе. Вот примеры из нашей кодовой базы, демонстрирующие несколько методов взлома сложные операторы в несколько строк, все либеральное использование разрывов строк внутри незакрытых ({[ цепочка методы, заканчивая незаконченные цепочки символом. , составляя длинные строки, помещая строки рядом друг с другом, разделенные обратной косой чертой, а затем новой строкой. разрыв длинных логических операторов с переносом строки после таких операторов, как && и || scope = Translation :: Phrase.includes (: фраза_перевод). Объединяется (: фраза_скриншоты). Где (: фраза_screenshots => {: controller => имя_контроллера,: действие => JAROMIR_JAGR_SALUTE,}) translation = FactoryGirl.create (: фраза_перевод,: locale =>: is,: фраза => фраза,: key => 'phone_number_not_revealed_time_zon e ',: 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 @servations_alteration.checkin == @ резервирование.начальная_дата && @ резервирование_alteration.checkout == (@ резервирование.начальная_дата + @ резервирование.ночи) redirect_to_alteration @reservation_alterationend "Виза для иностранных путешественников"),: beveled_big_icon => "штамп" do%> "Иностранным гостям, направляющимся в Россию, возможно, потребуется получить визу ...")%> Эти фрагменты кода намного более читабельны, чем альтернатива: scope = Translation :: Phrase.includes (: фраза_переводы) .joins (: фраза_скрина) .where (: фраза_скрина => {: controller => имя_контроллера,: действие => JAROMIR_JAGR_SALUTE}) translation = FactoryGirl.create (: фраза_перевод,: locale =>: is,: фраза => фраза,: 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 @servation_alteration.checkin == @ reservation.start_date && @ Booking_alteration.checkout == (@ Booking.start_date + @ Booking.nights) redirect_to_alteration @reservation_alterationend "Виза для иностранных путешественников"),: beveled_big_icon => "штамп" do%> "Иностранным гостям, направляющимся в Россию, возможно, потребуется получить визу до ...")%> Комментирование Несмотря на то, что писать комментарии сложно, они абсолютно необходимы для обеспечения читабельности нашего кода. Следующие правила описывают, что и где следует комментировать. Но помните: хотя комментарии очень важны, лучший код самодокументируется. Давать разумные имена типам и переменным намного лучше, чем использовать непонятные имена, которые вы затем должны объяснять в комментариях. При написании ваших комментариев, напишите для своей аудитории: следующий участник, которому нужно будет понять ваш код. Будьте щедры — следующим может быть вы! Части этого раздела во многом заимствованы из руководств по стилю Google C ++ и Python. Комментарии на уровне файла/класса: Каждое определение класса должно иметь сопровождающий комментарий, описывающий, для чего оно предназначено и как его следует использовать. Файл, содержащий ноль классов или более одного класса, должен иметь комментарий вверху, описывающий его содержимое. # Автоматическое преобразование одного языкового стандарта в другой, где это возможно, например, # Американский английский в британский. Модуль перевода # Класс для преобразования текста между похожими языками. # На данный момент предоставляется единственное преобразование между американским английским -> британским, канадским, # австралийским и новозеландским вариантами. class PrimAndProper def initialize @converters = {: en => {: "en-AU" => AmericanToAustralian.new,: "en-CA" => AmericanToCanadian.new,: "en-GB" => AmericanToBritish.new,: "en-NZ" => AmericanToKiwi.new,}} end ... # Применяет преобразования к американскому английскому языку, что является общим для # вариантов всех других английских колоний. class AmericanToColonial ... end # Преобразует американский английский в британский. # В дополнение к обычным вариациям колониального английского языка, меняет "apartment" # на "flat". class AmericanToBritish Все файлы, включая файлы данных и конфигурации, должны иметь комментарии на уровне файлов. Из translation/config/columnsial_spelling_variants.yml: Список вариантов написания с американского на британский . ## Этот список составлен с помощью # lib/tasks/list_american_to_british_spelling_variants.rake. ## Он содержит слова с общими вариантами написания: # [trave] led/lled, [real] ize/ise, [flav] или/our, [cent] er/re, плюс # и эти дополнения: # изучено/изучено , практики/практики, самолет/самолет, ... сектантства: сектантстванейтрализация: нейтрализация ... Комментарии к функциям: Каждое объявление функции должно иметь комментарии непосредственно перед ним, описывающие, что функция делает и как ее использовать. Эти комментарии должны быть описательными («Открывает файл»), а не императивными («Открыть файл»); комментарий описывает функцию, но не говорит функции, что ей делать. Как правило, эти комментарии не описывают, как функция выполняет свою задачу. Вместо этого это следует оставить комментариям, перемежаемым в коде функции. Каждая функция должна упоминать, что такое входы и выходы, если только она не удовлетворяет всем следующим критериям: не виден извне очень короткий очевидный Вы можете использовать любой формат, который вы желание. В Ruby две популярные схемы документации функций — это TomDoc и YARD. Вы также можете просто кратко записать вещи: # Возвращает резервные локали для the_locale. # Если установлено opts [: exclude_default], локаль по умолчанию, которая # в противном случае всегда последний из возвращенного списка будет исключен. ## Например: # 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 () для создания массива, который мы можем изменить. ret = @fallbacks [the_locale] .dup # Здесь мы делаем два предположения: # 1) Существует только один языковой стандарт по умолчанию (то есть у него нет менее специфичных # дочерних элементов). # 1) Локаль по умолчанию - это просто язык. (Например: en, а не en-US.) If opts [: exclude_default] && ret.last == self.default_locale && ret.last! = Language_from_locale (the_locale) ret.pop end retend С другой стороны, никогда не описывайте код. Предположим, человек, читающий код, знает язык (но не то, что вы пытаетесь сделать) лучше, чем вы. Пунктуация, орфография и грамматика: Обратите внимание на пунктуацию, орфографию и грамматику; хорошо написанные комментарии легче читать, чем плохо написанные. Комментарии должны быть такими же удобочитаемыми, как и повествовательный текст, с правильными заглавными буквами и пунктуацией. Во многих случаях полные предложения читаются лучше, чем их фрагменты. Более короткие комментарии, такие как комментарии в конце строки кода, иногда могут быть менее формальными, но вы должны соответствовать своему стилю. Хотя может быть неприятно иметь точку зрения рецензента кода Обратите внимание, что вы используете запятую, когда вам следует использовать точку с запятой, очень важно, чтобы исходный код поддерживал высокий уровень ясности и удобочитаемости. Правильная пунктуация, орфография и грамматика помогают в достижении этой цели. TODO-комментарии: Используйте TODO-комментарии для временного кода , краткосрочное решение или достаточно хорошее, но не идеальное. TODO должны включать строку TODO заглавными буквами, за которой следует полное имя человека, который может лучше всего представить контекст проблемы. на которую ссылается TODO, в круглых скобках. Двоеточие указывать не обязательно. Комментарий, объясняющий, что нужно делать, является обязательным. Основная цель состоит в том, чтобы иметь согласованный формат TODO, который можно было бы искать, чтобы найти человека, который может предоставить более подробную информацию по запросу. TODO — это не обязательство, что указанное лицо устранит проблему. Таким образом, когда вы создаете TODO, почти всегда указывается ваше имя. # bad # TODO (RS): Используйте правильное пространство имен для этой константы. # bad # TODO (drumm3rz4lyfe): используйте правильное пространство имен для этой константы. # good # TODO (Ringo Starr): используйте правильное пространство имен для этой константы. Закомментированный код: Никогда не оставляйте закомментированный код в нашей кодовой базе. Методы Определения методов: Используйте def в круглых скобках, когда есть параметры. Опускайте круглые скобки, если метод не принимает никаких параметров. def some_method # тело пропущено end def some_method_with_parameters (arg1, arg2) # тело пропущено end Не использовать аргументы по умолчанию. Вместо этого используйте хэш параметров. # baddef Obliterate (things, softly = true, except = [], at = Time.now) ... end # gooddef Obliterate (things, options = {}) default_options = {: weakly => true, # стереть с мягким удалением: except => [], # пропустить стирание этих вещей: at => Time.now, # не стирать их на потом} options.reverse_merge! (default_options) ... end Вызов методов: Используйте круглые скобки для вызова метода: Если метод возвращает значение. # bad @ current_user = User.find_by_id 1964192 # good @ current_user = User.find_by_id (1964192) Если в первом аргументе метода используются круглые скобки. # ошибка! (x + y)% len, value # goodput! ((x + y)% len, value) Никогда не ставьте пробел между именем метода и открывающая скобка. # badf (3 + 2) + 1 # goodf (3 + 2) + 1 Не используйте скобки для вызова метода, если метод не принимает аргументов. # badnil? () # goodnil? Если метод не вернуть значение (или нас не волнует возврат), круглые скобки необязательны. (Особенно, если аргументы занимают несколько строк, скобки могут улучшить читаемость.) # okayrender (: partial => 'foo') # okayrender: partial = > 'foo' В любом случае: Если метод принимает хэш параметров в качестве последнего аргумента, не используйте {} во время вызова. # bad get '/v1/reservations', {: id => 54875} # good get '/v1/reservations', : id => 54875 Условные выражения Условные ключевые слова: Никогда не используйте then для многострочного if/if. # badif some_condition then ... end # goodif some_condition ... end Ключевые слова and, or и not запрещены. Просто оно того не стоит. Всегда используйте &&, || и! вместо этого. Модификатор, если/если использование разрешено, когда тело простое, условие простое, и все это умещается в одной строке. В противном случае избегайте модификатора if/if # bad - это не помещается в одной строке add_trebuchet_experiments_on_page (request_opts [: trebuchet_experiments_on_page]) if request_opts [: trebuchet_experiments_on_page] &&! request_opts [: trebuchet_experiments_on_page]. пусто? # Хорошо, если 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 - это сложно и требует нескольких строк и комментария parts [i] = part.to_i (INTEGER_BASE) if! part.nil? && [0, 2, 3] .include? (I) # нормально вернуть, если self.reconciled? Никогда не использовать, если только с else. Сначала перепишите их с положительным регистром. # плохо, разве что удачно? ставит «неудача» или «успех» помещает "успех" или "завершает" Избегать, если только не указано несколько условий. # плохо, если только foo? && бар? ... end # хорошо, если! (foo? && bar?) ... end Не используйте круглые скобки вокруг условия if/except /while, если условие не содержит присваивания (см. Использование возвращаемого значения = ниже). # плохо if (x> 10) ... end # хорошо, если x> 10 ... end # хорошо, если (x = self.next_value) ... end Тернарный оператор: Избегайте тернарного оператора (? :), за исключением случаев, когда все выражения чрезвычайно тривиальны. Однако используйте тернарный оператор (? 🙂 над конструкциями if/then/else/end для однострочных условных выражений.. # bad result = if some_condition, то что-то еще something_else end # good result = some_condition? something: something_else Используйте одно выражение для каждой ветви в тернарном операторе. Это также означает, что тернарные операторы не должны быть вложенными. В этих случаях лучше использовать конструкции if/else. # bad some_condition? (nested_condition? nested_something: nested_something_else): something_else # хорошо if some_condition nested_condition? nested_something: nested_something_else else something_else end Избегать многострочности?: (тернарный оператор), используйте вместо этого if/then/else/end. Синтаксис: Никогда не используйте for, если вы точно не знаете почему. Вместо этого в большинстве случаев следует использовать итераторы. for реализован с точки зрения каждого (так что вы добавляете уровень косвенности), но с изюминкой — for не вводит новую область видимости (в отличие от каждого), и переменные, определенные в его блоке, будут видны за ее пределами. arr = [1, 2, 3] # плохо для элемента в arr do ставит elem end # хорошо arr.each {| elem | помещает elem} Предпочитать {…} над do … end для однострочных блоков. Избегайте использования {…} для многострочных блоков (многострочные цепочки всегда уродливы). Всегда используйте do … end для «потока управления» и «определений методов» (например, в Rakefiles и некоторых DSL). Избегайте do … end при связывании. names = ["Bozhidar", "Steve", "Sarah"] # good names.each {| name | помещает name} # bad names.each do | name | помещает 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} Некоторые будут утверждать, что многострочная цепочка могла бы выглядеть нормально с использованием {…}, но они должны спросить себя, действительно ли этот код читается и содержимое блока может быть извлечено с помощью изящных методов. Избегайте возврата там, где он не требуется. # baddef some_method (some_arr) return some_arr.sizeend # gooddef some_method (some_arr) some_arr.sizeend Использование возвращаемого значения = (присваивание) нормально, но окружите присваивание скобками. # хорошо - показывает предполагаемое использование присваивания if (v = array.grep (/foo/)) ... end # плохо if v = array.grep (/foo/) ... end # тоже хорошо - показывает предполагаемое использование присваивания и имеет правильный приоритет if (v = self.next_value) == "hello" ... end Используйте || = свободно для инициализации переменных. # задайте имя Божидар, только если оно равно nil или falsename || = 'Божидар' Не используйте || = в ini установить логические переменные. (Подумайте, что произойдет, если текущее значение окажется ложным. ) # bad - для параметра enabled будет установлено значение true, даже если оно было false, enabled || = true # good enabled = true, если включено. nil? Избегайте использования специальных переменных в стиле Perl (например, $ 0-9, $ и т. д.). Они довольно загадочны, и их использование в любых сценариях, кроме однострочных, не рекомендуется. Предпочитайте длинные версии, такие как $ PROGRAM_NAME. Используйте _ для неиспользуемых аргументов блока. # badresult = hash.map { | k, v | v + 1} # goodresult = hash.map {| _, v | v + 1} Когда блок метода принимает только один аргумент, а тело состоит исключительно из чтения атрибута или вызова одного метода без аргументов, используйте &: сокращение. # bad bluths.map {| bluth | bluth.occupation} bluths.select {| bluth | bluth.blue_self? } # good bluths.map (&: occation) bluths.select (&: blue_self?) Именование Используйте snake_case для методов и переменных. Используйте CamelCase для классов и модулей. (Сохраняйте аббревиатуры вроде HTTP, RFC, XML в верхнем регистре.) Используйте SCREAMING_SNAKE_CASE для других констант. Имена методов предиката (методов, возвращающих логическое значение) должны заканчиваться вопросительным знаком. (т.е. массив # пуст?). Имена потенциально «опасных» методов (т.е. методов, которые изменяют себя или аргументы, exit !, и т. д.) должны заканчиваться восклицательным знаком. Методы взрыва должны существовать, только если существует метод без взрыва. (Подробнее об этом.) Назовите одноразовые переменные _. payment, _ = Payment.complete_paypal_payment! (Params [: токен], native_currency, created_at) Classes Избегайте использования переменных класса (@@) из-за их «неприятных «поведение при наследовании. class Parent @@ class_var = 'parent' def self.print_class_var помещает @@ class_var endendclass Child напечатает «дочерний» Как вы можете видеть, все классы в иерархии классов фактически используют одну переменную класса. Переменные экземпляра класса обычно предпочтительнее переменных класса. Используйте def self.method для определения одноэлементных методов. Это делает методы более устойчивыми к изменениям рефакторинга. class TestClass # bad def TestClass.some_method ... end # good def self.some_other_method ... end Избегайте class class TestClass # bad class Сделать отступ для публики, защищенные и частные методы, а также определения методов, к которым они применяются. Оставьте одну пустую строку над ними. class SomeClass def public_method # ... end private def private_method # ... end end Исключения Не используйте исключения для потока управления. # badbegin n/drescue ZeroDivisionError put " Нельзя делить на 0! "End # goodif d.zero? помещает «Невозможно разделить на 0!» иначе n/dend Избегайте сохранения класса Exception. # badbegin # здесь возникает исключение rescue Exception # exception processingend # goodbegin # здесь возникает исключение rescue StandardError # обработка исключенияend # acceptbegin # здесь возникает исключениеrescue # обработка исключенийend Коллекции Используйте Set вместо Array при работе с уникальными элементами. Set реализует коллекцию неупорядоченных значений без дубликатов. Это гибрид интуитивно понятных средств взаимодействия Array и быстрого поиска по Hash. Используйте символы вместо строк в качестве ключей хеширования. # badhash = {'one' => 1, 'two' => 2, 'three' => 3} # goodhash = {: one => 1,: two => 2,: three => 3} Используйте многострочные хэши, когда это делает код более читаемым, и используйте конечные запятые, чтобы гарантировать, что изменения параметров не вызывают посторонних строк различий, когда логика иначе не изменено. hash = {: protocol => 'https',: only_path => false,: controller =>: users,: action => : set_password,: redirect => @redirect_url,: secret => @secret,} Строки Вместо этого предпочитать строковую интерполяцию конкатенации строк: # bademail_with_name = user.name + '" Кроме того, помните об интерполяции в стиле Ruby 1.9. Допустим, вы составляете ключи кеша следующим образом: CACHE_KEY = '_store'cache.write (@ user.id + CACHE_KEY) Предпочитать интерполяцию строк вместо объединения строк: CACHE_KEY = '% d_store'cache.write (CACHE_KEY% @ user.id) Избегайте использования String # +, когда вам нужно создать большие блоки данных. Вместо этого используйте String # # хороший, а также быстрый HTML = '' html Заголовок страницы ' paragraphs.each do | paragraph | html # {paragraph} " end Регулярные выражения Избегайте использования $ 1- 9, так как может быть трудно отследить, что они содержат. Вместо этого можно использовать именованные группы. # bad/(regexp)/= ~ string ... process $ 1 # good/(? regexp) /= ~ строка ... process meanful_var Будьте осторожны с ^ и $, поскольку они соответствуют началу/концу строки, а не окончанию строки. Если вы хотите сопоставить всю строку, используйте: A и z. string = "some injection nusername" string [/^ username $/] # соответствует строке [/ Ausername z/] # не соответствует Используйте модификатор x для сложных регулярных выражений. Это делает их более удобочитаемыми, и вы можете добавлять полезные комментарии. Только будьте осторожны, пробелы игнорируются. regexp =% r {start # some text s # white space char (group) # first group (?: alt1 | alt2) # некоторая альтернатива end} x Процентные литералы Используйте% w свободно. STATES =% w (проект открыт закрыт) Используйте% () для однострочных строк, требующих как интерполяция, так и встроенные двойные кавычки. Для многострочных строк лучше использовать heredocs. # должно быть '
    Some text
    ' # bad - no двойные кавычки% (это стиль # {качество}) # должно быть "Это стиль # {качество}" # плохо - несколько строк% (
    n # {exclamation} n
    ) # должен быть наследником. # хорошо - требует интерполяции, содержит кавычки, однострочный% ( # {name} )
    • Используйте% r только для регулярных выражений, соответствующих более чем одному символу '/'.
      # плохо% r ( s +) # все еще плохо% r (^ /(.*)$)# должно быть/^/(.*)$/# good% r (^/blog/2011/(.*)$)
    Процентные литералы
    Используйте% w свободно.
    STATES =% w (проект открыт закрыт)
    Используйте% () для однострочных строк, которые требуют как интерполяции, так и встроенных двойных кавычек.  Для многострочных строк лучше использовать heredocs.
    # должно быть '
    Some text
    ' # bad - no двойные кавычки% (это стиль # {качество}) # должно быть "Это стиль # {качество}" # плохо - несколько строк% (
    n # {exclamation} n
    ) # должен быть наследником. # хорошо - требует интерполяции, содержит кавычки, однострочный% ( # {name} )
    • Используйте% r только для регулярных выражений, соответствующих более чем одному символу '/'.
      # плохо% r ( s +) # все еще плохо% r (^ /(.*)$)# должно быть/^/(.*)$/# good% r (^/blog/2011/(.*)$)
    
    
    
    
    
    
  2. Whitespace
  3. Длина строки
  4. Комментирование
  5. Методы
  6. Условные выражения
  7. Синтаксис:
  8. Именование
  9. Classes
  10. Исключения
  11. Коллекции
  12. Строки
  13. Регулярные выражения
  14. Процентные литералы
  15. Процентные литералы

Руководство по стилю/синтаксису

Это руководство по стилю Ruby рекомендует стандартные методы, чтобы в реальном мире мы могли писать хороший код. Руководство разделено на несколько разделов.

  • Пробел
    • Отступ
    • NewLines
  • Длина строки
  • Комментарий
    • Комментарии на уровне файла/класса
    • Комментарии к функциям
    • Блокирующие и встроенные комментарии
    • Пунктуация, орфография и грамматика
    • Комментарии TODO
    • Закомментированный код
  • Методы
    • Определения методов
    • Вызовы методов
  • Условные выражения
    • Условные ключевые слова
    • Тернарный оператор
  • Синтаксис
  • Именование
  • Классы
  • Исключения
  • Коллекции
  • Строки
  • Регулярные выражения
  • Процентные литералы

Whitespace

  • Используйте программные вкладки с два пробела-отступ.
  • Отступ, если такой же глубокий, как регистр.
  casewhen song.name == 'Misty' put '  Только не снова! ', Когда song.duration> 120 ставит' Too  long! ', когда Time.now.hour> 21 ставит "Уже слишком поздно", иначе song.playendkind = case year, когда 1850..1889, затем' Blues ', когда 1890..1909, затем' Ragtime ', когда 1910..1929, затем' New  Orleans Jazz ', когда 1930..1939, затем' Swing ', когда 1940..1950, затем' Bebop 'else' Jazz 'end  
  • Выровнять параметры функции либо все включено та же строка или по одной на
  # gooddef self.create_translation (фраза_id, фраза_key, target_locale, значение, user_id, do_xss_check, allow_verification) ... end # baddef  self.create_translation (фраза_ид, фраза_ключ, целевой_локал, значение, user_id, do_xss_check, allow_verification) ... конец  
  • Отступать следующие строки в многострочных логических выражениях. // пользователь) Trebuchet.current.launch? (ProgramEligibilityHelper :: PROGRAM_TREBUCHET_FLAG) && is_i n_program? (пользователь) && program_not_expiredend

    • Никогда не оставляйте конечные пробелы.
    • Используйте пробелы вокруг операторов; после запятых, двоеточий и точек с запятой; и вокруг {и до}.
      sum = 1 + 2 a, b = 1, 2 1> 2?  истина: ложь;  помещает 'Hi' [1, 2, 3] .each {| e |  помещает e}  
    • Без пробелов после (, [или перед],)
       some (arg) .other [1, 2, 3] .length  

    Новые строки:

    • Добавьте новую строку после if, условия охватывают несколько строк, чтобы помочь различать условия и тело.
      if @servations_alteration.checkin == @ Booking.start_date && @ Booking_alteration.checkout == (@ Booking.start_date + @ Booking.nights) redirect_to_alteration @reservation_alteration  конец  

    Длина строки

    Сохраняйте длину каждой строки кода читаемой. Если у вас нет причины, используйте строки длиной менее 100 символов. Сохранение кода, визуально сгруппированного вместе (в соответствии с ограничением строки в 100 символов), упрощает понимание. Например, вам не нужно прокручивать одну строку вперед и назад, чтобы увидеть, что происходит — вы можете просматривать все это вместе.

    Вот примеры из нашей кодовой базы, демонстрирующие несколько методов взлома сложные операторы в несколько строк, все

    • либеральное использование разрывов строк внутри незакрытых ({[
    • цепочка методы, заканчивая незаконченные цепочки символом.
    • , составляя длинные строки, помещая строки рядом друг с другом, разделенные обратной косой чертой, а затем новой строкой.
    • разрыв длинных логических операторов с переносом строки после таких операторов, как && и ||
      scope = Translation ::  Phrase.includes (: фраза_перевод). Объединяется (: фраза_скриншоты). Где (: фраза_screenshots => {: controller => имя_контроллера,: действие => JAROMIR_JAGR_SALUTE,}) 
     translation = FactoryGirl.create (: фраза_перевод,: locale =>: is,: фраза => фраза,: key => 'phone_number_not_revealed_time_zon  e ',: 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 @servations_alteration.checkin ==  @ резервирование.начальная_дата && @ резервирование_alteration.checkout == (@ резервирование.начальная_дата + @ резервирование.ночи) redirect_to_alteration @reservation_alterationend  
        "Виза для иностранных путешественников"),: beveled_big_icon => "штамп" do%>  "Иностранным гостям, направляющимся в Россию, возможно, потребуется получить визу ...")%>    

    Эти фрагменты кода намного более читабельны, чем альтернатива:

      scope = Translation :: Phrase.includes (: фраза_переводы) .joins (:  фраза_скрина) .where (: фраза_скрина => {: controller => имя_контроллера,: действие => JAROMIR_JAGR_SALUTE}) translation = FactoryGirl.create (: фраза_перевод,: locale =>: is,: фраза => фраза,: 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 @servation_alteration.checkin == @ reservation.start_date && @ Booking_alteration.checkout == (@ Booking.start_date + @ Booking.nights) redirect_to_alteration @reservation_alterationend  
        "Виза для иностранных путешественников"),: beveled_big_icon => "штамп" do%>  "Иностранным гостям, направляющимся в Россию, возможно, потребуется получить визу до ...")%>    

    Комментирование

    Несмотря на то, что писать комментарии сложно, они абсолютно необходимы для обеспечения читабельности нашего кода. Следующие правила описывают, что и где следует комментировать. Но помните: хотя комментарии очень важны, лучший код самодокументируется. Давать разумные имена типам и переменным намного лучше, чем использовать непонятные имена, которые вы затем должны объяснять в комментариях.

    При написании ваших комментариев, напишите для своей аудитории: следующий участник, которому нужно будет понять ваш код. Будьте щедры — следующим может быть вы!

    Части этого раздела во многом заимствованы из руководств по стилю Google C ++ и Python.

    Комментарии на уровне файла/класса:

    Каждое определение класса должно иметь сопровождающий комментарий, описывающий, для чего оно предназначено и как его следует использовать.

    Файл, содержащий ноль классов или более одного класса, должен иметь комментарий вверху, описывающий его содержимое.

       # Автоматическое преобразование одного языкового стандарта в другой, где это возможно, например, # Американский английский в британский. Модуль перевода # Класс для преобразования текста между похожими языками.  # На данный момент предоставляется единственное преобразование между американским английским -> британским, канадским, # австралийским и новозеландским вариантами.  class PrimAndProper def initialize @converters = {: en => {: "en-AU" => AmericanToAustralian.new,: "en-CA" => AmericanToCanadian.new,: "en-GB" => AmericanToBritish.new,:  "en-NZ" => AmericanToKiwi.new,}} end ... # Применяет преобразования к американскому английскому языку, что является общим для # вариантов всех других английских колоний.  class AmericanToColonial ... end # Преобразует американский английский в британский.  # В дополнение к обычным вариациям колониального английского языка, меняет "apartment" # на "flat".  class AmericanToBritish  

    Все файлы, включая файлы данных и конфигурации, должны иметь комментарии на уровне файлов. Из

      translation/config/columnsial_spelling_variants.yml:  
      Список вариантов написания с американского на британский  . ## Этот список составлен с помощью # lib/tasks/list_american_to_british_spelling_variants.rake. ## Он содержит слова с общими вариантами написания: # [trave] led/lled, [real] ize/ise, [flav] или/our, [cent] er/re, плюс # и эти дополнения: # изучено/изучено  , практики/практики, самолет/самолет, ... сектантства: сектантстванейтрализация: нейтрализация ...  

    Комментарии к функциям:

    Каждое объявление функции должно иметь комментарии непосредственно перед ним, описывающие, что функция делает и как ее использовать. Эти комментарии должны быть описательными («Открывает файл»), а не императивными («Открыть файл»); комментарий описывает функцию, но не говорит функции, что ей делать. Как правило, эти комментарии не описывают, как функция выполняет свою задачу. Вместо этого это следует оставить комментариям, перемежаемым в коде функции.

    Каждая функция должна упоминать, что такое входы и выходы, если только она не удовлетворяет всем следующим критериям:

    • не виден извне
    • очень короткий
    • очевидный

    Вы можете использовать любой формат, который вы желание. В Ruby две популярные схемы документации функций — это TomDoc и YARD. Вы также можете просто кратко записать вещи:

      # Возвращает резервные локали для the_locale. # Если установлено opts [: exclude_default], локаль по умолчанию, которая # в противном случае всегда  последний из возвращенного списка будет исключен. ## Например: # 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 () для создания массива, который мы можем изменить.  ret = @fallbacks [the_locale] .dup # Здесь мы делаем два предположения: # 1) Существует только один языковой стандарт по умолчанию (то есть у него нет менее специфичных # дочерних элементов).  # 1) Локаль по умолчанию - это просто язык.  (Например: en, а не en-US.) If opts [: exclude_default] && ret.last == self.default_locale && ret.last! = Language_from_locale (the_locale) ret.pop end retend  

    С другой стороны, никогда не описывайте код. Предположим, человек, читающий код, знает язык (но не то, что вы пытаетесь сделать) лучше, чем вы.

    Пунктуация, орфография и грамматика:

    Обратите внимание на пунктуацию, орфографию и грамматику; хорошо написанные комментарии легче читать, чем плохо написанные.

    Комментарии должны быть такими же удобочитаемыми, как и повествовательный текст, с правильными заглавными буквами и пунктуацией. Во многих случаях полные предложения читаются лучше, чем их фрагменты. Более короткие комментарии, такие как комментарии в конце строки кода, иногда могут быть менее формальными, но вы должны соответствовать своему стилю.

    Хотя может быть неприятно иметь точку зрения рецензента кода Обратите внимание, что вы используете запятую, когда вам следует использовать точку с запятой, очень важно, чтобы исходный код поддерживал высокий уровень ясности и удобочитаемости. Правильная пунктуация, орфография и грамматика помогают в достижении этой цели.

    TODO-комментарии:

    Используйте TODO-комментарии для временного кода , краткосрочное решение или достаточно хорошее, но не идеальное.

    TODO должны включать строку TODO заглавными буквами, за которой следует полное имя человека, который может лучше всего представить контекст проблемы. на которую ссылается TODO, в круглых скобках. Двоеточие указывать не обязательно. Комментарий, объясняющий, что нужно делать, является обязательным. Основная цель состоит в том, чтобы иметь согласованный формат TODO, который можно было бы искать, чтобы найти человека, который может предоставить более подробную информацию по запросу. TODO — это не обязательство, что указанное лицо устранит проблему. Таким образом, когда вы создаете TODO, почти всегда указывается ваше имя.

      # bad # TODO (RS): Используйте правильное пространство имен для этой константы.  # bad # TODO (drumm3rz4lyfe): используйте правильное пространство имен для этой константы.  # good # TODO (Ringo Starr): используйте правильное пространство имен для этой константы.  

    Закомментированный код:

    Никогда не оставляйте закомментированный код в нашей кодовой базе.

    Методы

    Определения методов:

    • Используйте def в круглых скобках, когда есть параметры. Опускайте круглые скобки, если метод не принимает никаких параметров.
      def some_method # тело пропущено end def some_method_with_parameters (arg1, arg2) # тело пропущено end  
    • Не использовать аргументы по умолчанию. Вместо этого используйте хэш параметров.
      # baddef Obliterate (things, softly = true, except = [], at = Time.now) ... end #  gooddef Obliterate (things, options = {}) default_options = {: weakly => true, # стереть с мягким удалением: except => [], # пропустить стирание этих вещей: at => Time.now, # не стирать  их на потом} options.reverse_merge! (default_options) ... end  

    Вызов методов:

    Используйте круглые скобки для вызова метода:

    • Если метод возвращает значение.
      # bad @ current_user =  User.find_by_id 1964192 # good @ current_user = User.find_by_id (1964192)  
    • Если в первом аргументе метода используются круглые скобки.
      # ошибка!  (x + y)% len, value # goodput! ((x + y)% len, value)  
    • Никогда не ставьте пробел между именем метода и открывающая скобка.
      # badf (3 + 2) + 1 # goodf (3 + 2) + 1  
    • Не используйте скобки для вызова метода, если метод не принимает аргументов.
      # badnil? () # goodnil?  
    • Если метод не вернуть значение (или нас не волнует возврат), круглые скобки необязательны. (Особенно, если аргументы занимают несколько строк, скобки могут улучшить читаемость.)
      # okayrender (: partial => 'foo') # okayrender: partial =  > 'foo'  

    В любом случае:

    • Если метод принимает хэш параметров в качестве последнего аргумента, не используйте {} во время вызова.
      # bad get '/v1/reservations', {: id => 54875} # good get '/v1/reservations',  : id => 54875  

    Условные выражения

    Условные ключевые слова:

    • Никогда не используйте then для многострочного if/if.
      # badif some_condition then ... end # goodif some_condition ... end  
    • Ключевые слова and, or и not запрещены. Просто оно того не стоит. Всегда используйте &&, || и! вместо этого.
    • Модификатор, если/если использование разрешено, когда тело простое, условие простое, и все это умещается в одной строке. В противном случае избегайте модификатора if/if
      # bad - это не помещается в одной строке add_trebuchet_experiments_on_page (request_opts [: trebuchet_experiments_on_page]) if request_opts [: trebuchet_experiments_on_page]  &&! request_opts [: trebuchet_experiments_on_page]. пусто?  # Хорошо, если 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 - это сложно и требует нескольких строк и комментария parts [i] = part.to_i (INTEGER_BASE) if! part.nil?  && [0, 2, 3] .include? (I) # нормально вернуть, если self.reconciled?  
    • Никогда не использовать, если только с else. Сначала перепишите их с положительным регистром.
      # плохо, разве что удачно?  ставит «неудача» или «успех»  помещает "успех" или "завершает"  
    • Избегать, если только не указано несколько условий.
      # плохо, если только foo?  && бар?  ... end # хорошо, если! (foo? && bar?) ... end  
    • Не используйте круглые скобки вокруг условия if/except /while, если условие не содержит присваивания (см. Использование возвращаемого значения = ниже).
      # плохо if (x> 10) ... end  # хорошо, если x> 10 ... end # хорошо, если (x = self.next_value) ... end  

    Тернарный оператор:

    • Избегайте тернарного оператора (? :), за исключением случаев, когда все выражения чрезвычайно тривиальны. Однако используйте тернарный оператор (? 🙂 над конструкциями if/then/else/end для однострочных условных выражений..
      # bad result = if some_condition, то что-то еще something_else end # good result = some_condition?  something: something_else  
    • Используйте одно выражение для каждой ветви в тернарном операторе. Это также означает, что тернарные операторы не должны быть вложенными. В этих случаях лучше использовать конструкции if/else.
      # bad some_condition?  (nested_condition? nested_something: nested_something_else): something_else # хорошо if some_condition nested_condition?  nested_something: nested_something_else else something_else end  
    • Избегать многострочности?: (тернарный оператор), используйте вместо этого if/then/else/end.

    Синтаксис:

    • Никогда не используйте for, если вы точно не знаете почему. Вместо этого в большинстве случаев следует использовать итераторы. for реализован с точки зрения каждого (так что вы добавляете уровень косвенности), но с изюминкой — for не вводит новую область видимости (в отличие от каждого), и переменные, определенные в его блоке, будут видны за ее пределами.
      arr = [1, 2, 3] # плохо для элемента в arr do ставит elem end # хорошо arr.each {| elem |  помещает elem}  
    • Предпочитать {…} над do … end для однострочных блоков. Избегайте использования {…} для многострочных блоков (многострочные цепочки всегда уродливы). Всегда используйте do … end для «потока управления» и «определений методов» (например, в Rakefiles и некоторых DSL). Избегайте do … end при связывании.
      names = ["Bozhidar", "Steve", "Sarah"] # good names.each {| name  |  помещает name} # bad names.each do | name |  помещает 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}  

    Некоторые будут утверждать, что многострочная цепочка могла бы выглядеть нормально с использованием {…}, но они должны спросить себя, действительно ли этот код читается и содержимое блока может быть извлечено с помощью изящных методов.

    • Избегайте возврата там, где он не требуется.
      # baddef some_method  (some_arr) return some_arr.sizeend # gooddef some_method (some_arr) some_arr.sizeend  
    • Использование возвращаемого значения = (присваивание) нормально, но окружите присваивание скобками.
      # хорошо - показывает предполагаемое использование присваивания if (v = array.grep (/foo/)) ... end # плохо if  v = array.grep (/foo/) ... end # тоже хорошо - показывает предполагаемое использование присваивания и имеет правильный приоритет if (v = self.next_value) == "hello" ... end  
    • Используйте || = свободно для инициализации переменных.
      # задайте имя Божидар, только если оно равно nil или  falsename || = 'Божидар'  
    • Не используйте || = в ini установить логические переменные. (Подумайте, что произойдет, если текущее значение окажется ложным. )
      # bad - для параметра enabled будет установлено значение true, даже если оно было false, enabled || = true # good enabled = true, если включено. nil?  
    • Избегайте использования специальных переменных в стиле Perl (например, $ 0-9, $ и т. д.). Они довольно загадочны, и их использование в любых сценариях, кроме однострочных, не рекомендуется. Предпочитайте длинные версии, такие как $ PROGRAM_NAME.
    • Используйте _ для неиспользуемых аргументов блока.
      # badresult = hash.map {  | k, v |  v + 1} # goodresult = hash.map {| _, v |  v + 1}  
    • Когда блок метода принимает только один аргумент, а тело состоит исключительно из чтения атрибута или вызова одного метода без аргументов, используйте &: сокращение.
      # bad bluths.map {| bluth |  bluth.occupation} bluths.select {| bluth |  bluth.blue_self?  } # good bluths.map (&: occation) bluths.select (&: blue_self?)  

    Именование

    • Используйте snake_case для методов и переменных.
    • Используйте CamelCase для классов и модулей. (Сохраняйте аббревиатуры вроде HTTP, RFC, XML в верхнем регистре.)
    • Используйте SCREAMING_SNAKE_CASE для других констант.
    • Имена методов предиката (методов, возвращающих логическое значение) должны заканчиваться вопросительным знаком. (т.е. массив # пуст?).
    • Имена потенциально «опасных» методов (т.е. методов, которые изменяют себя или аргументы, exit !, и т. д.) должны заканчиваться восклицательным знаком. Методы взрыва должны существовать, только если существует метод без взрыва. (Подробнее об этом.)
    • Назовите одноразовые переменные _.
      payment, _ = Payment.complete_paypal_payment! (Params [:  токен], native_currency, created_at)  

    Classes

    • Избегайте использования переменных класса (@@) из-за их «неприятных «поведение при наследовании.
      class Parent @@ class_var = 'parent' def self.print_class_var помещает @@ class_var endendclass Child  напечатает «дочерний»  

    Как вы можете видеть, все классы в иерархии классов фактически используют одну переменную класса. Переменные экземпляра класса обычно предпочтительнее переменных класса.

    • Используйте def self.method для определения одноэлементных методов. Это делает методы более устойчивыми к изменениям рефакторинга.
      class TestClass # bad def TestClass.some_method ... end # good def self.some_other_method ... end   
    • Избегайте class
      class TestClass # bad class  
    • Сделать отступ для публики, защищенные и частные методы, а также определения методов, к которым они применяются. Оставьте одну пустую строку над ними.
      class SomeClass def public_method # ... end private def private_method # ... end end  

    Исключения

    • Не используйте исключения для потока управления.
      # badbegin n/drescue ZeroDivisionError put "  Нельзя делить на 0! "End # goodif d.zero?  помещает «Невозможно разделить на 0!» иначе n/dend  
    • Избегайте сохранения класса Exception.
      # badbegin # здесь возникает исключение rescue Exception # exception processingend # goodbegin # здесь возникает исключение rescue StandardError # обработка исключенияend # acceptbegin # здесь возникает исключениеrescue # обработка исключенийend  

    Коллекции

    • Используйте Set вместо Array при работе с уникальными элементами. Set реализует коллекцию неупорядоченных значений без дубликатов. Это гибрид интуитивно понятных средств взаимодействия Array и быстрого поиска по Hash.
    • Используйте символы вместо строк в качестве ключей хеширования.
      # badhash = {'one' => 1, 'two' => 2, 'three' => 3} # goodhash = {: one => 1,: two => 2,: three => 3}  
    • Используйте многострочные хэши, когда это делает код более читаемым, и используйте конечные запятые, чтобы гарантировать, что изменения параметров не вызывают посторонних строк различий, когда логика иначе не изменено.
      hash = {: protocol => 'https',: only_path => false,: controller =>: users,: action =>  : set_password,: redirect => @redirect_url,: secret => @secret,}  

    Строки

    • Вместо этого предпочитать строковую интерполяцию конкатенации строк:
      # bademail_with_name = user.name + '" 

    Кроме того, помните об интерполяции в стиле Ruby 1.9. Допустим, вы составляете ключи кеша следующим образом:

      CACHE_KEY = '_store'cache.write (@ user.id + CACHE_KEY)  

    Предпочитать интерполяцию строк вместо объединения строк:

      CACHE_KEY = '% d_store'cache.write (CACHE_KEY% @ user.id)  
    • Избегайте использования String # +, когда вам нужно создать большие блоки данных. Вместо этого используйте String #
      # хороший, а также быстрый HTML  = '' html  Заголовок страницы ' paragraphs.each do | paragraph |  html  # {paragraph} " end  

    Регулярные выражения

    • Избегайте использования $ 1- 9, так как может быть трудно отследить, что они содержат. Вместо этого можно использовать именованные группы.
      # bad/(regexp)/= ~ string ... process $ 1 # good/(?  regexp) /= ~ строка ... process meanful_var  
    • Будьте осторожны с ^ и $, поскольку они соответствуют началу/концу строки, а не окончанию строки. Если вы хотите сопоставить всю строку, используйте: A и z.
      string = "some injection  nusername" string [/^ username $/]  # соответствует строке [/ Ausername  z/] # не соответствует  
    • Используйте модификатор x для сложных регулярных выражений. Это делает их более удобочитаемыми, и вы можете добавлять полезные комментарии. Только будьте осторожны, пробелы игнорируются.
      regexp =% r {start # some text  s # white space char (group) # first group (?:  alt1 | alt2) # некоторая альтернатива end} x  

    Процентные литералы

    • Используйте% w свободно.
      STATES =% w (проект открыт закрыт)  
    • Используйте% () для однострочных строк, требующих как интерполяция, так и встроенные двойные кавычки. Для многострочных строк лучше использовать heredocs.
      # должно быть '
    Some text
    ' # bad - no двойные кавычки% (это стиль # {качество}) # должно быть "Это стиль # {качество}" # плохо - несколько строк% (
    n # {exclamation} n
    ) # должен быть наследником. # хорошо - требует интерполяции, содержит кавычки, однострочный% ( # {name} )
    • Используйте% r только для регулярных выражений, соответствующих более чем одному символу '/'.
      # плохо% r ( s +) # все еще плохо% r (^ /(.*)$)# должно быть/^/(.*)$/# good% r (^/blog/2011/(.*)$)  

    Процентные литералы

    • Используйте% w свободно.
      STATES =% w (проект открыт закрыт)  
    • Используйте% () для однострочных строк, которые требуют как интерполяции, так и встроенных двойных кавычек. Для многострочных строк лучше использовать heredocs.
      # должно быть '
    Some text
    ' # bad - no двойные кавычки% (это стиль # {качество}) # должно быть "Это стиль # {качество}" # плохо - несколько строк% (
    n # {exclamation} n
    ) # должен быть наследником. # хорошо - требует интерполяции, содержит кавычки, однострочный% ( # {name} )
    • Используйте% r только для регулярных выражений, соответствующих более чем одному символу '/'.
      # плохо% r ( s +) # все еще плохо% r (^ /(.*)$)# должно быть/^/(.*)$/# good% r (^/blog/2011/(.*)$)  

Оцените статью
nanomode.ru
Добавить комментарий