diff --git a/CONTRIBUTING-ruRU.md b/CONTRIBUTING-ruRU.md
new file mode 100644
index 000000000..bc32eb8c6
--- /dev/null
+++ b/CONTRIBUTING-ruRU.md
@@ -0,0 +1,36 @@
+# Как сотрудничать в проекте
+
+Мы очень рады, что вы решили помочь нам в этом проекте! Пожалуйста,
+следуйте простым правилам, описанным ниже.
+
+* Сделайте [личную копию][fork] (fork) этого проекта GitHub'е.
+
+* Если вы еще не решили, чем вы можете помочь этому проекту, то просмотрите
+ пометки с тегом `@FIXME` в исходном коде. Возможно, что-то из этих пунктов
+ покажется вам интересным.
+
+* Если задуманные изменения велики и вызывают сомнения, инициируйте
+ [обсуждение][issues] с описанием ваших намерений.
+
+* Создайте тематическую ветку с говорящим именем: `fb_some_important_fix`.
+ Не стесняйтесь создать несколько веток для связанных по смыслу изменений:
+ принять изменение проще, если оно атомарно, и сложно, если оно велико и
+ противоречиво, когда одна часть приветствуется, а другая не совсем.
+
+* Ссылки на разделы руководства оформляйте на отдельных строках:
+```
+
+Пишите комментарии по-английски.
+[[ссылка](#english-comments)]
+```
+
+* Проделайте запланированную работу по исправлению ошибок или переводу в
+ созданной тематической ветке. Прокомментируйте вашу работу при добавлении.
+
+* Загрузите вашу ветку на GitHub.
+
+* Отправье нам [запрос на слияние][pull request], добавьте комментарий к нему.
+
+[fork]: https://help.github.com/articles/fork-a-repo
+[pull request]: https://help.github.com/articles/using-pull-requests
+[issues]: https://help.github.com/articles/about-issues
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
new file mode 100644
index 000000000..e45808056
--- /dev/null
+++ b/CONTRIBUTORS.md
@@ -0,0 +1,4 @@
+# Many thanks to those guys:
+* [@piton4eg](https://github.com/piton4eg)
+* [@constXife](https://github.com/constXife)
+* [@Zloy](https://github.com/Zloy)
diff --git a/README-deDE.md b/README-deDE.md
new file mode 100644
index 000000000..0d136522d
--- /dev/null
+++ b/README-deDE.md
@@ -0,0 +1,4 @@
+# The Ruby Style Guide: German Edition
+
+The resource moved to a separate repository:
+https://github.com/arbox/de-ruby-style-guide/blob/master/README-deDE.md
diff --git a/README-enUS.md b/README-enUS.md
new file mode 100644
index 000000000..b3f7b9157
--- /dev/null
+++ b/README-enUS.md
@@ -0,0 +1,3653 @@
+# Prelude
+
+> Role models are important.
+> -- Officer Alex J. Murphy / RoboCop
+
+One thing has always bothered me as a Ruby developer - Python developers have a
+great programming style reference
+([PEP-8][]) and we never got an official
+guide, documenting Ruby coding style and best practices. And I do believe that
+style matters. I also believe that a great hacker community, such as Ruby has,
+should be quite capable of producing this coveted document.
+
+This guide started its life as our internal company Ruby coding guidelines
+(written by yours truly). At some point I decided that the work I was doing
+might be interesting to members of the Ruby community in general and that the
+world had little need for another internal company guideline. But the world
+could certainly benefit from a community-driven and community-sanctioned set of
+practices, idioms and style prescriptions for Ruby programming.
+
+Since the inception of the guide I've received a lot of feedback from members of
+the exceptional Ruby community around the world. Thanks for all the suggestions
+and the support! Together we can make a resource beneficial to each and every
+Ruby developer out there.
+
+By the way, if you're into Rails you might want to check out the complementary
+[Ruby on Rails Style Guide][rails-style-guide].
+
+# The Ruby Style Guide
+
+This Ruby style guide recommends best practices so that real-world Ruby
+programmers can write code that can be maintained by other real-world Ruby
+programmers. A style guide that reflects real-world usage gets used, and a style
+guide that holds to an ideal that has been rejected by the people it is supposed
+to help risks not getting used at all – no matter how good it is.
+
+The guide is separated into several sections of related rules. I've tried to add
+the rationale behind the rules (if it's omitted I've assumed it's pretty
+obvious).
+
+I didn't come up with all the rules out of nowhere - they are mostly
+based on my extensive career as a professional software engineer,
+feedback and suggestions from members of the Ruby community and
+various highly regarded Ruby programming resources, such as
+["Programming Ruby 1.9"][pickaxe] and
+["The Ruby Programming Language"][trpl].
+
+There are some areas in which there is no clear consensus in the Ruby community
+regarding a particular style (like string literal quoting, spacing inside hash
+literals, dot position in multi-line method chaining, etc.). In such scenarios
+all popular styles are acknowledged and it's up to you to pick one and apply it
+consistently.
+
+This style guide evolves over time as additional conventions are
+identified and past conventions are rendered obsolete by changes in
+Ruby itself.
+
+Many projects have their own coding style guidelines (often derived
+from this guide). In the event of any conflicts, such
+project-specific guides take precedence for that project.
+
+You can generate a PDF or an HTML copy of this guide using
+[Transmuter][].
+
+[RuboCop][] is a code analyzer, based on this
+style guide.
+
+Translations of the guide are available in the following languages:
+
+* [Chinese Simplified](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
+* [Chinese Traditional](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
+* [French](https://github.com/porecreat/ruby-style-guide/blob/master/README-frFR.md)
+* [German](https://github.com/arbox/ruby-style-guide/blob/master/README-deDE.md)
+* [Japanese](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
+* [Korean](https://github.com/dalzony/ruby-style-guide/blob/master/README-koKR.md)
+* [Portuguese](https://github.com/rubensmabueno/ruby-style-guide/blob/master/README-PT-BR.md)
+* [Russian](https://github.com/arbox/ruby-style-guide/blob/master/README-ruRU.md)
+* [Spanish](https://github.com/alemohamad/ruby-style-guide/blob/master/README-esLA.md)
+* [Vietnamese](https://github.com/scrum2b/ruby-style-guide/blob/master/README-viVN.md)
+
+## Table of Contents
+
+* [Source Code Layout](#source-code-layout)
+* [Syntax](#syntax)
+* [Naming](#naming)
+* [Comments](#comments)
+ * [Comment Annotations](#comment-annotations)
+* [Classes](#classes--modules)
+* [Exceptions](#exceptions)
+* [Collections](#collections)
+* [Strings](#strings)
+* [Regular Expressions](#regular-expressions)
+* [Percent Literals](#percent-literals)
+* [Metaprogramming](#metaprogramming)
+* [Misc](#misc)
+* [Tools](#tools)
+
+## Source Code Layout
+
+> Nearly everybody is convinced that every style but their own is
+> ugly and unreadable. Leave out the "but their own" and they're
+> probably right...
+> -- Jerry Coffin (on indentation)
+
+*
+ Use `UTF-8` as the source file encoding.
+[[link](#utf-8)]
+
+*
+ Use two **spaces** per indentation level (aka soft tabs). No hard tabs.
+[[link](#spaces-indentation)]
+
+ ```Ruby
+ # bad - four spaces
+ def some_method
+ do_something
+ end
+
+ # good
+ def some_method
+ do_something
+ end
+ ```
+
+*
+ Use Unix-style line endings. (*BSD/Solaris/Linux/OS X users are covered by
+ default, Windows users have to be extra careful.)
+[[link](#crlf)]
+
+ * If you're using Git you might want to add the following
+ configuration setting to protect your project from Windows line
+ endings creeping in:
+
+ ```bash
+ $ git config --global core.autocrlf true
+ ```
+
+*
+ Don't use `;` to separate statements and expressions. As a corollary - use one
+ expression per line.
+[[link](#no-semicolon)]
+
+ ```Ruby
+ # bad
+ puts 'foobar'; # superfluous semicolon
+
+ puts 'foo'; puts 'bar' # two expressions on the same line
+
+ # good
+ puts 'foobar'
+
+ puts 'foo'
+ puts 'bar'
+
+ puts 'foo', 'bar' # this applies to puts in particular
+ ```
+
+*
+ Prefer a single-line format for class definitions with no body.
+[[link](#single-line-classes)]
+
+ ```Ruby
+ # bad
+ class FooError < StandardError
+ end
+
+ # okish
+ class FooError < StandardError; end
+
+ # good
+ FooError = Class.new(StandardError)
+ ```
+
+*
+ Avoid single-line methods. Although they are somewhat popular in the wild,
+ there are a few peculiarities about their definition syntax that make their
+ use undesirable. At any rate - there should be no more than one expression in
+ a single-line method.
+[[link](#no-single-line-methods)]
+
+ ```Ruby
+ # bad
+ def too_much; something; something_else; end
+
+ # okish - notice that the first ; is required
+ def no_braces_method; body end
+
+ # okish - notice that the second ; is optional
+ def no_braces_method; body; end
+
+ # okish - valid syntax, but no ; makes it kind of hard to read
+ def some_method() body end
+
+ # good
+ def some_method
+ body
+ end
+ ```
+
+ One exception to the rule are empty-body methods.
+
+ ```Ruby
+ # good
+ def no_op; end
+ ```
+
+*
+ Use spaces around operators, after commas, colons and semicolons, around `{`
+ and before `}`. Whitespace might be (mostly) irrelevant to the Ruby
+ interpreter, but its proper use is the key to writing easily readable code.
+[[link](#spaces-operators)]
+
+ ```Ruby
+ sum = 1 + 2
+ a, b = 1, 2
+ [1, 2, 3].each { |e| puts e }
+ class FooError < StandardError; end
+ ```
+
+ The only exception, regarding operators, is the exponent operator:
+
+ ```Ruby
+ # bad
+ e = M * c ** 2
+
+ # good
+ e = M * c**2
+ ```
+
+ `{` and `}` deserve a bit of clarification, since they are used
+ for block and hash literals, as well as string interpolation.
+ For hash literals two styles are considered acceptable.
+
+ ```Ruby
+ # good - space after { and before }
+ { one: 1, two: 2 }
+
+ # good - no space after { and before }
+ {one: 1, two: 2}
+ ```
+
+ The first variant is slightly more readable (and arguably more
+ popular in the Ruby community in general). The second variant has
+ the advantage of adding visual difference between block and hash
+ literals. Whichever one you pick - apply it consistently.
+
+*
+ No spaces after `(`, `[` or before `]`, `)`.
+[[link](#no-spaces-braces)]
+
+ ```Ruby
+ some(arg).other
+ [1, 2, 3].size
+ ```
+
+*
+ No space after `!`.
+[[link](#no-space-bang)]
+
+ ```Ruby
+ # bad
+ ! something
+
+ # good
+ !something
+ ```
+
+*
+ No space inside range literals.
+[[link](#no-space-inside-range-literals)]
+
+ ```Ruby
+ # bad
+ 1 .. 3
+ 'a' ... 'z'
+
+ # good
+ 1..3
+ 'a'...'z'
+ ```
+
+*
+ Indent `when` as deep as `case`. I know that many would disagree
+ with this one, but it's the style established in both "The Ruby
+ Programming Language" and "Programming Ruby".
+[[link](#indent-when-to-case)]
+
+ ```Ruby
+ # bad
+ 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
+
+ # good
+ 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
+ ```
+
+*
+ When assigning the result of a conditional expression to a variable,
+ preserve the usual alignment of its branches.
+[[link](#indent-conditional-assignment)]
+
+ ```Ruby
+ # bad - pretty convoluted
+ 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
+
+ result = if some_cond
+ calc_something
+ else
+ calc_something_else
+ end
+
+ # good - it's apparent what's going on
+ 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
+
+ result = if some_cond
+ calc_something
+ else
+ calc_something_else
+ end
+
+ # good (and a bit more width efficient)
+ 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
+
+ result =
+ if some_cond
+ calc_something
+ else
+ calc_something_else
+ end
+ ```
+
+*
+ Use empty lines between method definitions and also to break up a method
+ into logical paragraphs internally.
+[[link](#empty-lines-between-methods)]
+
+ ```Ruby
+ def some_method
+ data = initialize(options)
+
+ data.manipulate!
+
+ data.result
+ end
+
+ def some_method
+ result
+ end
+ ```
+
+*
+ Avoid comma after the last parameter in a method call, especially when the
+ parameters are not on separate lines.
+[[link](#no-trailing-params-comma)]
+
+ ```Ruby
+ # bad - easier to move/add/remove parameters, but still not preferred
+ some_method(
+ size,
+ count,
+ color,
+ )
+
+ # bad
+ some_method(size, count, color, )
+
+ # good
+ some_method(size, count, color)
+ ```
+
+*
+ Use spaces around the `=` operator when assigning default values to method
+ parameters:
+[[link](#spaces-around-equals)]
+
+ ```Ruby
+ # bad
+ def some_method(arg1=:default, arg2=nil, arg3=[])
+ # do something...
+ end
+
+ # good
+ def some_method(arg1 = :default, arg2 = nil, arg3 = [])
+ # do something...
+ end
+ ```
+
+ While several Ruby books suggest the first style, the second is much more
+ prominent in practice (and arguably a bit more readable).
+
+*
+ Avoid line continuation `\` where not required. In practice, avoid using
+ line continuations for anything but string concatenation.
+[[link](#no-trailing-backslash)]
+
+ ```Ruby
+ # bad
+ result = 1 - \
+ 2
+
+ # good (but still ugly as hell)
+ result = 1 \
+ - 2
+
+ long_string = 'First part of the long string' \
+ ' and second part of the long string'
+ ```
+
+*
+ Adopt a consistent multi-line method chaining style. There are two
+ popular styles in the Ruby community, both of which are considered
+ good - leading `.` (Option A) and trailing `.` (Option B).
+[[link](#consistent-multi-line-chains)]
+
+ * **(Option A)** When continuing a chained method invocation on
+ another line keep the `.` on the second line.
+
+ ```Ruby
+ # bad - need to consult first line to understand second line
+ one.two.three.
+ four
+
+ # good - it's immediately clear what's going on the second line
+ one.two.three
+ .four
+ ```
+
+ * **(Option B)** When continuing a chained method invocation on another line,
+ include the `.` on the first line to indicate that the
+ expression continues.
+
+ ```Ruby
+ # bad - need to read ahead to the second line to know that the chain continues
+ one.two.three
+ .four
+
+ # good - it's immediately clear that the expression continues beyond the first line
+ one.two.three.
+ four
+ ```
+
+ A discussion on the merits of both alternative styles can be found
+ [here](https://github.com/bbatsov/ruby-style-guide/pull/176).
+
+*
+ Align the parameters of a method call if they span more than one
+ line. When aligning parameters is not appropriate due to line-length
+ constraints, single indent for the lines after the first is also
+ acceptable.
+[[link](#no-double-indent)]
+
+ ```Ruby
+ # starting point (line is too long)
+ def send_mail(source)
+ Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
+ end
+
+ # bad (double indent)
+ def send_mail(source)
+ Mailer.deliver(
+ to: 'bob@example.com',
+ from: 'us@example.com',
+ subject: 'Important message',
+ body: source.text)
+ end
+
+ # good
+ def send_mail(source)
+ Mailer.deliver(to: 'bob@example.com',
+ from: 'us@example.com',
+ subject: 'Important message',
+ body: source.text)
+ end
+
+ # good (normal indent)
+ def send_mail(source)
+ Mailer.deliver(
+ to: 'bob@example.com',
+ from: 'us@example.com',
+ subject: 'Important message',
+ body: source.text
+ )
+ end
+ ```
+
+*
+ Align the elements of array literals spanning multiple lines.
+[[link](#align-multiline-arrays)]
+
+ ```Ruby
+ # bad - single indent
+ menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
+ 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
+
+ # good
+ menu_item = [
+ 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
+ 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam'
+ ]
+
+ # good
+ menu_item =
+ ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
+ 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
+ ```
+
+*
+ Add underscores to large numeric literals to improve their readability.
+[[link](#underscores-in-numerics)]
+
+ ```Ruby
+ # bad - how many 0s are there?
+ num = 1000000
+
+ # good - much easier to parse for the human brain
+ num = 1_000_000
+ ```
+
+*
+ Use RDoc and its conventions for API documentation. Don't put an
+ empty line between the comment block and the `def`.
+[[link](#rdoc-conventions)]
+
+*
+ Limit lines to 80 characters.
+[[link](#80-character-limits)]
+
+*
+ Avoid trailing whitespace.
+[[link](#no-trailing-whitespace)]
+
+*
+ End each file with a newline.
+[[link](#newline-eof)]
+
+*
+ Don't use block comments. They cannot be preceded by whitespace and are not
+ as easy to spot as regular comments.
+[[link](#no-block-comments)]
+
+ ```Ruby
+ # bad
+ =begin
+ comment line
+ another comment line
+ =end
+
+ # good
+ # comment line
+ # another comment line
+ ```
+
+## Syntax
+
+*
+ Use `::` only to reference constants(this includes classes and
+ modules) and constructors (like `Array()` or `Nokogiri::HTML()`).
+ Do not use `::` for regular method invocation.
+[[link](#double-colons)]
+
+ ```Ruby
+ # bad
+ SomeClass::some_method
+ some_object::some_method
+
+ # good
+ SomeClass.some_method
+ some_object.some_method
+ SomeModule::SomeClass::SOME_CONST
+ SomeModule::SomeClass()
+ ```
+
+*
+ Use `def` with parentheses when there are parameters. Omit the
+ parentheses when the method doesn't accept any parameters.
+[[link](#method-parens)]
+
+ ```Ruby
+ # bad
+ def some_method()
+ # body omitted
+ end
+
+ # good
+ def some_method
+ # body omitted
+ end
+
+ # bad
+ def some_method_with_parameters param1, param2
+ # body omitted
+ end
+
+ # good
+ def some_method_with_parameters(param1, param2)
+ # body omitted
+ end
+ ```
+
+*
+ Do not use `for`, unless you know exactly why. Most of the time iterators
+ should be used instead. `for` is implemented in terms of `each` (so
+ you're adding a level of indirection), but with a twist - `for`
+ doesn't introduce a new scope (unlike `each`) and variables defined
+ in its block will be visible outside it.
+[[link](#no-for-loops)]
+
+ ```Ruby
+ arr = [1, 2, 3]
+
+ # bad
+ for elem in arr do
+ puts elem
+ end
+
+ # note that elem is accessible outside of the for loop
+ elem # => 3
+
+ # good
+ arr.each { |elem| puts elem }
+
+ # elem is not accessible outside each's block
+ elem # => NameError: undefined local variable or method `elem'
+ ```
+
+*
+ Do not use `then` for multi-line `if/unless`.
+[[link](#no-then)]
+
+ ```Ruby
+ # bad
+ if some_condition then
+ # body omitted
+ end
+
+ # good
+ if some_condition
+ # body omitted
+ end
+ ```
+
+*
+ Always put the condition on the same line as the `if`/`unless` in a
+ multi-line conditional.
+[[link](#same-line-condition)]
+
+ ```Ruby
+ # bad
+ if
+ some_condition
+ do_something
+ do_something_else
+ end
+
+ # good
+ if some_condition
+ do_something
+ do_something_else
+ end
+ ```
+
+*
+ Favor the ternary operator(`?:`) over `if/then/else/end` constructs.
+ It's more common and obviously more concise.
+[[link](#ternary-operator)]
+
+ ```Ruby
+ # bad
+ result = if some_condition then something else something_else end
+
+ # good
+ result = some_condition ? something : something_else
+ ```
+
+*
+ Use one expression per branch in a ternary operator. This
+ also means that ternary operators must not be nested. Prefer
+ `if/else` constructs in these cases.
+[[link](#no-nested-ternary)]
+
+ ```Ruby
+ # 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
+ ```
+
+*
+ Do not use `if x; ...`. Use the ternary
+ operator instead.
+[[link](#no-semicolon-ifs)]
+
+ ```Ruby
+ # bad
+ result = if some_condition; something else something_else end
+
+ # good
+ result = some_condition ? something : something_else
+ ```
+
+*
+ Leverage the fact that `if` and `case` are expressions which return a
+ result.
+[[link](#use-if-case-returns)]
+
+ ```Ruby
+ # bad
+ if condition
+ result = x
+ else
+ result = y
+ end
+
+ # good
+ result =
+ if condition
+ x
+ else
+ y
+ end
+ ```
+
+*
+ Use `when x then ...` for one-line cases. The alternative syntax `when x:
+ ...` has been removed as of Ruby 1.9.
+[[link](#one-line-cases)]
+
+*
+ Do not use `when x; ...`. See the previous rule.
+[[link](#no-when-semicolons)]
+
+*
+ Use `!` instead of `not`.
+[[link](#bang-not-not)]
+
+ ```Ruby
+ # bad - braces are required because of op precedence
+ x = (not something)
+
+ # good
+ x = !something
+ ```
+
+*
+ Avoid the use of `!!`.
+[[link](#no-bang-bang)]
+
+ ```Ruby
+ # bad
+ x = 'test'
+ # obscure nil check
+ if !!x
+ # body omitted
+ end
+
+ x = false
+ # double negation is useless on booleans
+ !!x # => false
+
+ # good
+ x = 'test'
+ unless x.nil?
+ # body omitted
+ end
+ ```
+
+*
+ The `and` and `or` keywords are banned. It's just not worth it. Always use
+ `&&` and `||` instead.
+[[link](#no-and-or-or)]
+
+ ```Ruby
+ # bad
+ # boolean expression
+ if some_condition and some_other_condition
+ do_something
+ end
+
+ # control flow
+ document.saved? or document.save!
+
+ # good
+ # boolean expression
+ if some_condition && some_other_condition
+ do_something
+ end
+
+ # control flow
+ document.saved? || document.save!
+ ```
+
+*
+ Avoid multi-line `?:` (the ternary operator); use `if/unless` instead.
+[[link](#no-multiline-ternary)]
+
+*
+ Favor modifier `if/unless` usage when you have a single-line body. Another
+ good alternative is the usage of control flow `&&/||`.
+[[link](#if-as-a-modifier)]
+
+ ```Ruby
+ # bad
+ if some_condition
+ do_something
+ end
+
+ # good
+ do_something if some_condition
+
+ # another good option
+ some_condition && do_something
+ ```
+
+*
+ Avoid modifier `if/unless` usage at the end of a non-trivial multi-line
+ block.
+[[link](#no-multiline-if-modifiers)]
+
+ ```Ruby
+ # bad
+ 10.times do
+ # multi-line body omitted
+ end if some_condition
+
+ # good
+ if some_condition
+ 10.times do
+ # multi-line body omitted
+ end
+ end
+ ```
+
+*
+ Favor `unless` over `if` for negative conditions (or control flow `||`).
+[[link](#unless-for-negatives)]
+
+ ```Ruby
+ # bad
+ do_something if !some_condition
+
+ # bad
+ do_something if not some_condition
+
+ # good
+ do_something unless some_condition
+
+ # another good option
+ some_condition || do_something
+ ```
+
+*
+ Do not use `unless` with `else`. Rewrite these with the positive case first.
+[[link](#no-else-with-unless)]
+
+ ```Ruby
+ # bad
+ unless success?
+ puts 'failure'
+ else
+ puts 'success'
+ end
+
+ # good
+ if success?
+ puts 'success'
+ else
+ puts 'failure'
+ end
+ ```
+
+*
+ Don't use parentheses around the condition of an `if/unless/while/until`.
+[[link](#no-parens-if)]
+
+ ```Ruby
+ # bad
+ if (x > 10)
+ # body omitted
+ end
+
+ # good
+ if x > 10
+ # body omitted
+ end
+ ```
+
+Note that there is an exception to this rule, namely [safe assignment in
+condition](#safe-assignment-in-condition).
+
+*
+ Do not use `while/until condition do` for multi-line `while/until`.
+[[link](#no-multiline-while-do)]
+
+ ```Ruby
+ # bad
+ while x > 5 do
+ # body omitted
+ end
+
+ until x > 5 do
+ # body omitted
+ end
+
+ # good
+ while x > 5
+ # body omitted
+ end
+
+ until x > 5
+ # body omitted
+ end
+ ```
+
+*
+ Favor modifier `while/until` usage when you have a single-line body.
+[[link](#while-as-a-modifier)]
+
+ ```Ruby
+ # bad
+ while some_condition
+ do_something
+ end
+
+ # good
+ do_something while some_condition
+ ```
+
+*
+ Favor `until` over `while` for negative conditions.
+[[link](#until-for-negatives)]
+
+ ```Ruby
+ # bad
+ do_something while !some_condition
+
+ # good
+ do_something until some_condition
+ ```
+
+*
+ Use `Kernel#loop` instead of `while/until` when you need an infinite loop.
+[[link](#infinite-loop)]
+
+ ```ruby
+ # bad
+ while true
+ do_something
+ end
+
+ until false
+ do_something
+ end
+
+ # good
+ loop do
+ do_something
+ end
+ ```
+
+*
+ Use `Kernel#loop` with `break` rather than `begin/end/until` or
+ `begin/end/while` for post-loop tests.
+[[link](#loop-with-break)]
+
+ ```Ruby
+ # bad
+ begin
+ puts val
+ val += 1
+ end while val < 0
+
+ # good
+ loop do
+ puts val
+ val += 1
+ break unless val < 0
+ end
+ ```
+
+*
+ Omit parentheses around parameters for methods that are part of an internal
+ DSL (e.g. Rake, Rails, RSpec), methods that have "keyword" status in Ruby
+ (e.g. `attr_reader`, `puts`) and attribute access methods. Use parentheses
+ around the arguments of all other method invocations.
+[[link](#no-dsl-parens)]
+
+ ```Ruby
+ class Person
+ attr_reader :name, :age
+
+ # omitted
+ end
+
+ temperance = Person.new('Temperance', 30)
+ temperance.name
+
+ puts temperance.age
+
+ x = Math.sin(y)
+ array.delete(e)
+
+ bowling.score.should == 0
+ ```
+
+*
+ Omit the outer braces around an implicit options hash.
+[[link](#no-braces-opts-hash)]
+
+ ```Ruby
+ # bad
+ user.set({ name: 'John', age: 45, permissions: { read: true } })
+
+ # good
+ user.set(name: 'John', age: 45, permissions: { read: true })
+ ```
+
+*
+ Omit both the outer braces and parentheses for methods that are part of an
+ internal DSL.
+[[link](#no-dsl-decorating)]
+
+ ```Ruby
+ class Person < ActiveRecord::Base
+ # bad
+ validates(:name, { presence: true, length: { within: 1..10 } })
+
+ # good
+ validates :name, presence: true, length: { within: 1..10 }
+ end
+ ```
+
+*
+ Omit parentheses for method calls with no arguments.
+[[link](#no-args-no-parens)]
+
+ ```Ruby
+ # bad
+ Kernel.exit!()
+ 2.even?()
+ fork()
+ 'test'.upcase()
+
+ # good
+ Kernel.exit!
+ 2.even?
+ fork
+ 'test'.upcase
+ ```
+
+*
+ Use the proc invocation shorthand when the invoked method is the only operation of a block.
+[[link](#single-action-blocks)]
+
+ ```Ruby
+ # bad
+ names.map { |name| name.upcase }
+
+ # good
+ names.map(&:upcase)
+ ```
+
+*
+ Prefer `{...}` over `do...end` for single-line blocks. Avoid using `{...}`
+ for multi-line blocks (multiline chaining is always ugly). Always use
+ `do...end` for "control flow" and "method definitions" (e.g. in Rakefiles and
+ certain DSLs). Avoid `do...end` when chaining.
+[[link](#single-line-blocks)]
+
+ ```Ruby
+ names = %w(Bozhidar Steve Sarah)
+
+ # bad
+ names.each do |name|
+ puts name
+ end
+
+ # good
+ names.each { |name| puts name }
+
+ # bad
+ names.select do |name|
+ name.start_with?('S')
+ end.map { |name| name.upcase }
+
+ # good
+ names.select { |name| name.start_with?('S') }.map(&:upcase)
+ ```
+
+ Some will argue that multiline chaining would look OK with the use of {...},
+ but they should ask themselves - is this code really readable and can the
+ blocks' contents be extracted into nifty methods?
+
+*
+ Consider using explicit block argument to avoid writing block literal that
+ just passes its arguments to another block. Beware of the performance impact,
+ though, as the block gets converted to a Proc.
+[[link](#block-argument)]
+
+ ```Ruby
+ require 'tempfile'
+
+ # bad
+ def with_tmp_dir
+ Dir.mktmpdir do |tmp_dir|
+ Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments
+ end
+ end
+
+ # good
+ def with_tmp_dir(&block)
+ Dir.mktmpdir do |tmp_dir|
+ Dir.chdir(tmp_dir, &block)
+ end
+ end
+
+ with_tmp_dir do |dir|
+ puts "dir is accessible as a parameter and pwd is set: #{dir}"
+ end
+ ```
+
+*
+ Avoid `return` where not required for flow of control.
+[[link](#no-explicit-return)]
+
+ ```Ruby
+ # bad
+ def some_method(some_arr)
+ return some_arr.size
+ end
+
+ # good
+ def some_method(some_arr)
+ some_arr.size
+ end
+ ```
+
+*
+ Avoid `self` where not required. (It is only required when calling a self
+ write accessor.)
+[[link](#no-self-unless-required)]
+
+ ```Ruby
+ # bad
+ def ready?
+ if self.last_reviewed_at > self.last_updated_at
+ self.worker.update(self.content, self.options)
+ self.status = :in_progress
+ end
+ self.status == :verified
+ end
+
+ # good
+ def ready?
+ if last_reviewed_at > last_updated_at
+ worker.update(content, options)
+ self.status = :in_progress
+ end
+ status == :verified
+ end
+ ```
+
+*
+ As a corollary, avoid shadowing methods with local variables unless they are
+ both equivalent.
+[[link](#no-shadowing)]
+
+ ```Ruby
+ class Foo
+ attr_accessor :options
+
+ # ok
+ def initialize(options)
+ self.options = options
+ # both options and self.options are equivalent here
+ end
+
+ # bad
+ def do_something(options = {})
+ unless options[:when] == :later
+ output(self.options[:message])
+ end
+ end
+
+ # good
+ def do_something(params = {})
+ unless params[:when] == :later
+ output(options[:message])
+ end
+ end
+ end
+ ```
+
+*
+ Don't use the return value of `=` (an assignment) in conditional expressions
+ unless the assignment is wrapped in parentheses. This is a fairly popular
+ idiom among Rubyists that's sometimes referred to as *safe assignment in
+ condition*.
+[[link](#safe-assignment-in-condition)]
+
+ ```Ruby
+ # bad (+ a warning)
+ if v = array.grep(/foo/)
+ do_something(v)
+ ...
+ end
+
+ # good (MRI would still complain, but RuboCop won't)
+ if (v = array.grep(/foo/))
+ do_something(v)
+ ...
+ end
+
+ # good
+ v = array.grep(/foo/)
+ if v
+ do_something(v)
+ ...
+ end
+ ```
+
+*
+ Use shorthand self assignment operators whenever applicable.
+[[link](#self-assignment)]
+
+ ```Ruby
+ # bad
+ x = x + y
+ x = x * y
+ x = x**y
+ x = x / y
+ x = x || y
+ x = x && y
+
+ # good
+ x += y
+ x *= y
+ x **= y
+ x /= y
+ x ||= y
+ x &&= y
+ ```
+
+*
+ Use `||=` to initialize variables only if they're not already initialized.
+[[link](#double-pipe-for-uninit)]
+
+ ```Ruby
+ # bad
+ name = name ? name : 'Bozhidar'
+
+ # bad
+ name = 'Bozhidar' unless name
+
+ # good - set name to Bozhidar, only if it's nil or false
+ name ||= 'Bozhidar'
+ ```
+
+*
+ Don't use `||=` to initialize boolean variables. (Consider what would happen
+ if the current value happened to be `false`.)
+[[link](#no-double-pipes-for-bools)]
+
+ ```Ruby
+ # bad - would set enabled to true even if it was false
+ enabled ||= true
+
+ # good
+ enabled = true if enabled.nil?
+ ```
+
+*
+ Use `&&=` to preprocess variables that may or may not exist. Using `&&=`
+ will change the value only if it exists, removing the need to check its
+ existence with `if`.
+[[link](#double-amper-preprocess)]
+
+ ```Ruby
+ # bad
+ if something
+ something = something.downcase
+ end
+
+ # bad
+ something = something ? something.downcase : nil
+
+ # ok
+ something = something.downcase if something
+
+ # good
+ something = something && something.downcase
+
+ # better
+ something &&= something.downcase
+ ```
+
+*
+ Avoid explicit use of the case equality operator `===`. As its name implies
+ it is meant to be used implicitly by `case` expressions and outside of them it
+ yields some pretty confusing code.
+[[link](#no-case-equality)]
+
+ ```Ruby
+ # bad
+ Array === something
+ (1..100) === 7
+ /something/ === some_string
+
+ # good
+ something.is_a?(Array)
+ (1..100).include?(7)
+ some_string =~ /something/
+ ```
+
+*
+ Do not use `eql?` when using `==` will do. The stricter comparison semantics
+ provided by `eql?` are rarely needed in practice.
+[[link](#eql)]
+
+ ```Ruby
+ # bad - eql? is the same as == for strings
+ "ruby".eql? some_str
+
+ # good
+ "ruby" == some_str
+ 1.0.eql? x # eql? makes sense here if want to differentiate between Fixnum and Float 1
+ ```
+
+*
+ Avoid using Perl-style special variables (like `$:`, `$;`, etc. ). They are
+ quite cryptic and their use in anything but one-liner scripts is discouraged.
+ Use the human-friendly aliases provided by the `English` library.
+[[link](#no-cryptic-perlisms)]
+
+ ```Ruby
+ # bad
+ $:.unshift File.dirname(__FILE__)
+
+ # good
+ require 'English'
+ $LOAD_PATH.unshift File.dirname(__FILE__)
+ ```
+
+*
+ Do not put a space between a method name and the opening parenthesis.
+[[link](#parens-no-spaces)]
+
+ ```Ruby
+ # bad
+ f (3 + 2) + 1
+
+ # good
+ f(3 + 2) + 1
+ ```
+
+*
+ If the first argument to a method begins with an open parenthesis, always
+ use parentheses in the method invocation. For example, write `f((3 + 2) + 1)`.
+[[link](#parens-as-args)]
+
+*
+ Always run the Ruby interpreter with the `-w` option so it will warn you if
+ you forget either of the rules above!
+[[link](#always-warn-at-runtime)]
+
+*
+ Do not use nested method definitions, use lambda instead.
+ Nested method definitions actually produce methods in the same scope
+ (e.g. class) as the outer method. Furthermore, the "nested method" will be
+ redefined every time the method containing its definition is invoked.
+[[link](#no-nested-methods)]
+
+ ```Ruby
+ # bad
+ def foo(x)
+ def bar(y)
+ # body omitted
+ end
+
+ bar(x)
+ end
+
+ # good - the same as the previous, but no bar redefinition on every foo call
+ def bar(y)
+ # body omitted
+ end
+
+ def foo(x)
+ bar(x)
+ end
+
+ # also good
+ def foo(x)
+ bar = ->(y) { ... }
+ bar.call(x)
+ end
+ ```
+
+*
+ Use the new lambda literal syntax for single line body blocks. Use the
+ `lambda` method for multi-line blocks.
+[[link](#lambda-multi-line)]
+
+ ```Ruby
+ # bad
+ l = lambda { |a, b| a + b }
+ l.call(1, 2)
+
+ # correct, but looks extremely awkward
+ l = ->(a, b) do
+ tmp = a * 7
+ tmp * b / 50
+ end
+
+ # good
+ l = ->(a, b) { a + b }
+ l.call(1, 2)
+
+ l = lambda do |a, b|
+ tmp = a * 7
+ tmp * b / 50
+ end
+ ```
+
+*
+ Prefer `proc` over `Proc.new`.
+[[link](#proc)]
+
+ ```Ruby
+ # bad
+ p = Proc.new { |n| puts n }
+
+ # good
+ p = proc { |n| puts n }
+ ```
+
+*
+ Prefer `proc.call()` over `proc[]` or `proc.()` for both lambdas and procs.
+[[link](#proc-call)]
+
+ ```Ruby
+ # bad - looks similar to Enumeration access
+ l = ->(v) { puts v }
+ l[1]
+
+ # also bad - uncommon syntax
+ l = ->(v) { puts v }
+ l.(1)
+
+ # good
+ l = ->(v) { puts v }
+ l.call(1)
+ ```
+
+*
+ Prefix with `_` unused block parameters and local variables. It's also
+ acceptable to use just `_` (although it's a bit less descriptive). This
+ convention is recognized by the Ruby interpreter and tools like RuboCop and
+ will suppress their unused variable warnings.
+[[link](#underscore-unused-vars)]
+
+ ```Ruby
+ # bad
+ result = hash.map { |k, v| v + 1 }
+
+ def something(x)
+ unused_var, used_var = something_else(x)
+ # ...
+ end
+
+ # good
+ result = hash.map { |_k, v| v + 1 }
+
+ def something(x)
+ _unused_var, used_var = something_else(x)
+ # ...
+ end
+
+ # good
+ result = hash.map { |_, v| v + 1 }
+
+ def something(x)
+ _, used_var = something_else(x)
+ # ...
+ end
+ ```
+
+*
+ Use `$stdout/$stderr/$stdin` instead of `STDOUT/STDERR/STDIN`.
+ `STDOUT/STDERR/STDIN` are constants, and while you can actually reassign
+ (possibly to redirect some stream) constants in Ruby, you'll get an
+ interpreter warning if you do so.
+[[link](#global-stdout)]
+
+*
+ Use `warn` instead of `$stderr.puts`. Apart from being more concise and
+ clear, `warn` allows you to suppress warnings if you need to (by setting the
+ warn level to 0 via `-W0`).
+[[link](#warn)]
+
+*
+ Favor the use of `sprintf` and its alias `format` over the fairly cryptic
+ `String#%` method.
+[[link](#sprintf)]
+
+ ```Ruby
+ # bad
+ '%d %d' % [20, 10]
+ # => '20 10'
+
+ # good
+ sprintf('%d %d', 20, 10)
+ # => '20 10'
+
+ # good
+ sprintf('%{first} %{second}', first: 20, second: 10)
+ # => '20 10'
+
+ format('%d %d', 20, 10)
+ # => '20 10'
+
+ # good
+ format('%{first} %{second}', first: 20, second: 10)
+ # => '20 10'
+ ```
+
+*
+ Favor the use of `Array#join` over the fairly cryptic `Array#*` with
+[[link](#array-join)]
+ a string argument.
+
+ ```Ruby
+ # bad
+ %w(one two three) * ', '
+ # => 'one, two, three'
+
+ # good
+ %w(one two three).join(', ')
+ # => 'one, two, three'
+ ```
+
+*
+ Use `[*var]` or `Array()` instead of explicit `Array` check, when dealing
+ with a variable you want to treat as an Array, but you're not certain it's an
+ array.
+[[link](#splat-arrays)]
+
+ ```Ruby
+ # bad
+ paths = [paths] unless paths.is_a? Array
+ paths.each { |path| do_something(path) }
+
+ # good
+ [*paths].each { |path| do_something(path) }
+
+ # good (and a bit more readable)
+ Array(paths).each { |path| do_something(path) }
+ ```
+
+*
+ Use ranges or `Comparable#between?` instead of complex comparison logic when
+ possible.
+[[link](#ranges-or-between)]
+
+ ```Ruby
+ # bad
+ do_something if x >= 1000 && x <= 2000
+
+ # good
+ do_something if (1000..2000).include?(x)
+
+ # good
+ do_something if x.between?(1000, 2000)
+ ```
+
+*
+ Favor the use of predicate methods to explicit comparisons with `==`.
+ Numeric comparisons are OK.
+[[link](#predicate-methods)]
+
+ ```Ruby
+ # bad
+ if x % 2 == 0
+ end
+
+ if x % 2 == 1
+ end
+
+ if x == nil
+ end
+
+ # good
+ if x.even?
+ end
+
+ if x.odd?
+ end
+
+ if x.nil?
+ end
+
+ if x.zero?
+ end
+
+ if x == 0
+ end
+ ```
+
+*
+ Don't do explicit non-`nil` checks unless you're dealing with boolean
+ values.
+[[link](#no-non-nil-checks)]
+
+ ```ruby
+ # bad
+ do_something if !something.nil?
+ do_something if something != nil
+
+ # good
+ do_something if something
+
+ # good - dealing with a boolean
+ def value_set?
+ !@some_boolean.nil?
+ end
+ ```
+
+*
+ Avoid the use of `BEGIN` blocks.
+[[link](#no-BEGIN-blocks)]
+
+*
+ Do not use `END` blocks. Use `Kernel#at_exit` instead.
+[[link](#no-END-blocks)]
+
+ ```ruby
+ # bad
+ END { puts 'Goodbye!' }
+
+ # good
+ at_exit { puts 'Goodbye!' }
+ ```
+
+*
+ Avoid the use of flip-flops.
+[[link](#no-flip-flops)]
+
+*
+ Avoid use of nested conditionals for flow of control.
+[[link](#no-nested-conditionals)]
+
+ Prefer a guard clause when you can assert invalid data. A guard clause
+ is a conditional statement at the top of a function that bails out as
+ soon as it can.
+
+ ```Ruby
+ # bad
+ def compute_thing(thing)
+ if thing[:foo]
+ update_with_bar(thing)
+ if thing[:foo][:bar]
+ partial_compute(thing)
+ else
+ re_compute(thing)
+ end
+ end
+ end
+
+ # good
+ def compute_thing(thing)
+ return unless thing[:foo]
+ update_with_bar(thing[:foo])
+ return re_compute(thing) unless thing[:foo][:bar]
+ partial_compute(thing)
+ end
+ ```
+
+ Prefer `next` in loops instead of conditional blocks.
+
+ ```Ruby
+ # bad
+ [0, 1, 2, 3].each do |item|
+ if item > 1
+ puts item
+ end
+ end
+
+ # good
+ [0, 1, 2, 3].each do |item|
+ next unless item > 1
+ puts item
+ end
+ ```
+
+*
+ Prefer `map` over `collect`, `find` over `detect`, `select` over `find_all`,
+ `reduce` over `inject` and `size` over `length`. This is not a hard
+ requirement; if the use of the alias enhances readability, it's ok to use it.
+ The rhyming methods are inherited from Smalltalk and are not common in other
+ programming languages. The reason the use of `select` is encouraged over
+ `find_all` is that it goes together nicely with `reject` and its name is
+ pretty self-explanatory.
+[[link](#map-find-select-reduce-size)]
+
+*
+ Don't use `count` as a substitute for `size`. For `Enumerable` objects other
+ than `Array` it will iterate the entire collection in order to determine its
+ size.
+[[link](#count-vs-size)]
+
+ ```Ruby
+ # bad
+ some_hash.count
+
+ # good
+ some_hash.size
+ ```
+
+*
+ Use `flat_map` instead of `map` + `flatten`. This does not apply for arrays
+ with a depth greater than 2, i.e. if `users.first.songs == ['a', ['b','c']]`,
+ then use `map + flatten` rather than `flat_map`. `flat_map` flattens the
+ array by 1, whereas `flatten` flattens it all the way.
+[[link](#flat-map)]
+
+ ```Ruby
+ # bad
+ all_songs = users.map(&:songs).flatten.uniq
+
+ # good
+ all_songs = users.flat_map(&:songs).uniq
+ ```
+
+*
+ Prefer `reverse_each` to `reverse.each` because some classes that `include
+ Enumerable` will provide an efficient implementation. Even in the worst case
+ where a class does not provide a specialized implementation, the general
+ implementation inherited from `Enumerable` will be at least as efficient as
+ using `reverse.each`.
+[[link](#reverse-each)]
+
+ ```Ruby
+ # bad
+ array.reverse.each { ... }
+
+ # good
+ array.reverse_each { ... }
+ ```
+
+## Naming
+
+> The only real difficulties in programming are cache invalidation and
+> naming things.
+> -- Phil Karlton
+
+*
+ Name identifiers in English.
+[[link](#english-identifiers)]
+
+ ```Ruby
+ # bad - identifier using non-ascii characters
+ заплата = 1_000
+
+ # bad - identifier is a Bulgarian word, written with Latin letters (instead of Cyrillic)
+ zaplata = 1_000
+
+ # good
+ salary = 1_000
+ ```
+
+*
+ Use `snake_case` for symbols, methods and variables.
+[[link](#snake-case-symbols-methods-vars)]
+
+ ```Ruby
+ # bad
+ :'some symbol'
+ :SomeSymbol
+ :someSymbol
+
+ someVar = 5
+
+ def someMethod
+ ...
+ end
+
+ def SomeMethod
+ ...
+ end
+
+ # good
+ :some_symbol
+
+ def some_method
+ ...
+ end
+ ```
+
+*
+ Use `CamelCase` for classes and modules. (Keep acronyms like HTTP, RFC, XML
+ uppercase.)
+[[link](#camelcase-classes)]
+
+ ```Ruby
+ # bad
+ class Someclass
+ ...
+ end
+
+ class Some_Class
+ ...
+ end
+
+ class SomeXml
+ ...
+ end
+
+ # good
+ class SomeClass
+ ...
+ end
+
+ class SomeXML
+ ...
+ end
+ ```
+
+*
+ Use `snake_case` for naming files, e.g. `hello_world.rb`.
+[[link](#snake-case-files)]
+
+*
+ Use `snake_case` for naming directories, e.g.
+ `lib/hello_world/hello_world.rb`.
+[[link](#snake-case-dirs)]
+
+*
+ Aim to have just a single class/module per source file. Name the file name
+ as the class/module, but replacing CamelCase with snake_case.
+[[link](#one-class-per-file)]
+
+*
+ Use `SCREAMING_SNAKE_CASE` for other constants.
+[[link](#screaming-snake-case)]
+
+ ```Ruby
+ # bad
+ SomeConst = 5
+
+ # good
+ SOME_CONST = 5
+ ```
+
+*
+ The names of predicate methods (methods that return a boolean value) should
+ end in a question mark. (i.e. `Array#empty?`). Methods that don't return a
+ boolean, shouldn't end in a question mark.
+[[link](#bool-methods-qmark)]
+
+*
+ The names of potentially *dangerous* methods (i.e. methods that modify
+ `self` or the arguments, `exit!` (doesn't run the finalizers like `exit`
+ does), etc.) should end with an exclamation mark if there exists a safe
+ version of that *dangerous* method.
+[[link](#dangerous-method-bang)]
+
+ ```Ruby
+ # bad - there is no matching 'safe' method
+ class Person
+ def update!
+ end
+ end
+
+ # good
+ class Person
+ def update
+ end
+ end
+
+ # good
+ class Person
+ def update!
+ end
+
+ def update
+ end
+ end
+ ```
+
+*
+ Define the non-bang (safe) method in terms of the bang (dangerous) one if
+ possible.
+[[link](#safe-because-unsafe)]
+
+ ```Ruby
+ class Array
+ def flatten_once!
+ res = []
+
+ each do |e|
+ [*e].each { |f| res << f }
+ end
+
+ replace(res)
+ end
+
+ def flatten_once
+ dup.flatten_once!
+ end
+ end
+ ```
+
+*
+ When using `reduce` with short blocks, name the arguments `|a, e|`
+ (accumulator, element).
+[[link](#reduce-blocks)]
+
+*
+ When defining binary operators, name the parameter `other`(`<<` and `[]` are
+ exceptions to the rule, since their semantics are different).
+[[link](#other-arg)]
+
+ ```Ruby
+ def +(other)
+ # body omitted
+ end
+ ```
+
+## Comments
+
+> Good code is its own best documentation. As you're about to add a
+> comment, ask yourself, "How can I improve the code so that this
+> comment isn't needed?" Improve the code and then document it to make
+> it even clearer.
+> -- Steve McConnell
+
+*
+ Write self-documenting code and ignore the rest of this section. Seriously!
+[[link](#no-comments)]
+
+*
+ Write comments in English.
+[[link](#english-comments)]
+
+*
+ Use one space between the leading `#` character of the comment and the text
+ of the comment.
+[[link](#hash-space)]
+
+*
+ Comments longer than a word are capitalized and use punctuation. Use [one
+ space](http://en.wikipedia.org/wiki/Sentence_spacing) after periods.
+[[link](#english-syntax)]
+
+*
+ Avoid superfluous comments.
+[[link](#no-superfluous-comments)]
+
+ ```Ruby
+ # bad
+ counter += 1 # Increments counter by one.
+ ```
+
+*
+ Keep existing comments up-to-date. An outdated comment is worse than no
+ comment at all.
+[[link](#comment-upkeep)]
+
+> Good code is like a good joke - it needs no explanation.
+> -- Russ Olsen
+
+*
+ Avoid writing comments to explain bad code. Refactor the code to make it
+ self-explanatory. (Do or do not - there is no try. --Yoda)
+[[link](#refactor-dont-comment)]
+
+### Comment Annotations
+
+*
+ Annotations should usually be written on the line immediately above the
+ relevant code.
+[[link](#annotate-above)]
+
+*
+ The annotation keyword is followed by a colon and a space, then a note
+ describing the problem.
+[[link](#annotate-keywords)]
+
+*
+ If multiple lines are required to describe the problem, subsequent lines
+ should be indented three spaces after the `#` (one general plus two for
+ indentation purpose).
+[[link](#indent-annotations)]
+
+ ```Ruby
+ def bar
+ # FIXME: This has crashed occasionally since v3.2.1. It may
+ # be related to the BarBazUtil upgrade.
+ baz(:quux)
+ end
+ ```
+
+*
+ In cases where the problem is so obvious that any documentation would be
+ redundant, annotations may be left at the end of the offending line with no
+ note. This usage should be the exception and not the rule.
+[[link](#rare-eol-annotations)]
+
+ ```Ruby
+ def bar
+ sleep 100 # OPTIMIZE
+ end
+ ```
+
+*
+ Use `TODO` to note missing features or functionality that should be added at
+ a later date.
+[[link](#todo)]
+
+*
+ Use `FIXME` to note broken code that needs to be fixed.
+[[link](#fixme)]
+
+*
+ Use `OPTIMIZE` to note slow or inefficient code that may cause performance
+ problems.
+[[link](#optimize)]
+
+*
+ Use `HACK` to note code smells where questionable coding practices were used
+ and should be refactored away.
+[[link](#hack)]
+
+*
+ Use `REVIEW` to note anything that should be looked at to confirm it is
+ working as intended. For example: `REVIEW: Are we sure this is how the client
+ does X currently?`
+[[link](#review)]
+
+*
+ Use other custom annotation keywords if it feels appropriate, but be sure to
+ document them in your project's `README` or similar.
+[[link](#document-annotations)]
+
+## Classes & Modules
+
+*
+ Use a consistent structure in your class definitions.
+[[link](#consistent-classes)]
+
+ ```Ruby
+ class Person
+ # extend and include go first
+ extend SomeModule
+ include AnotherModule
+
+ # inner classes
+ CustomErrorKlass = Class.new(StandardError)
+
+ # constants are next
+ SOME_CONSTANT = 20
+
+ # afterwards we have attribute macros
+ attr_reader :name
+
+ # followed by other macros (if any)
+ validates :name
+
+ # public class methods are next in line
+ def self.some_method
+ end
+
+ # initialization goes between class methods and other instance methods
+ def initialize
+ end
+
+ # followed by other public instance methods
+ def some_method
+ end
+
+ # protected and private methods are grouped near the end
+ protected
+
+ def some_protected_method
+ end
+
+ private
+
+ def some_private_method
+ end
+ end
+ ```
+
+*
+ Don't nest multi line classes within classes. Try to have such nested
+ classes each in their own file in a folder named like the containing class.
+[[link](#file-classes)]
+
+ ```Ruby
+ # bad
+
+ # foo.rb
+ class Foo
+ class Bar
+ # 30 methods inside
+ end
+
+ class Car
+ # 20 methods inside
+ end
+
+ # 30 methods inside
+ end
+
+ # good
+
+ # foo.rb
+ class Foo
+ # 30 methods inside
+ end
+
+ # foo/bar.rb
+ class Foo
+ class Bar
+ # 30 methods inside
+ end
+ end
+
+ # foo/car.rb
+ class Foo
+ class Car
+ # 20 methods inside
+ end
+ end
+ ```
+
+*
+ Prefer modules to classes with only class methods. Classes should be used
+ only when it makes sense to create instances out of them.
+[[link](#modules-vs-classes)]
+
+ ```Ruby
+ # bad
+ class SomeClass
+ def self.some_method
+ # body omitted
+ end
+
+ def self.some_other_method
+ end
+ end
+
+ # good
+ module SomeModule
+ module_function
+
+ def some_method
+ # body omitted
+ end
+
+ def some_other_method
+ end
+ end
+ ```
+
+*
+ Favor the use of `module_function` over `extend self` when you want to turn
+ a module's instance methods into class methods.
+[[link](#module-function)]
+
+ ```Ruby
+ # bad
+ module Utilities
+ extend self
+
+ def parse_something(string)
+ # do stuff here
+ end
+
+ def other_utility_method(number, string)
+ # do some more stuff
+ end
+ end
+
+ # good
+ module Utilities
+ module_function
+
+ def parse_something(string)
+ # do stuff here
+ end
+
+ def other_utility_method(number, string)
+ # do some more stuff
+ end
+ end
+ ```
+
+*
+ When designing class hierarchies make sure that they conform to the [Liskov
+ Substitution
+ Principle](http://en.wikipedia.org/wiki/Liskov_substitution_principle).
+[[link](#liskov)]
+
+*
+ Try to make your classes as
+ [SOLID](http://en.wikipedia.org/wiki/SOLID_\(object-oriented_design\)) as
+ possible.
+[[link](#solid-design)]
+
+*
+ Always supply a proper `to_s` method for classes that represent domain
+ objects.
+[[link](#define-to-s)]
+
+ ```Ruby
+ class Person
+ attr_reader :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+
+ def to_s
+ "#{@first_name} #{@last_name}"
+ end
+ end
+ ```
+
+*
+ Use the `attr` family of functions to define trivial accessors or mutators.
+[[link](#attr_family)]
+
+ ```Ruby
+ # bad
+ class Person
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+
+ def first_name
+ @first_name
+ end
+
+ def last_name
+ @last_name
+ end
+ end
+
+ # good
+ class Person
+ attr_reader :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+ end
+ ```
+
+*
+ Avoid the use of `attr`. Use `attr_reader` and `attr_accessor` instead.
+[[link](#attr)]
+
+ ```Ruby
+ # bad - creates a single attribute accessor (deprecated in 1.9)
+ attr :something, true
+ attr :one, :two, :three # behaves as attr_reader
+
+ # good
+ attr_accessor :something
+ attr_reader :one, :two, :three
+ ```
+
+*
+ Consider using `Struct.new`, which defines the trivial accessors,
+ constructor and comparison operators for you.
+[[link](#struct-new)]
+
+ ```Ruby
+ # good
+ class Person
+ attr_accessor :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+ end
+
+ # better
+ Person = Struct.new(:first_name, :last_name) do
+ end
+ ````
+
+*
+ Don't extend an instance initialized by `Struct.new`. Extending it introduces
+ a superfluous class level and may also introduce weird errors if the file is
+ required multiple times.
+[[link](#no-extend-struct-new)]
+
+ ```Ruby
+ # bad
+ class Person < Struct.new(:first_name, :last_name)
+ end
+
+ # good
+ Person = Struct.new(:first_name, :last_name)
+ ````
+
+*
+ Consider adding factory methods to provide additional sensible ways to
+ create instances of a particular class.
+[[link](#factory-methods)]
+
+ ```Ruby
+ class Person
+ def self.create(options_hash)
+ # body omitted
+ end
+ end
+ ```
+
+*
+ Prefer [duck-typing](http://en.wikipedia.org/wiki/Duck_typing) over
+ inheritance.
+[[link](#duck-typing)]
+
+ ```Ruby
+ # bad
+ class Animal
+ # abstract method
+ def speak
+ end
+ end
+
+ # extend superclass
+ class Duck < Animal
+ def speak
+ puts 'Quack! Quack'
+ end
+ end
+
+ # extend superclass
+ class Dog < Animal
+ def speak
+ puts 'Bau! Bau!'
+ end
+ end
+
+ # good
+ class Duck
+ def speak
+ puts 'Quack! Quack'
+ end
+ end
+
+ class Dog
+ def speak
+ puts 'Bau! Bau!'
+ end
+ end
+ ```
+
+*
+ Avoid the usage of class (`@@`) variables due to their "nasty" behavior in
+ inheritance.
+[[link](#no-class-vars)]
+
+ ```Ruby
+ 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"
+ ```
+
+ As you can see all the classes in a class hierarchy actually share one
+ class variable. Class instance variables should usually be preferred
+ over class variables.
+
+*
+ Assign proper visibility levels to methods (`private`, `protected`) in
+ accordance with their intended usage. Don't go off leaving everything `public`
+ (which is the default). After all we're coding in *Ruby* now, not in *Python*.
+[[link](#visibility)]
+
+*
+ Indent the `public`, `protected`, and `private` methods as much as the method
+ definitions they apply to. Leave one blank line above the visibility modifier
+ and one blank line below in order to emphasize that it applies to all methods
+ below it.
+[[link](#indent-public-private-protected)]
+
+ ```Ruby
+ class SomeClass
+ def public_method
+ # ...
+ end
+
+ private
+
+ def private_method
+ # ...
+ end
+
+ def another_private_method
+ # ...
+ end
+ end
+ ```
+
+*
+ Use `def self.method` to define singleton methods. This makes the code
+ easier to refactor since the class name is not repeated.
+[[link](#def-self-singletons)]
+
+ ```Ruby
+ class TestClass
+ # bad
+ def TestClass.some_method
+ # body omitted
+ end
+
+ # good
+ def self.some_other_method
+ # body omitted
+ end
+
+ # Also possible and convenient when you
+ # have to define many singleton methods.
+ class << self
+ def first_method
+ # body omitted
+ end
+
+ def second_method_etc
+ # body omitted
+ end
+ end
+ end
+ ```
+
+*
+ Prefer `alias` when aliasing methods in lexical class scope as the
+ resolution of `self` in this context is also lexical, and it communicates
+ clearly to the user that the indirection of your alias will not be altered
+ at runtime or by any subclass unless made explicit.
+[[link](#alias-method-lexically)]
+
+ ```Ruby
+ class Westerner
+ def first_name
+ @names.first
+ end
+
+ alias given_name first_name
+ end
+ ```
+
+ Since `alias`, like `def`, is a keyword, prefer bareword arguments over
+ symbols or strings. In other words, do `alias foo bar`, not
+ `alias :foo :bar`.
+
+ Also be aware of how Ruby handles aliases and inheritance: an alias
+ references the method that was resolved at the time the alias was defined;
+ it is not dispatched dynamically.
+
+ ```Ruby
+ class Fugitive < Westerner
+ def first_name
+ 'Nobody'
+ end
+ end
+ ```
+
+ In this example, `Fugitive#given_name` would still call the original
+ `Westerner#first_name` method, not `Fugitive#first_name`. To override the
+ behavior of `Fugitive#given_name` as well, you'd have to redefine it in the
+ derived class.
+
+ ```Ruby
+ class Fugitive < Westerner
+ def first_name
+ 'Nobody'
+ end
+
+ alias given_name first_name
+ end
+ ```
+
+*
+ Always use `alias_method` when aliasing methods of modules, classes, or
+ singleton classes at runtime, as the lexical scope of `alias` leads to
+ unpredictability in these cases.
+[[link](#alias-method)]
+
+ ```Ruby
+ module Mononymous
+ def self.included(other)
+ other.class_eval { alias_method :full_name, :given_name }
+ end
+ end
+
+ class Sting < Westerner
+ include Mononymous
+ end
+ ```
+
+## Exceptions
+
+*
+ Signal exceptions using the `fail` method. Use `raise` only when catching an
+ exception and re-raising it (because here you're not failing, but explicitly
+ and purposefully raising an exception).
+[[link](#fail-method)]
+
+ ```Ruby
+ begin
+ fail 'Oops'
+ rescue => error
+ raise if error.message != 'Oops'
+ end
+ ```
+
+*
+ Don't specify `RuntimeError` explicitly in the two argument version of
+ `fail/raise`.
+[[link](#no-explicit-runtimeerror)]
+
+ ```Ruby
+ # bad
+ fail RuntimeError, 'message'
+
+ # good - signals a RuntimeError by default
+ fail 'message'
+ ```
+
+*
+ Prefer supplying an exception class and a message as two separate arguments
+ to `fail/raise`, instead of an exception instance.
+[[link](#exception-class-messages)]
+
+ ```Ruby
+ # bad
+ fail SomeException.new('message')
+ # Note that there is no way to do `fail SomeException.new('message'), backtrace`.
+
+ # good
+ fail SomeException, 'message'
+ # Consistent with `fail SomeException, 'message', backtrace`.
+ ```
+
+*
+ Do not return from an `ensure` block. If you explicitly return from a method
+ inside an `ensure` block, the return will take precedence over any exception
+ being raised, and the method will return as if no exception had been raised at
+ all. In effect, the exception will be silently thrown away.
+[[link](#no-return-ensure)]
+
+ ```Ruby
+ def foo
+ fail
+ ensure
+ return 'very bad idea'
+ end
+ ```
+
+*
+ Use *implicit begin blocks* where possible.
+[[link](#begin-implicit)]
+
+ ```Ruby
+ # bad
+ def foo
+ begin
+ # main logic goes here
+ rescue
+ # failure handling goes here
+ end
+ end
+
+ # good
+ def foo
+ # main logic goes here
+ rescue
+ # failure handling goes here
+ end
+ ```
+
+*
+ Mitigate the proliferation of `begin` blocks by using *contingency methods*
+ (a term coined by Avdi Grimm).
+[[link](#contingency-methods)]
+
+ ```Ruby
+ # bad
+ begin
+ something_that_might_fail
+ rescue IOError
+ # handle IOError
+ end
+
+ begin
+ something_else_that_might_fail
+ rescue IOError
+ # handle IOError
+ end
+
+ # good
+ def with_io_error_handling
+ yield
+ rescue IOError
+ # handle IOError
+ end
+
+ with_io_error_handling { something_that_might_fail }
+
+ with_io_error_handling { something_else_that_might_fail }
+ ```
+
+*
+ Don't suppress exceptions.
+[[link](#dont-hide-exceptions)]
+
+ ```Ruby
+ # bad
+ begin
+ # an exception occurs here
+ rescue SomeError
+ # the rescue clause does absolutely nothing
+ end
+
+ # bad
+ do_something rescue nil
+ ```
+
+*
+ Avoid using `rescue` in its modifier form.
+[[link](#no-rescue-modifiers)]
+
+ ```Ruby
+ # bad - this catches exceptions of StandardError class and its descendant classes
+ read_file rescue handle_error($!)
+
+ # good - this catches only the exceptions of Errno::ENOENT class and its descendant classes
+ def foo
+ read_file
+ rescue Errno::ENOENT => ex
+ handle_error(ex)
+ end
+ ```
+
+*
+ Don't use exceptions for flow of control.
+[[link](#no-exceptional-flows)]
+
+ ```Ruby
+ # 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
+ ```
+
+*
+ Avoid rescuing the `Exception` class. This will trap signals and calls to
+ `exit`, requiring you to `kill -9` the process.
+[[link](#no-blind-rescues)]
+
+ ```Ruby
+ # bad
+ begin
+ # calls to exit and kill signals will be caught (except kill -9)
+ exit
+ rescue Exception
+ puts "you didn't really want to exit, right?"
+ # exception handling
+ end
+
+ # good
+ begin
+ # a blind rescue rescues from StandardError, not Exception as many
+ # programmers assume.
+ rescue => e
+ # exception handling
+ end
+
+ # also good
+ begin
+ # an exception occurs here
+
+ rescue StandardError => e
+ # exception handling
+ end
+ ```
+
+*
+ Put more specific exceptions higher up the rescue chain, otherwise they'll
+ never be rescued from.
+[[link](#exception-ordering)]
+
+ ```Ruby
+ # bad
+ begin
+ # some code
+ rescue Exception => e
+ # some handling
+ rescue StandardError => e
+ # some handling that will never be executed
+ end
+
+ # good
+ begin
+ # some code
+ rescue StandardError => e
+ # some handling
+ rescue Exception => e
+ # some handling
+ end
+ ```
+
+*
+ Release external resources obtained by your program in an `ensure` block.
+[[link](#release-resources)]
+
+ ```Ruby
+ f = File.open('testfile')
+ begin
+ # .. process
+ rescue
+ # .. handle error
+ ensure
+ f.close if f
+ end
+ ```
+
+*
+Use versions of resource obtaining methods that do automatic
+resource cleanup when possible.
+[[link](#auto-release-resources)]
+
+ ```Ruby
+ # bad - you need to close the file descriptor explicitly
+ f = File.open('testfile')
+ # ...
+ f.close
+
+ # good - the file descriptor is closed automatically
+ File.open('testfile') do |f|
+ # ...
+ end
+ ```
+
+*
+ Favor the use of exceptions for the standard library over introducing new
+ exception classes.
+[[link](#standard-exceptions)]
+
+## Collections
+
+*
+ Prefer literal array and hash creation notation (unless you need to pass
+ parameters to their constructors, that is).
+[[link](#literal-array-hash)]
+
+ ```Ruby
+ # bad
+ arr = Array.new
+ hash = Hash.new
+
+ # good
+ arr = []
+ hash = {}
+ ```
+
+*
+ Prefer `%w` to the literal array syntax when you need an array of words
+ (non-empty strings without spaces and special characters in them). Apply this
+ rule only to arrays with two or more elements.
+[[link](#percent-w)]
+
+ ```Ruby
+ # bad
+ STATES = ['draft', 'open', 'closed']
+
+ # good
+ STATES = %w(draft open closed)
+ ```
+
+*
+ Prefer `%i` to the literal array syntax when you need an array of symbols
+ (and you don't need to maintain Ruby 1.9 compatibility). Apply this rule only
+ to arrays with two or more elements.
+[[link](#percent-i)]
+
+ ```Ruby
+ # bad
+ STATES = [:draft, :open, :closed]
+
+ # good
+ STATES = %i(draft open closed)
+ ```
+
+*
+ Avoid comma after the last item of an `Array` or `Hash` literal, especially
+ when the items are not on separate lines.
+[[link](#no-trailing-array-commas)]
+
+ ```Ruby
+ # bad - easier to move/add/remove items, but still not preferred
+ VALUES = [
+ 1001,
+ 2020,
+ 3333,
+ ]
+
+ # bad
+ VALUES = [1001, 2020, 3333, ]
+
+ # good
+ VALUES = [1001, 2020, 3333]
+ ```
+
+*
+ Avoid the creation of huge gaps in arrays.
+[[link](#no-gappy-arrays)]
+
+ ```Ruby
+ arr = []
+ arr[100] = 1 # now you have an array with lots of nils
+ ```
+
+*
+ When accessing the first or last element from an array, prefer `first` or
+ `last` over `[0]` or `[-1]`.
+[[link](#first-and-last)]
+
+*
+ Use `Set` instead of `Array` when dealing with unique elements. `Set`
+ implements a collection of unordered values with no duplicates. This is a
+ hybrid of `Array`'s intuitive inter-operation facilities and `Hash`'s fast
+ lookup.
+[[link](#set-vs-array)]
+
+*
+ Prefer symbols instead of strings as hash keys.
+[[link](#symbols-as-keys)]
+
+ ```Ruby
+ # bad
+ hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
+
+ # good
+ hash = { one: 1, two: 2, three: 3 }
+ ```
+
+*
+ Avoid the use of mutable objects as hash keys.
+[[link](#no-mutable-keys)]
+
+*
+ Use the Ruby 1.9 hash literal syntax when your hash keys are symbols.
+[[link](#hash-literals)]
+
+ ```Ruby
+ # bad
+ hash = { :one => 1, :two => 2, :three => 3 }
+
+ # good
+ hash = { one: 1, two: 2, three: 3 }
+ ```
+
+*
+ Don't mix the Ruby 1.9 hash syntax with hash rockets in the same hash
+ literal. When you've got keys that are not symbols stick to the hash rockets
+ syntax.
+[[link](#no-mixed-hash-syntaces)]
+
+ ```Ruby
+ # bad
+ { a: 1, 'b' => 2 }
+
+ # good
+ { :a => 1, 'b' => 2 }
+ ```
+
+*
+ Use `Hash#key?` instead of `Hash#has_key?` and `Hash#value?` instead of
+ `Hash#has_value?`. As noted
+ [here](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/43765) by
+ Matz, the longer forms are considered deprecated.
+[[link](#hash-key)]
+
+ ```Ruby
+ # bad
+ hash.has_key?(:test)
+ hash.has_value?(value)
+
+ # good
+ hash.key?(:test)
+ hash.value?(value)
+ ```
+
+*
+ Use `Hash#fetch` when dealing with hash keys that should be present.
+[[link](#hash-fetch)]
+
+ ```Ruby
+ heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
+ # bad - if we make a mistake we might not spot it right away
+ heroes[:batman] # => "Bruce Wayne"
+ heroes[:supermann] # => nil
+
+ # good - fetch raises a KeyError making the problem obvious
+ heroes.fetch(:supermann)
+ ```
+
+*
+ Introduce default values for hash keys via `Hash#fetch` as opposed to using
+ custom logic.
+[[link](#hash-fetch-defaults)]
+
+ ```Ruby
+ batman = { name: 'Bruce Wayne', is_evil: false }
+
+ # bad - if we just use || operator with falsy value we won't get the expected result
+ batman[:is_evil] || true # => true
+
+ # good - fetch work correctly with falsy values
+ batman.fetch(:is_evil, true) # => false
+ ```
+
+*
+ Prefer the use of the block instead of the default value in `Hash#fetch` if the code that has to be evaluated may have side effects or be expensive.
+[[link](#use-hash-blocks)]
+
+ ```Ruby
+ batman = { name: 'Bruce Wayne' }
+
+ # bad - if we use the default value, we eager evaluate it
+ # so it can slow the program down if done multiple times
+ batman.fetch(:powers, get_batman_powers) # get_batman_powers is an expensive call
+
+ # good - blocks are lazy evaluated, so only triggered in case of KeyError exception
+ batman.fetch(:powers) { get_batman_powers }
+ ```
+
+*
+ Use `Hash#values_at` when you need to retrieve several values consecutively
+ from a hash.
+[[link](#hash-values-at)]
+
+ ```Ruby
+ # bad
+ email = data['email']
+ username = data['nickname']
+
+ # good
+ email, username = data.values_at('email', 'nickname')
+ ```
+
+*
+ Rely on the fact that as of Ruby 1.9 hashes are ordered.
+[[link](#ordered-hashes)]
+
+*
+ Do not modify a collection while traversing it.
+[[link](#no-modifying-collections)]
+
+*
+ When accessing elements of a collection, avoid direct access
+ via `[n]` by using an alternate form of the reader method if it is
+ supplied. This guards you from calling `[]` on `nil`.
+[[link](#accessing-elements-directly)]
+
+ ```Ruby
+ # bad
+ Regexp.last_match[1]
+
+ # good
+ Regexp.last_match(1)
+ ```
+
+*
+ When providing an accessor for a collection, provide an alternate form
+ to save users from checking for `nil` before accessing an element in
+ the collection.
+[[link](#provide-alternate-accessor-to-collections)]
+
+ ```Ruby
+ # bad
+ def awesome_things
+ @awesome_things
+ end
+
+ # good
+ def awesome_things(index = nil)
+ if index && @awesome_things
+ @awesome_things[index]
+ else
+ @awesome_things
+ end
+ end
+ ```
+
+## Strings
+
+*
+ Prefer string interpolation and string formatting instead of string
+ concatenation:
+[[link](#string-interpolation)]
+
+ ```Ruby
+ # bad
+ email_with_name = user.name + ' <' + user.email + '>'
+
+ # good
+ email_with_name = "#{user.name} <#{user.email}>"
+
+ # good
+ email_with_name = format('%s <%s>', user.name, user.email)
+ ```
+
+*
+ With interpolated expressions, there should be no padded-spacing inside the braces.
+[[link](#pad-string-interpolation)]
+
+ ```Ruby
+ # bad
+ "From: #{ user.first_name }, #{ user.last_name }"
+
+ # good
+ "From: #{user.first_name}, #{user.last_name}"
+ ```
+
+*
+ Adopt a consistent string literal quoting style. There are two popular
+ styles in the Ruby community, both of which are considered good - single
+ quotes by default (Option A) and double quotes by default (Option B).
+[[link](#consistent-string-literals)]
+
+ * **(Option A)** Prefer single-quoted strings when you don't need
+ string interpolation or special symbols such as `\t`, `\n`, `'`,
+ etc.
+
+ ```Ruby
+ # bad
+ name = "Bozhidar"
+
+ # good
+ name = 'Bozhidar'
+ ```
+
+ * **(Option B)** Prefer double-quotes unless your string literal
+ contains `"` or escape characters you want to suppress.
+
+ ```Ruby
+ # bad
+ name = 'Bozhidar'
+
+ # good
+ name = "Bozhidar"
+ ```
+
+ The string literals in this guide are aligned with the first style.
+
+*
+ Don't use the character literal syntax `?x`. Since Ruby 1.9 it's basically
+ redundant - `?x` would interpreted as `'x'` (a string with a single character
+ in it).
+[[link](#no-character-literals)]
+
+ ```Ruby
+ # bad
+ char = ?c
+
+ # good
+ char = 'c'
+ ```
+
+*
+ Don't leave out `{}` around instance and global variables being interpolated
+ into a string.
+[[link](#curlies-interpolate)]
+
+ ```Ruby
+ class Person
+ attr_reader :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+
+ # bad - valid, but awkward
+ def to_s
+ "#@first_name #@last_name"
+ end
+
+ # good
+ def to_s
+ "#{@first_name} #{@last_name}"
+ end
+ end
+
+ $global = 0
+ # bad
+ puts "$global = #$global"
+
+ # good
+ puts "$global = #{$global}"
+ ```
+
+*
+ Don't use `Object#to_s` on interpolated objects. It's invoked on them
+ automatically.
+[[link](#no-to-s)]
+
+ ```Ruby
+ # bad
+ message = "This is the #{result.to_s}."
+
+ # good
+ message = "This is the #{result}."
+ ```
+
+*
+ Avoid using `String#+` when you need to construct large data chunks.
+ Instead, use `String#<<`. Concatenation mutates the string instance in-place
+ and is always faster than `String#+`, which creates a bunch of new string
+ objects.
+[[link](#concat-strings)]
+
+ ```Ruby
+ # good and also fast
+ html = ''
+ html << '
Page title
'
+
+ paragraphs.each do |paragraph|
+ html << "#{paragraph}
"
+ end
+ ```
+
+*
+ Don't use `String#gsub` in scenarios in which you can use a faster more specialized alternative.
+[[link](#dont-abuse-gsub)]
+
+ ```Ruby
+ url = 'http://example.com'
+ str = 'lisp-case-rules'
+
+ # bad
+ url.gsub("http://", "https://")
+ str.gsub("-", "_")
+
+ # good
+ url.sub("http://", "https://")
+ str.tr("-", "_")
+ ```
+
+*
+ When using heredocs for multi-line strings keep in mind the fact that they
+ preserve leading whitespace. It's a good practice to employ some margin based
+ on which to trim the excessive whitespace.
+[[link](#heredocs)]
+
+ ```Ruby
+ code = <<-END.gsub(/^\s+\|/, '')
+ |def test
+ | some_method
+ | other_method
+ |end
+ END
+ # => "def test\n some_method\n other_method\nend\n"
+ ```
+
+## Regular Expressions
+
+> Some people, when confronted with a problem, think
+> "I know, I'll use regular expressions." Now they have two problems.
+> -- Jamie Zawinski
+
+*
+ Don't use regular expressions if you just need plain text search in string:
+ `string['text']`
+[[link](#no-regexp-for-plaintext)]
+
+*
+ For simple constructions you can use regexp directly through string index.
+[[link](#regexp-string-index)]
+
+ ```Ruby
+ match = string[/regexp/] # get content of matched regexp
+ first_group = string[/text(grp)/, 1] # get content of captured group
+ string[/text (grp)/, 1] = 'replace' # string => 'text replace'
+ ```
+
+*
+ Use non-capturing groups when you don't use captured result of parentheses.
+[[link](#non-capturing-regexp)]
+
+ ```Ruby
+ /(first|second)/ # bad
+ /(?:first|second)/ # good
+ ```
+
+*
+ Don't use the cryptic Perl-legacy variables denoting last regexp group
+ matches (`$1`, `$2`, etc). Use `Regexp.last_match(n)` instead.
+[[link](#no-perl-regexp-last-matchers)]
+
+ ```Ruby
+ /(regexp)/ =~ string
+ ...
+
+ # bad
+ process $1
+
+ # good
+ process Regexp.last_match(1)
+ ```
+
+*
+ Avoid using numbered groups as it can be hard to track what they contain.
+ Named groups can be used instead.
+[[link](#no-numbered-regexes)]
+
+ ```Ruby
+ # bad
+ /(regexp)/ =~ string
+ ...
+ process Regexp.last_match(1)
+
+ # good
+ /(?regexp)/ =~ string
+ ...
+ process meaningful_var
+ ```
+
+*
+ Character classes have only a few special characters you should care about:
+ `^`, `-`, `\`, `]`, so don't escape `.` or brackets in `[]`.
+[[link](#limit-escapes)]
+
+*
+ Be careful with `^` and `$` as they match start/end of line, not string
+ endings. If you want to match the whole string use: `\A` and `\z` (not to be
+ confused with `\Z` which is the equivalent of `/\n?\z/`).
+[[link](#caret-and-dollar-regexp)]
+
+ ```Ruby
+ string = "some injection\nusername"
+ string[/^username$/] # matches
+ string[/\Ausername\z/] # doesn't match
+ ```
+
+*
+ Use `x` modifier for complex regexps. This makes them more readable and you
+ can add some useful comments. Just be careful as spaces are ignored.
+[[link](#comment-regexes)]
+
+ ```Ruby
+ regexp = /
+ start # some text
+ \s # white space char
+ (group) # first group
+ (?:alt1|alt2) # some alternation
+ end
+ /x
+ ```
+
+*
+ For complex replacements `sub`/`gsub` can be used with block or hash.
+[[link](#gsub-blocks)]
+
+## Percent Literals
+
+*
+ Use `%()`(it's a shorthand for `%Q`) for single-line strings which require
+ both interpolation and embedded double-quotes. For multi-line strings, prefer
+ heredocs.
+[[link](#percent-q-shorthand)]
+
+ ```Ruby
+ # bad (no interpolation needed)
+ %(Some text
)
+ # should be 'Some text
'
+
+ # bad (no double-quotes)
+ %(This is #{quality} style)
+ # should be "This is #{quality} style"
+
+ # bad (multiple lines)
+ %(\n#{exclamation}\n
)
+ # should be a heredoc.
+
+ # good (requires interpolation, has quotes, single line)
+ %(#{name} | )
+ ```
+
+*
+ Avoid `%q` unless you have a string with both `'` and `"` in it. Regular
+ string literals are more readable and should be preferred unless a lot of
+ characters would have to be escaped in them.
+[[link](#percent-q)]
+
+ ```Ruby
+ # bad
+ name = %q(Bruce Wayne)
+ time = %q(8 o'clock)
+ question = %q("What did you say?")
+
+ # good
+ name = 'Bruce Wayne'
+ time = "8 o'clock"
+ question = '"What did you say?"'
+ ```
+
+*
+ Use `%r` only for regular expressions matching *at least* one '/'
+ character.
+[[link](#percent-r)]
+
+ ```Ruby
+ # bad
+ %r{\s+}
+
+ # good
+ %r{^/(.*)$}
+ %r{^/blog/2011/(.*)$}
+ ```
+
+*
+ Avoid the use of `%x` unless you're going to invoke a command with
+ backquotes in it(which is rather unlikely).
+[[link](#percent-x)]
+
+ ```Ruby
+ # bad
+ date = %x(date)
+
+ # good
+ date = `date`
+ echo = %x(echo `date`)
+ ```
+
+*
+ Avoid the use of `%s`. It seems that the community has decided `:"some
+ string"` is the preferred way to create a symbol with spaces in it.
+[[link](#percent-s)]
+
+*
+ Prefer `()` as delimiters for all `%` literals, except `%r`. Since parentheses
+ often appear inside regular expressions in many scenarios a less common
+ character like `{` might be a better choice for a delimiter, depending on the
+ regexp's content.
+[[link](#percent-literal-braces)]
+
+ ```Ruby
+ # bad
+ %w[one two three]
+ %q{"Test's king!", John said.}
+
+ # good
+ %w(one two three)
+ %q("Test's king!", John said.)
+ ```
+
+## Metaprogramming
+
+*
+ Avoid needless metaprogramming.
+[[link](#no-needless-metaprogramming)]
+
+*
+ Do not mess around in core classes when writing libraries. (Do not
+ monkey-patch them.)
+[[link](#no-monkey-patching)]
+
+*
+ The block form of `class_eval` is preferable to the string-interpolated
+ form. - when you use the string-interpolated form, always supply `__FILE__`
+ and `__LINE__`, so that your backtraces make sense:
+[[link](#block-class-eval)]
+
+ ```ruby
+ class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
+ ```
+
+ - `define_method` is preferable to `class_eval{ def ... }`
+
+*
+ When using `class_eval` (or other `eval`) with string interpolation, add a
+ comment block showing its appearance if interpolated (a practice used in Rails
+ code):
+[[link](#eval-comment-docs)]
+
+ ```ruby
+ # from activesupport/lib/active_support/core_ext/string/output_safety.rb
+ UNSAFE_STRING_METHODS.each do |unsafe_method|
+ if 'String'.respond_to?(unsafe_method)
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
+ def #{unsafe_method}(*params, &block) # def capitalize(*params, &block)
+ to_str.#{unsafe_method}(*params, &block) # to_str.capitalize(*params, &block)
+ end # end
+
+ def #{unsafe_method}!(*params) # def capitalize!(*params)
+ @dirty = true # @dirty = true
+ super # super
+ end # end
+ EOT
+ end
+ end
+ ```
+
+*
+ Avoid using `method_missing` for metaprogramming because backtraces become
+ messy, the behavior is not listed in `#methods`, and misspelled method calls
+ might silently work, e.g. `nukes.launch_state = false`. Consider using
+ delegation, proxy, or `define_method` instead. If you must use
+ `method_missing`:
+[[link](#no-method-missing)]
+
+ - Be sure to [also define `respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html)
+ - Only catch methods with a well-defined prefix, such as `find_by_*` -- make your code as assertive as possible.
+ - Call `super` at the end of your statement
+ - Delegate to assertive, non-magical methods:
+
+ ```ruby
+ # bad
+ def method_missing?(meth, *params, &block)
+ if /^find_by_(?.*)/ =~ meth
+ # ... lots of code to do a find_by
+ else
+ super
+ end
+ end
+
+ # good
+ def method_missing?(meth, *params, &block)
+ if /^find_by_(?.*)/ =~ meth
+ find_by(prop, *params, &block)
+ else
+ super
+ end
+ end
+
+ # best of all, though, would to define_method as each findable attribute is declared
+ ```
+
+*
+ Prefer `public_send` over `send` so as not to circumvent `private`/`protected` visibility.
+[[link](#prefer-public-send)]
+
+## Misc
+
+*
+ Write `ruby -w` safe code.
+[[link](#always-warn)]
+
+*
+ Avoid hashes as optional parameters. Does the method do too much? (Object
+ initializers are exceptions for this rule).
+[[link](#no-optional-hash-params)]
+
+*
+ Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will
+ be shorter than 5 LOC. Empty lines do not contribute to the relevant LOC.
+[[link](#short-methods)]
+
+*
+ Avoid parameter lists longer than three or four parameters.
+[[link](#too-many-params)]
+
+*
+ If you really need "global" methods, add them to Kernel and make them
+ private.
+[[link](#private-global-methods)]
+
+*
+ Use module instance variables instead of global variables.
+[[link](#instance-vars)]
+
+ ```Ruby
+ # bad
+ $foo_bar = 1
+
+ # good
+ module Foo
+ class << self
+ attr_accessor :bar
+ end
+ end
+
+ Foo.bar = 1
+ ```
+
+*
+ Use `OptionParser` for parsing complex command line options and `ruby -s`
+ for trivial command line options.
+[[link](#optionparser)]
+
+*
+ Prefer `Time.now` over `Time.new` when retrieving the current system time.
+[[link](#time-now)]
+
+*
+ Code in a functional way, avoiding mutation when that makes sense.
+[[link](#functional-code)]
+
+*
+ Do not mutate parameters unless that is the purpose of the method.
+[[link](#no-param-mutations)]
+
+*
+ Avoid more than three levels of block nesting.
+[[link](#three-is-the-number-thou-shalt-count)]
+
+*
+ Be consistent. In an ideal world, be consistent with these guidelines.
+[[link](#be-consistent)]
+
+*
+ Use common sense.
+[[link](#common-sense)]
+
+## Tools
+
+Here's some tools to help you automatically check Ruby code against
+this guide.
+
+### RuboCop
+
+[RuboCop][] is a Ruby code style
+checker based on this style guide. RuboCop already covers a
+significant portion of the Guide, supports both MRI 1.9 and MRI 2.0
+and has good Emacs integration.
+
+### RubyMine
+
+[RubyMine](http://www.jetbrains.com/ruby/)'s code inspections are
+[partially based](http://confluence.jetbrains.com/display/RUBYDEV/RubyMine+Inspections)
+on this guide.
+
+# Contributing
+
+The guide is still a work in progress - some rules are lacking examples, some
+rules don't have examples that illustrate them clearly enough. Improving such rules
+is a great (and simple way) to help the Ruby community!
+
+In due time these issues will (hopefully) be addressed - just keep them in mind
+for now.
+
+Nothing written in this guide is set in stone. It's my desire to work
+together with everyone interested in Ruby coding style, so that we could
+ultimately create a resource that will be beneficial to the entire Ruby
+community.
+
+Feel free to open tickets or send pull requests with improvements. Thanks in
+advance for your help!
+
+You can also support the project (and RuboCop) with financial
+contributions via [gittip](https://www.gittip.com/bbatsov).
+
+[](https://www.gittip.com/bbatsov)
+
+## How to Contribute?
+
+It's easy, just follow the [contribution guidelines](https://github.com/bbatsov/ruby-style-guide/blob/master/CONTRIBUTING.md).
+
+# License
+
+
+This work is licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US)
+
+# Spread the Word
+
+A community-driven style guide is of little use to a community that
+doesn't know about its existence. Tweet about the guide, share it with
+your friends and colleagues. Every comment, suggestion or opinion we
+get makes the guide just a little bit better. And we want to have the
+best possible guide, don't we?
+
+Cheers,
+[Bozhidar](https://twitter.com/bbatsov)
+
+[PEP-8]: http://www.python.org/dev/peps/pep-0008/
+[rails-style-guide]: https://github.com/bbatsov/rails-style-guide
+[pickaxe]: http://pragprog.com/book/ruby4/programming-ruby-1-9-2-0
+[trpl]: http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177
+[transmuter]: https://github.com/TechnoGate/transmuter
+[RuboCop]: https://github.com/bbatsov/rubocop
diff --git a/README-ruRU.md b/README-ruRU.md
new file mode 100644
index 000000000..851b1bf5a
--- /dev/null
+++ b/README-ruRU.md
@@ -0,0 +1,3557 @@
+# Вступление
+
+> Ролевые модели важны.
+> -- Офицер Алекс Мёрфи / Робот-полицейский
+
+Один из вопросов, который меня всегда беспокоил как разработчика на Руби,
+— это то, что у разработчиков на Питоне есть великолепное руководствo
+по стилю оформления ([PEP-8][]), а у нас
+никогда не было официального руководства, описывавшего бы стиль оформления кода
+на Руби и дающего примеры его успешного применения. Я же уверен, что стиль
+оформления крайне важен. Также я верю, что такое замечательное сообщество
+разработчиков, которое есть у Руби, вполне имеет силы создать этот давно
+назревший документ.
+
+Это наставление появилось на свет в нашей фирме в виде внутреннего руководства
+по оформлению кода на Руби (составленного вашим покорным слугой). И в какой-то
+момент я решил, что данная работа, которой я тогда занимался, может быть
+интересной и другим членам сообщества программистов на Руби и что миру вовсе
+не нужно еще одно руководство для внутреннего пользования: окружающий мир может
+получить пользу от совместно создаваемого и одобренного сообществом набора
+практик, идиом и стилистических предписаний для программирования на Руби.
+
+Со времени опубликования этого руководства я получил многочисленные отклики
+от членов сообщества программистов на Руби из разных уголков со всего мира. Я
+очень благодарен им за полезные предложения и поддержку! Нашими общими усилиями
+мы сможем сделать этот ресурс полезным для всех и каждого разработчика на Руби.
+
+И кстати, если вы работаете с Rails, вы можете взглянуть на дополняющее это
+руководство [Ruby on Rails 3 & 4: Руководство по стилю оформления][rails-style-guide].
+
+# Руби: руководство по стилю оформления
+
+Это руководство по оформлению кода на Руби дает передовые рекомендации, так что
+обычный программист на Руби сможет создавать код, который с легкостью смогут
+поддерживать другие обычные программисты на Руби. Руководство по оформлению,
+которое отражает повседневную практику, будет применяться постоянно, а руководство,
+стремящееся к идеалу, который не принимается обычными людьми, подвергается риску
+вообще быть забытым — не важно, насколько хорошим оно является.
+
+Данное руководство разделено на несколько частей, состоящий из связанных по смыслу
+правил. В каждом случае я попытался обосновать появление этих правил (объяснение
+опущено в ситуациях, когда я посчитал его очевидным).
+
+Все эти правила не появились из пустоты, они по большей части основываются на моем
+собственном обширном профессиональном опыте в качестве разработчика ПО, отзывах
+и предложениях других членов сообщества программистов на Руби и различных
+общепризнанных источниках по программированию на Руби, например,
+["Programming Ruby 1.9"][pickaxe] и ["Язык программирования Ruby"][trpl]
+(в оригинале ["The Ruby Programming Language"][entrpl]).
+
+Во многих областях до сих пор нет единого мнения в среде разработчиков на Руби
+относительно конкретных аспектов стиля оформления (например, оформление строк
+в кавычках, пробелы при оформлении хешей, месторасположение точки при
+многострочном последовательном вызове методов и т.д.). В таких ситуациях мы
+рассматривали все распространенные стили, вам же решать, какой из этих стилей
+вы будете применять последовательно в вашем коде.
+
+Это руководство все еще находится в процессе создания: у многих правил нет
+примеров, у других нет примеров, достаточно ясно объясняющих эти правила. В свое
+время каждое правило найдет свое объяснение, а пока просто примите их к сведению.
+
+Вы можете создать копию этого руководства в форматах PDF или HTML при помощи
+[Transmuter][].
+
+[RuboCop][] — это анализатор кода, основывающийся на правилах этого
+руководства по оформлению.
+
+Переводы данного руководства доступны на следующих языках:
+
+* [английский (исходная версия)](https://github.com/bbatsov/ruby-style-guide/blob/master/README.md)
+* [вьетнамский](https://github.com/scrum2b/ruby-style-guide/blob/master/README-viVN.md)
+* [испанский](https://github.com/alemohamad/ruby-style-guide/blob/master/README-esLA.md)
+* [китайский традиционный](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
+* [китайский упрощенный](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
+* [корейский](https://github.com/dalzony/ruby-style-guide/blob/master/README-koKR.md)
+* [немецкий](https://github.com/arbox/ruby-style-guide/blob/master/README-deDE.md)
+* [французский](https://github.com/porecreat/ruby-style-guide/blob/master/README-frFR.md)
+* [португальский](https://github.com/rubensmabueno/ruby-style-guide/blob/master/README-PT-BR.md)
+* [русский (данный документ)](https://github.com/arbox/ruby-style-guide/blob/master/README-ruRU.md)
+* [японский](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
+
+## Оглавление
+
+* [Организация исходного кода](#Организация-исходного-кода)
+* [Синтаксис](#Синтаксис)
+* [Наименование](#Hаименование)
+* [Комментарии](#Комментарии)
+ * [Пометки в комментариях](#Пометки-в-комментариях)
+* [Классы и модули](#Классы-и-модули)
+* [Исключения](#Исключения)
+* [Коллекции](#Коллекции)
+* [Строки](#Строки)
+* [Регулярные выражения](#Регулярные-выражения)
+* [Процентные литералы](#Процентные-литералы)
+* [Метапрограммирование](#Метапрограммирование)
+* [Разное](#Разное)
+* [Инструментарий](#Инструментарий)
+
+## Организация исходного кода
+
+> Почти все убеждены, что любой стиль кроме их собственного ужасен и нечитаем.
+> Уберите отсюда "кроме их собственного" — и они будут, наверное, правы...
+> -- Джерри Коффин (Jerry Coffin) об отступах
+
+* Используйте `UTF-8` в качестве кодировки для исходного
+ кода.[[ссылка](#utf-8)]
+
+* Используйте два **пробела** на уровень
+ отступа (т.е. мягкую табуляцию). Никаких знаков табуляции.
+ [[ссылка](#spaces-indentation)]
+
+ ```Ruby
+ # плохо (четыре пробела)
+ def some_method
+ do_something
+ end
+
+ # хорошо
+ def some_method
+ do_something
+ end
+ ```
+
+* Используйте стиль Unix для строк (пользователи
+ *BSD/Solaris/Linux/OS X используют их по умолчанию, пользователям Windows
+ нужно обратить особое внимание).[[ссылка](#crlf)]
+
+ * Если вы используете Git, вы можете добавить следующие настройки
+ в вашу конфигурацию, чтобы предотвратить ненамеренное проникновение в ваш
+ код строк, оканчивающихся в стиле Windows:
+
+ ```bash
+ $ git config --global core.autocrlf true
+ ```
+
+* Не используйте `;` для разделения директив и
+ выражений. Отсюда непосредсвенно следует, что каждая директива должна занимать
+ свою отдельную строку.[[ссылка](#no-semicolon)]
+
+ ```Ruby
+ # плохо (точка с запятой избыточна)
+ puts 'foobar';
+
+ puts 'foo'; puts 'bar' # две директивы на одной строке
+
+ # хорошо
+ puts 'foobar'
+
+ puts 'foo'
+ puts 'bar'
+
+ puts 'foo', 'bar' # это частное правило для `puts`
+ ```
+
+* Используйте преимущественно однострочный
+ формат для определений классов с пустым телом.
+ [[ссылка](#single-line-classes)]
+
+ ```Ruby
+ # плохо
+ class FooError < StandardError
+ end
+
+ # сносно
+ class FooError < StandardError; end
+
+ # хорошо
+ FooError = Class.new(StandardError)
+ ```
+
+* Избегайте однострочных методов. И хотя
+ они достаточно популярны в среде программистов, существует множество
+ неприятных мелочей, связанных с синтаксисом их определения, которые делают
+ применение таких методов нежелательным. В любом случае однострочные методы не
+ должны содержать больше одного выражения.
+ [[ссылка](#no-single-line-methods)]
+
+
+ ```Ruby
+ # плохо
+ def too_much; something; something_else; end
+
+ # сносно (обратите внимание, что первая `;` обязательна)
+ def no_braces_method; body end
+
+ # сносно (обратите внимание, что вторая `;` опциональна)
+ def no_braces_method; body; end
+
+ # сносно (корректный синтаксис, но отсутствие `;` создает трудности при прочтении)
+ def some_method() body end
+
+ # хорошо
+ def some_method
+ body
+ end
+ ```
+
+ Одним исключением в этом правиле являются методы с пустым телом.
+
+ ```Ruby
+ # хорошо
+ def no_op; end
+ ```
+
+* Вставляйте пробелы вокруг операторов, после
+ запятых, двоеточий и точек с запятыми, вокруг `{` и перед `}`.
+ Пробелы (по большей части) игнорируются интерпретатором Руби, но
+ их правильное использование является ключом к написанию легко читаемого кода.
+ [[ссылка](#spaces-operators)]
+
+ ```Ruby
+ sum = 1 + 2
+ a, b = 1, 2
+ [1, 2, 3].each { |e| puts e }
+ class FooError < StandardError; end
+ ```
+
+ Единственным исключением для операторов является оператор степени:
+
+ ```Ruby
+ # плохо
+ e = M * c ** 2
+
+ # хорошо
+ e = M * c**2
+ ```
+
+ `{` и `}` заслуживают некоторого пояснения, так как они используются
+ для блоков и для литералов хешей, а также для интерполяции строк.
+
+ Для литералов хешей два стиля являются общепринятыми:
+
+ ```Ruby
+ # хорошо (пробел после { и до })
+ { one: 1, two: 2 }
+
+ # хорошо (пробелы отсутствуют после { и перед })
+ {one: 1, two: 2}
+ ```
+
+ Первый вариант несколько проще для чтения и, по всей вероятности,
+ более распространен среди членов сообщества программистов на Руби.
+ Второй вариант имеет преимущество в том, что создается видимое различие
+ между блоками и литералами хешей. Какой бы стиль вы ни выбрали, применяйте
+ его единообразно.
+
+* Не используйте пробел после `(`, `[` или перед
+ `]`, `)`.[[ссылка](#no-spaces-braces)]
+
+ ```Ruby
+ some(arg).other
+ [1, 2, 3].size
+ ```
+
+* Не используйте пробел после `!`.
+ [[ссылка](#no-space-bang)]
+
+ ```Ruby
+ # плохо
+ ! something
+
+ # хорошо
+ !something
+ ```
+* Записывайте литералы диапазонов
+ без пробелов.[[link](#no-space-inside-range-literals)]
+
+ ```Ruby
+ # плохо
+ 1 .. 3
+ 'a' ... 'z'
+
+ # хорошо
+ 1..3
+ 'a'...'z'
+ ```
+
+* Делайте отступ для `when` таким же, как и
+ для `case`. Я знаю, что многие не согласятся с этим, но этот стиль
+ предписывается как "Языком программирования Ruby", так и "Programming Ruby".
+ [[ссылка](#indent-when-to-case)]
+
+ ```Ruby
+ # плохо
+ 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
+
+ # хорошо
+ 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
+ ```
+
+* Присваивая результат условного
+ выражения переменной, сохраняйте соответствие уровней отступа.
+ [[ссылка](#indent-conditional-assignment)]
+
+ ```Ruby
+ # плохо (слишком запутано)
+ 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
+
+ result = if some_cond
+ calc_something
+ else
+ calc_something_else
+ 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
+
+ result = if some_cond
+ calc_something
+ else
+ calc_something_else
+ 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
+
+ result =
+ if some_cond
+ calc_something
+ else
+ calc_something_else
+ end
+ ```
+
+* Используйте пустые строки для
+ разделения определений методов и выделения логических частей определений
+ внутри них.[[ссылка](#empty-lines-between-methods)]
+
+ ```Ruby
+ def some_method
+ data = initialize(options)
+
+ data.manipulate!
+
+ data.result
+ end
+
+ def some_method
+ result
+ end
+ ```
+
+
+* Избегайте запятых после последнего
+ параметра в вызове метода, особенно когда параметры расположены в отдельных
+ строках.[[ссылка](#no-trailing-params-comma)]
+
+
+ ```Ruby
+ # плохо, хотя проще перемещать/добавлять/удалять строки
+ some_method(
+ size,
+ count,
+ color,
+ )
+
+ # плохо
+ some_method(size, count, color, )
+
+ # хорошо
+ some_method(size, count, color)
+ ```
+
+* Вставляйте пробелы вокруг оператора
+ присваивания `=`, когда назначаете параметрам метода значения по умолчанию:
+ [[ссылка](#spaces-around-equals)]
+
+
+ ```Ruby
+ # плохо
+ def some_method(arg1=:default, arg2=nil, arg3=[])
+ # do something...
+ end
+
+ # хорошо
+ def some_method(arg1 = :default, arg2 = nil, arg3 = [])
+ # do something...
+ end
+ ```
+
+ Хотя в некоторых книгах по Ruby рекомендуют первый стиль, второй
+ гораздо более нагляден.
+
+* Не используйте символ продления строк `\`
+ везде, где можно обойтись без него. Практически не используйте его нигде,
+ кроме как при конкатенации строк.[[ссылка](#no-trailing-backslash)]
+
+
+ ```Ruby
+ # плохо
+ result = 1 - \
+ 2
+
+ # возможно (но ужасно)
+ result = 1 \
+ - 2
+
+ long_string = 'First part of the long string' \
+ ' and second part of the long string'
+ ```
+
+* Используйте единый стиль
+ многострочных последовательных цепочек вызовов методов. В сообществе Руби
+ популярны два взаимоисключающих стиля их оформления: с точкой в начале
+ (вариант A) и с точкой в конце (вариант B).
+ [[ссылка](#consistent-multi-line-chains)]
+
+ * **A** Когда продолжаете цепочку вызовов методов на
+ следующую строку, начинайте её с точки.
+
+ ```Ruby
+ # плохо - нужно посмотреть на предыдущую строку, чтобы понять
+ # смысл последующей
+ one.two.three.
+ four
+
+ # хорошо - сразу ясно, что происходит во второй строке
+ one.two.three
+ .four
+ ```
+
+ * **B** Соответственно, наоборот, когда продолжаете цепочку
+ вызовов на следующей строке, завершайте строку точкой `.`, давая
+ понять, что продолжение выражения следует
+
+ ```Ruby
+ # плохо - чтобы понять, что выражение не окончено, необходимо
+ # посмотреть на следующую строку.
+ one.two.three
+ .four
+
+ # хорошо - сразу видно, что выражение будет продолжено на
+ # следующей строке
+ one.two.three.
+ four
+ ```
+
+ C аргументами за и против обоих стилей можно ознакомиться в дискуссии
+ [здесь](https://github.com/bbatsov/ruby-style-guide/pull/176).
+
+* Выравнивайте параметры вызова метода, если
+ вызов занимает более одной строки. Если выравнивание невозможно из-за
+ ограничений на длину строки, то используйте одинарный отступ.
+ [[ссылка](#no-double-indent)]
+
+ ```Ruby
+ # первоначальный вариант (строка слишком длинная)
+ def send_mail(source)
+ Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
+ end
+
+ # плохо (двойной отступ)
+ def send_mail(source)
+ Mailer.deliver(
+ to: 'bob@example.com',
+ from: 'us@example.com',
+ subject: 'Important message',
+ body: source.text)
+ end
+
+ # хорошо
+ def send_mail(source)
+ Mailer.deliver(to: 'bob@example.com',
+ from: 'us@example.com',
+ subject: 'Important message',
+ body: source.text)
+ end
+
+ # хорошо (одинарный отступ)
+ def send_mail(source)
+ Mailer.deliver(
+ to: 'bob@example.com',
+ from: 'us@example.com',
+ subject: 'Important message',
+ body: source.text
+ )
+ end
+ ```
+
+* Выравнивайте элементы литералов массива,
+ если они занимают несколько строк.[[ссылка](#align-multiline-arrays)]
+
+ ```Ruby
+ # плохо
+ menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
+ 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
+
+ # хорошо
+ menu_item = [
+ 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
+ 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam'
+ ]
+
+ # хорошо
+ menu_item =
+ ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
+ 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
+ ```
+
+* Добавляйте символ подчеркивания
+ в большие числовые константы для улучшения их восприятия.
+ [[ссылка](#underscores-in-numerics)]
+
+ ```Ruby
+ # плохо (Сколько тут нолей?)
+ num = 1000000
+
+ # хорошо (число воспринимается гораздо легче)
+ num = 1_000_000
+ ```
+
+* Используйте устоявшиеся правила RDoc
+ для описания интерфейсов. Не отделяйте блок комментария от начала определения
+ метода `def` пустой строкой.[[ссылка](#rdoc-conventions)]
+
+* Ограничивайте длину строк 80-ю
+ символами.[[ссылка](#80-character-limits)]
+
+* Не оставляйте пробелы в конце строки.
+ [[ссылка](#no-trailing-whitespace)]
+
+* Завершайте каждый файл переводом строки.
+ [[ссылка](#newline-eof)]
+
+* Не пользуйтесь блочными комментариями. Их
+ нельзя разместить на необходимом уровне отступа. К тому же их сложнее
+ воспринимать, чем обычные комментарии.[[ссылка](#no-block-comments)]
+
+ ```Ruby
+ # плохо
+ =begin
+ строка комментария
+ еще одна строка комментария
+ =end
+
+ # хорошо
+ # строка комментария
+ # другая строка комментария
+ ```
+
+## Синтаксис
+
+*
+ Используйте `::` только для обращения к константам (в том числе к классам и
+ модулям) и конструкторам класса (например, `Array()` или `Nokogiri::HTML()`).
+ Никогда не используйте `::` для обычного вызова методов.
+ [[ссылка](#double-colons)]
+
+ ```Ruby
+ # плохо
+ SomeClass::some_method
+ some_object::some_method
+
+ # хорошо
+ SomeClass.some_method
+ some_object.some_method
+ SomeModule::SomeClass::SOME_CONST
+ SomeModule::SomeClass()
+ ```
+
+*
+ Используйте `def` со скобками, когда у метода есть параметры. Опускайте
+ скобки, когда метод не принимает параметров.
+ [[ссылка](#method-parens)]
+
+ ```Ruby
+ # плохо
+ def some_method()
+ # некоторый код
+ end
+
+ # хорошо
+ def some_method
+ # некоторый код
+ end
+
+ # плохо
+ def some_method_with_parameters param1, param2
+ # некоторый код
+ end
+
+ # хорошо
+ def some_method_with_parameters(param1, param2)
+ # некоторый код
+ end
+ ```
+
+* Используйте оператор `for` только в случаях, когда
+ вы точно знаете, зачем вы это делаете. В подавляющем большинстве остальных случаев
+ стоит применять итераторы. Оператор `for` реализуется при помощи `each` (таким
+ образом вы добавляете еще один уровень абстракции), но с некоторыми отличиями:
+ не создается отдельная область видимости (в отличии от `each`) и переменные,
+ объявленные в теле `for`, будут видны за пределами блока.
+ [[ссылка](#no-for-loops)]
+
+ ```Ruby
+ arr = [1, 2, 3]
+
+ # плохо
+ for elem in arr do
+ puts elem
+ end
+
+ # Учтите, elem доступен за пределами цикла
+ elem #=> 3
+
+ # хорошо
+ arr.each { |elem| puts elem }
+
+ # elem недоступен за пределами блока each
+ elem #=> NameError: undefined local variable or method `elem'
+ ```
+
+* Не используйте `then` для условий `if/unless`,
+ объявленных на нескольких строках.[[ссылка](#no-then)]
+
+ ```Ruby
+ # плохо
+ if some_condition then
+ # некоторое действие
+ end
+
+ # хорошо
+ if some_condition
+ # некоторое действие
+ end
+ ```
+
+
+* Всегда записывайте условие для `if/unless`
+ на той же строке, что содержит `if/then` в многострочном условии.
+ [[ссылка](#same-line-condition)]
+
+ ```Ruby
+ # плохо
+ if
+ some_condition
+ do_something
+ do_something_else
+ end
+
+ # хорошо
+ if some_condition
+ do_something
+ do_something_else
+ end
+ ```
+
+* Предпочитайте тернарный оператор (`?:`)
+ конструкциям с `if/then/else/end`. Он используется чаще и по определению
+ более краток.[[ссылка](#ternary-operator)]
+
+ ```Ruby
+ # плохо
+ result = if some_condition then something else something_else end
+
+ # хорошо
+ result = some_condition ? something : something_else
+ ```
+
+* Используйте только одно выражение в каждой
+ ветви тернарного оператора. Отсюда следует, что лучше избегать вложенных
+ тернарных операторов. При возникновении такой необходимости применяйте
+ конструкции с `if/else`.[[ссылка](#no-nested-ternary)]
+
+ ```Ruby
+ # плохо
+ 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 x: ...`, в Руби 1.9 эту синтаксическую конструкцию удалили,
+ используйте вместо нее тернарные операторы.
+ [[ссылка](#no-1.8-if-syntax)]
+
+ ```Ruby
+ # плохо
+ result = if some_condition: something else something_else end
+
+ # хорошо
+ result = some_condition ? something : something_else
+ ```
+
+*
+ Не используйте точку с запятой в `if x; ...`. Применяйте тернарные операторы.
+ [[ссылка](#no-semicolon-ifs)]
+
+*
+ Извлекайте пользу из такого факта, что `if` и `case` являются выражениями,
+ возвращающими результирующие значения.
+ [[ссылка](#use-if-case-returns)]
+
+ ```Ruby
+ # плохо
+ if condition
+ result = x
+ else
+ result = y
+ end
+
+ # хорошо
+ result =
+ if condition
+ x
+ else
+ y
+ end
+ ```
+
+* Применяйте `when x then ...` для однострочных
+ выражений. Вариант записи `when x: ...` был удален, начиная с Руби 1.9.
+ [[ссылка](#one-line-cases)]
+
+* Не используйте `when x; ...` по аналогии
+ с предыдущим правилом.[[ссылка](#no-when-semicolons)]
+
+* Используйте `!` вместо `not`.
+ [[ссылка](#bang-not-not)]
+
+ ```Ruby
+ # плохо (необходимы скобки из-за неоднозначности приоритетов операторов)
+ x = (not something)
+
+ # хорошо
+ x = !something
+ ```
+
+* Не используйте `!!`.
+ [[ссылка](#no-bang-bang)]
+
+ ```Ruby
+ # плохо
+ x = 'test'
+ # неявная проверка на nil
+ if !!x
+ # некоторое выражение
+ end
+
+ x = false
+ # двойное отрицание бессмысленно для булевых значений
+ !!x # => false
+
+ # хорошо
+ x = 'test'
+ unless x.nil?
+ # некоторое выражение
+ end
+ ```
+
+* Ключевые слова `and` и `or` следует забыть. Они
+ не несут дополнительной пользы. Всегда используйте `&&` и `||` вместо них.
+ [[ссылка](#no-and-or-or)]
+
+ ```Ruby
+ # плохо
+ # булево выражение
+ if some_condition and some_other_condition
+ do_something
+ end
+
+ # управление потоком исполнения
+ document.saved? or document.save!
+
+ # хорошо
+ # булево выражение
+ if some_condition && some_other_condition
+ do_something
+ end
+
+ # управление потоком исполнения
+ document.saved? || document.save!
+ ```
+
+* Избегайте многострочных тернарных
+ операторов `? :`. Используйте вместо них `if/unless`.
+ [[ссылка](#no-multiline-ternary)]
+
+* Для однострочных выражений по возможности
+ модификатор `if/unless`. Другим хорошим вариантом являются операторы
+ управления потоком исполнения `&&/||`.
+ [[ссылка](#if-as-a-modifier)]
+
+ ```Ruby
+ # плохо
+ if some_condition
+ do_something
+ end
+
+ # хорошо
+ do_something if some_condition
+
+ # еще хороший вариант
+ some_condition && do_something
+ ```
+
+* Избегайте `if/unless` в конце
+ нетривиального многострочного блока.
+ [[ссылка](#no-multiline-if-modifiers)]
+
+ ```Ruby
+ # плохо
+ 10.times do
+ # multi-line body omitted
+ end if some_condition
+
+ # хорошо
+ if some_condition
+ 10.times do
+ # multi-line body omitted
+ end
+ end
+ ```
+
+* Используйте `unless` вместо `if`
+ для отрицательных условий (или `||` для управления потоком исполнения).
+ [[ссылка](#unless-for-negatives)]
+
+ ```Ruby
+ # плохо
+ do_something if !some_condition
+
+ # плохо
+ do_something if not some_condition
+
+ # хорошо
+ do_something unless some_condition
+
+ # тоже хорошо
+ some_condition || do_something
+ ```
+
+* Не используйте `unless` вместе с `else`.
+ Перепишите такие выражение с положительной проверкой.
+ [[ссылка](#no-else-with-unless)]
+
+ ```Ruby
+ # плохо
+ unless success?
+ puts 'failure'
+ else
+ puts 'success'
+ end
+
+ # хорошо
+ if success?
+ puts 'success'
+ else
+ puts 'failure'
+ end
+ ```
+
+* Не используйте скобки для ограничения условных
+ выражений в `if/unless/while/until`.[[ссылка](#no-parens-if)]
+
+ ```Ruby
+ # плохо
+ if (x > 10)
+ # код опущен для краткости
+ end
+
+ # хорошо
+ if x > 10
+ # код опущен для краткости
+ end
+ ```
+ Однако в этом правиле есть некоторые исключения, например,
+ [надежные присвоения в условных выражениях](#safe-assignment-in-condition).
+
+* Не используйте `while/until УСЛОВИЕ do`
+ для многострочных циклов с `while/until`.
+ [[ссылка](#no-multiline-while-do)]
+
+ ```Ruby
+ # плохо
+ while x > 5 do
+ # код опущен для краткости
+ end
+
+ until x > 5 do
+ # код опущен для краткости
+ end
+
+ # хорошо
+ while x > 5
+ # код опущен для краткости
+ end
+
+ until x > 5
+ # код опущен для краткости
+ end
+ ```
+
+* Используйте `while/until` для однострочный
+ выражений.[[ссылка](#while-as-a-modifier)]
+
+ ```Ruby
+ # плохо
+ while some_condition
+ do_something
+ end
+
+ # хорошо
+ do_something while some_condition
+ ```
+* Используйте `until` вместо `while`
+ для условий на отрицания.[[ссылка](#until-for-negatives)]
+
+ ```Ruby
+ # плохо
+ do_something while !some_condition
+
+ # хорошо
+ do_something until some_condition
+ ```
+* Используйте `Kernel#loop` вместо `while/until`
+ для бесконечного цикла.[[ссылка](#infinite-loop)]
+
+ ```Ruby
+ # плохо
+ while true
+ do_something
+ end
+
+ until false
+ do_something
+ end
+
+ # хорошо
+ loop do
+ do_something
+ end
+ ```
+
+* Используйте `Kernel#loop` с `break` вместо
+ `begin/end/until` или `begin/end/while` для циклов с постусловием.
+ [[ссылка](#loop-with-break)]
+
+ ```Ruby
+ # плохо
+ begin
+ puts val
+ val += 1
+ end while val < 0
+
+ # хорошо
+ loop do
+ puts val
+ val += 1
+ break unless val < 0
+ end
+ ```
+
+* Не используйте скобки при вызове методов,
+ являющихся частью таких DSL, как Rake, Rails, RSpec, методов, имеющих
+ статус ключевого слова, например, `attr_reader`, `puts` и при вызове
+ аксессоров. Используйте скобки при вызове прочих методов.
+ [[ссылка](#no-dsl-parens)]
+
+ ```Ruby
+ class Person
+ attr_reader :name, :age
+
+ # omitted
+ end
+
+ temperance = Person.new('Temperance', 30)
+ temperance.name
+
+ puts temperance.age
+
+ x = Math.sin(y)
+ array.delete(e)
+
+ bowling.score.should == 0
+ ```
+
+* Не используйте фигурные скобки для
+ ограничения хешей, передаваемых методу.
+ [[ссылка](#no-braces-opts-hash)]
+
+ ```Ruby
+ # плохо
+ user.set({ name: 'John', age: 45, permissions: { read: true } })
+
+ # хорошо
+ user.set(name: 'John', age: 45, permissions: { read: true })
+ ```
+
+* Не используйте фигурные скобки для
+ ограничения хешей, передаваемых методу, и скобки вокруг параметров для
+ методов, являющихся частью DSL.
+ [[ссылка](#no-dsl-decorating)]
+
+ ```Ruby
+ class Person < ActiveRecord::Base
+ # плохо
+ validates(:name, { presence: true, length: { within: 1..10 } })
+
+ # хорошо
+ validates :name, presence: true, length: { within: 1..10 }
+ end
+ ```
+
+* Опускайте скобки при вызове метода без
+ параметров.
+ [[ссылка](#no-args-no-parens)]
+
+
+ ```Ruby
+ # плохо
+ Kernel.exit!()
+ 2.even?()
+ fork()
+ 'test'.upcase()
+
+ # хорошо
+ Kernel.exit!
+ 2.even?
+ fork
+ 'test'.upcase
+ ```
+
+*
+ Используйте краткую форму для вызова `proc`, если вызываемый метод является
+ единственным в блоке.
+ [[link](#single-action-blocks)]
+
+ ```Ruby
+ # плохо
+ names.map { |name| name.upcase }
+
+ # хорошо
+ names.map(&:upcase)
+ ```
+
+* Используйте преимущественно `{...}` в случае
+ однострочных блоков, а `do...end` в случае многострочных блоков (многострочные
+ последовательности вызовов методов всегда выглядят ужасно). Старайтесь
+ применять `do...end` для логических операций и определений методов (например,
+ для Rakefile и некоторых DSL). Не используйте `do...end` в цепочках вызовов.
+ [[ссылка](#single-line-blocks)]
+
+ ```Ruby
+ names = %w(Bozhidar Steve Sarah)
+
+ # плохо
+ names.each do |name|
+ puts name
+ end
+
+ # хорошо
+ names.each { |name| puts name }
+
+ # плохо
+ names.select do |name|
+ name.start_with?('S')
+ end.map { |name| name.upcase }
+
+ # хорошо
+ names.select { |name| name.start_with?('S') }.map(&:upcase)
+ ```
+
+ Некоторые из нас поспорят, что многострочные последовательные вызовы с блоками
+ при использовании {...} выглядят неплохо, но тогда стоит себя спросить, а
+ читается ли такой код и не стоит ли выделить эти блоки в отдельные специальные
+ методы.
+
+* Попробуйте использовать блоки напрямую в виде
+ аргумента в случае, когда блок просто передает свои аргументы в другой блок.
+ В этом случае обратите внимание на падение производительности, так как
+ аргументы будут преобразованы в объект класс `Proc`.
+ [[ссылка](#block-argument)]
+
+ ```Ruby
+ require 'tempfile'
+
+ # плохо
+ def with_tmp_dir
+ Dir.mktmpdir do |tmp_dir|
+ # блок просто передает аргументы дальше
+ Dir.chdir(tmp_dir) { |dir| yield dir }
+ end
+ end
+
+ # хорошо
+ def with_tmp_dir(&block)
+ Dir.mktmpdir do |tmp_dir|
+ Dir.chdir(tmp_dir, &block)
+ end
+ end
+
+ with_tmp_dir do |dir|
+ puts "dir доступен в виде параметра, и pwd имеет значение: #{dir}"
+ end
+ ```
+
+* Избегайте ключевого слова `return` везде,
+ где это не нужно для управления ветвлением.
+ [[ссылка](#no-explicit-return)]
+
+ ```Ruby
+ # плохо
+ def some_method(some_arr)
+ return some_arr.size
+ end
+
+ # хорошо
+ def some_method(some_arr)
+ some_arr.size
+ end
+ ```
+
+* Избегайте ключевого слова `self` везде,
+ где оно не требуется. Оно необходимо только при вызове методов доступа
+ (`attr_reader`, `attr_writer`, `attr_accessor`).
+ [[ссылка](#no-self-unless-required)]
+
+ ```Ruby
+ # плохо
+ def ready?
+ if self.last_reviewed_at > self.last_updated_at
+ self.worker.update(self.content, self.options)
+ self.status = :in_progress
+ end
+ self.status == :verified
+ end
+
+ # хорошо
+ def ready?
+ if last_reviewed_at > last_updated_at
+ worker.update(content, options)
+ self.status = :in_progress
+ end
+ status == :verified
+ end
+ ```
+
+* В качестве бездоказательного утверждения:
+ избегайте маскирования методов локальными переменными, если они не
+ эквивалентны.
+ [[ссылка](#no-shadowing)]
+
+ ```Ruby
+ class Foo
+ attr_accessor :options
+
+ # cносно
+ # как options, так и self.options здесь эквивалентны
+ def initialize(options)
+ self.options = options
+ end
+
+ # плохо
+ def do_something(options = {})
+ unless options[:when] == :later
+ output(self.options[:message])
+ end
+ end
+
+ # хорошо
+ def do_something(params = {})
+ unless params[:when] == :later
+ output(options[:message])
+ end
+ end
+ end
+ ```
+
+* Используйте возвращаемое
+ оператором присваивания (`=`) значение только в случаях, когда все
+ выражение стоит в скобках. Эта идиома достаточно распространена среди
+ программистов на Руби и часто называется *надежное присваивание в логических
+ выражениях*.
+ [[ссылка](#safe-assignment-in-condition)]
+
+
+ ```Ruby
+ # плохо (к тому же вызывает предупреждение)
+ if v = array.grep(/foo/)
+ do_something(v)
+ ...
+ end
+
+ # хорошо (MRI будет вызывает предупреждение, но не Рубокоп)
+ if (v = array.grep(/foo/))
+ do_something(v)
+ ...
+ end
+
+ # хорошо
+ v = array.grep(/foo/)
+ if v
+ do_something(v)
+ ...
+ end
+ ```
+
+*
+ По возможности используйте сокращенные операторы присваивания.
+ [[ссылка](#self-assignment)]
+
+ ```Ruby
+ # плохо
+ x = x + y
+ x = x * y
+ x = x**y
+ x = x / y
+ x = x || y
+ x = x && y
+
+ # хорошо
+ x += y
+ x *= y
+ x **= y
+ x /= y
+ x ||= y
+ x &&= y
+ ```
+
+*
+ Используйте оператор `||=` для инициализации переменных, только если
+ переменная еще не инициализирована.
+ [[ссылка](#double-pipe-for-uninit)]
+
+ ```Ruby
+ # плохо
+ name = name ? name : 'Bozhidar'
+
+ # плохо
+ name = 'Bozhidar' unless name
+
+ # хорошо (присвоить переменной name значение Bozhidar, только если ее значение
+ # nil или false
+ name ||= 'Bozhidar'
+ ```
+
+*
+ Не используйте оператор `||=` для инициализации логических переменных.
+ Это вызовет проблемы, если текущим значением переменной будет `false`.
+ [[ссылка](#no-double-pipes-for-bools)]
+
+ ```Ruby
+ # плохо (назначит переменной enabled значение true, даже если оно было false)
+ enabled ||= true
+
+ # хорошо
+ enabled = true if enabled.nil?
+ ```
+
+*
+ Используйте оператор `&&=` для предварительной работы с переменными, которые
+ уже или еще не инициализированы. Использование оператора `&&=` изменит
+ значение переменной, только если она инициализирована. При этом отпадает
+ необходимость в проверке с `if`.
+ [[ссылка](#double-amper-preprocess)]
+
+ ```Ruby
+ # плохо
+ if something
+ something = something.downcase
+ end
+
+ # плохо
+ something = something ? something.downcase : nil
+
+ # сносно
+ something = something.downcase if something
+
+ # хорошо
+ something = something && something.downcase
+
+ # еще лучше
+ something &&= something.downcase
+ ```
+
+*
+ Избегайте явного использования оператора равенства в case `===`. Как
+ подсказывает его имя, этот оператор предназначен для имплицитного
+ применения в выражениях `case`, в отрыве от них он приводит только к
+ разночтениям в коде.
+ [[ссылка](#no-case-equality)]
+
+ ```Ruby
+ # плохо
+ Array === something
+ (1..100) === 7
+ /something/ === some_string
+
+ # хорошо
+ something.is_a?(Array)
+ (1..100).include?(7)
+ some_string =~ /something/
+ ```
+*
+ Не используйте `eql?`, если будет достаточно `==`. Более строгая семантика
+ сравнения, реализованная в `eql?`, достаточно редко нужна на практике.
+ [[link](#eql)]
+
+ ```Ruby
+ # плохо (`eql?` работает для строк, как и `==`)
+ "ruby".eql? some_str
+
+ # хорошо
+ "ruby" == some_str
+ 1.0.eql? x # здесь `eql?` имеет смысл, если вы хотите различать классы числа: `Fixnum` vs. `Float`
+ ```
+
+*
+ Избегайте специальных переменных, заимствованых из языка Перл, например, `$:`,
+ `$;` и т.д. Они сложно воспринимаются, и их использование приветствуется
+ только в однострочных скриптах. В остальных случаях применяйте легкие для
+ восприятия варианты этих переменных из библиотеки `English`.
+ [[ссылка](#no-cryptic-perlisms)]
+
+ ```Ruby
+ # плохо
+ $:.unshift File.dirname(__FILE__)
+
+ # хорошо
+ require 'English'
+ $LOAD_PATH.unshift File.dirname(__FILE__)
+ ```
+
+*
+ Не оставляйте пробел между именем метода и открывающей скобкой.
+ [[ссылка](#parens-no-spaces)]
+
+ ```Ruby
+ # плохо
+ f (3 + 2) + 1
+
+ # хорошо
+ f(3 + 2) + 1
+ ```
+
+*
+ Если первый аргумент при вызове метода начинается скобкой, то всегда
+ используйте скобки при вызове метода. Например, пишем так: `f((3 + 2) + 1)`.
+ [[ссылка](#parens-as-args)]
+
+*
+ Всегда вызывайте интерпретатор Руби с ключом `-w`, чтобы получать напоминия о
+ правилах, описанных выше, даже если вы о них забываете.
+ [[ссылка](#always-warn-at-runtime)]
+
+*
+ Используйте новый синтаксис лямбда-выражений для однострочных блоков. Используйте
+ метод `lambda` для многострочных блоков.
+ [[ссылка](#lambda-multi-line)]
+
+ ```Ruby
+ # плохо
+ l = lambda { |a, b| a + b }
+ l.call(1, 2)
+
+ # верно, но выглядит очень странно
+ l = ->(a, b) do
+ tmp = a * 7
+ tmp * b / 50
+ end
+
+ # хорошо
+ l = ->(a, b) { a + b }
+ l.call(1, 2)
+
+ l = lambda do |a, b|
+ tmp = a * 7
+ tmp * b / 50
+ end
+ ```
+
+*
+ Используйте `proc` вместо `Proc.new`.
+ [[ссылка](#proc)]
+
+ ```Ruby
+ # плохо
+ p = Proc.new { |n| puts n }
+
+ # хорошо
+ p = proc { |n| puts n }
+ ```
+
+*
+ Используйте `proc.call()` вместо `proc[]` или `proc.()` для
+ лямбда-выражений и блоков.
+ [[ссылка](#proc-call)]
+
+ ```Ruby
+ # плохо (выглядит как доступ к энумератору)
+ l = ->(v) { puts v }
+ l[1]
+
+ # тоже плохо (редкая формулировка)
+ l = ->(v) { puts v }
+ l.(1)
+
+ # хорошо
+ l = ->(v) { puts v }
+ l.call(1)
+ ```
+
+*
+ Начинайте неиспользуемые параметры блока с подчеркивания `_`. Также допустимо
+ использовать только подчеркивание `_`, хотя это и менее информативно. Эта
+ договоренность распознается интерпретатором Руби и Рубокопом и уберет
+ предупреждения о неиспользуемых переменных.
+ [[ссылка](#underscore-unused-vars)]
+
+ ```Ruby
+ # плохо
+ result = hash.map { |k, v| v + 1 }
+
+ def something(x)
+ unused_var, used_var = something_else(x)
+ # ...
+ end
+
+ # хорошо
+ result = hash.map { |_k, v| v + 1 }
+
+ def something(x)
+ _unused_var, used_var = something_else(x)
+ # ...
+ end
+
+ # хорошо
+ result = hash.map { |_, v| v + 1 }
+
+ def something(x)
+ _, used_var = something_else(x)
+ # ...
+ end
+ ```
+
+*
+ Используйте переменные `$stdout/$stderr/$stdin` вместо констант
+ `STDOUT/STDERR/STDIN`. `STDOUT/STDERR/STDIN` являются константами, поэтому при
+ их переопределении (вы это можете сделать, например, для перенаправления
+ ввода-вывода) интерпретатор будет выдавать предупреждения.
+ [[ссылка](#global-stdout)]
+
+*
+ Используйте `warn` вместо `$stderr.puts`. Это не только короче, но и позволит
+ вам скрыть все предупреждения, если вам это понадобится (для этого задайте
+ уроверь предупреждений равный `0` при помощи опции `-W0`).
+ [[ссылка](#warn)]
+
+*
+ Используйте `sprintf` и его алиас `format` вместо довольно запутанного метода
+ `String#%`.
+ [[ссылка](#sprintf)]
+
+ ```Ruby
+ # плохо
+ '%d %d' % [20, 10]
+ # => '20 10'
+
+ # хорошо
+ sprintf('%d %d', 20, 10)
+ # => '20 10'
+
+ # хорошо
+ sprintf('%{first} %{second}', first: 20, second: 10)
+ # => '20 10'
+
+ format('%d %d', 20, 10)
+ # => '20 10'
+
+ # хорошо
+ format('%{first} %{second}', first: 20, second: 10)
+ # => '20 10'
+ ```
+
+*
+ Используйте `Array#join` вместо достаточно неочевидного `Array#*` со строковым
+ аргументом.
+ [[ссылка](#array-join)]
+
+ ```Ruby
+ # плохо
+ %w(one two three) * ', '
+ # => 'one, two, three'
+
+ # хорошо
+ %w(one two three).join(', ')
+ # => 'one, two, three'
+ ```
+
+*
+ Используйте `[*var]` или `Array()` вместо явной проверки с помощью `Array`,
+ когда вам приходится работать с переменной, которая по вашим ожиданиям должна
+ быть массивом, но вы в этом не полностью уверены.
+ [[ссылка](#splat-arrays)]
+
+ ```Ruby
+ # плохо
+ paths = [paths] unless paths.is_a? Array
+ paths.each { |path| do_something(path) }
+
+ # хорошо
+ [*paths].each { |path| do_something(path) }
+
+ # хорошо (and a bit more readable)
+ Array(paths).each { |path| do_something(path) }
+ ```
+
+*
+ Используйте интервалы или метод `Comparable#between?` вместо сложной логики
+ для сравнения, когда это возможно.
+ [[ссылка](#ranges-or-between)]
+
+ ```Ruby
+ # плохо
+ do_something if x >= 1000 && x <= 2000
+
+ # хорошо
+ do_something if (1000..2000).include?(x)
+
+ # хорошо
+ do_something if x.between?(1000, 2000)
+ ```
+
+*
+ Используйте предикативные методы вместо явного сравнения с использованием
+ `==`. Сравнение чисел можно проводить явно.
+ [[ссылка](#predicate-methods)]
+
+ ```Ruby
+ # плохо
+ if x % 2 == 0
+ end
+
+ if x % 2 == 1
+ end
+
+ if x == nil
+ end
+
+ # хорошо
+ if x.even?
+ end
+
+ if x.odd?
+ end
+
+ if x.nil?
+ end
+
+ if x.zero?
+ end
+
+ if x == 0
+ end
+ ```
+
+*
+ Проводите явную проверку на значение `nil`, только если вы работаете
+ с логическими значениями.
+ [[ссылка](#no-non-nil-checks)]
+
+ ```Ruby
+ # плохо
+ do_something if !something.nil?
+ do_something if something != nil
+
+ # хорошо
+ do_something if something
+
+ # хорошо (логическое значение)
+ def value_set?
+ !@some_boolean.nil?
+ end
+ ```
+
+*
+ Старайтесь не использовать блоки `BEGIN`.
+ [[ссылка](#no-BEGIN-blocks)]
+
+*
+ Никогда не используйте блоки `END`. Используйте метод `Kernel#at_exit`.
+ [[ссылка](#no-END-blocks)]
+
+ ```Ruby
+ # плохо
+ END { puts 'Goodbye!' }
+
+ # хорошо
+ at_exit { puts 'Goodbye!' }
+ ```
+
+*
+ Избегайте переменных-перевертышей (flip-flops).
+ [[ссылка](#no-flip-flops)]
+
+*
+ Избегайте вложенных условий для управления ветвлением. Используйте проверочные
+ выражения (guard clauses). Проверочные выражения - это условные выражения
+ в самом начале функции, которые срабатывают при первой же возможности.
+ [[ссылка](#no-nested-conditionals)]
+
+ ```Ruby
+ # плохо
+ def compute_thing(thing)
+ if thing[:foo]
+ update_with_bar(thing)
+ if thing[:foo][:bar]
+ partial_compute(thing)
+ else
+ re_compute(thing)
+ end
+ end
+ end
+
+ # хорошо
+ def compute_thing(thing)
+ return unless thing[:foo]
+ update_with_bar(thing[:foo])
+ return re_compute(thing) unless thing[:foo][:bar]
+ partial_compute(thing)
+ end
+ ```
+
+ Используйте в циклах `next` в место блоков с условием.
+
+ ```Ruby
+ # плохо
+ [0, 1, 2, 3].each do |item|
+ if item > 1
+ puts item
+ end
+ end
+
+ # хорошо
+ [0, 1, 2, 3].each do |item|
+ next unless item > 1
+ puts item
+ end
+ ```
+
+## Наименование
+
+> Единственными настоящими сложностями в программировании являются очистка кэша
+> и выбор наименований.
+> -- Фил Карлтон (Phil Karlton)
+
+* Используйте английский язык, называя
+ идентификаторы.[[ссылка](#english-identifiers)]
+
+ ```Ruby
+ # плохо (идентификатор использует символы вне ASCII)
+ зарплата = 1_000
+
+ # плохо (идентификатор - это русское слово, набранное латиницей вместо
+ # кириллицы)
+ zarplata = 1_000
+
+ # хорошо
+ salary = 1_000
+ ```
+
+* Используйте `snake_case` для
+ имен символов, методов и переменных.
+ [[ссылка](#snake-case-symbols-methods-vars)]
+
+ ```Ruby
+ # плохо
+ :'some symbol'
+ :SomeSymbol
+ :someSymbol
+
+ someVar = 5
+
+ def someMethod
+ ...
+ end
+
+ def SomeMethod
+ ...
+ end
+
+ # хорошо
+ :some_symbol
+
+ def some_method
+ ...
+ end
+ ```
+
+* Используйте `CamelCase` для имен классов и
+ модулей. Сокращения вроде `HTTP`, `RFC`, `XML` набирайте заглавными буквами.
+ [[ссылка](#camelcase-classes)]
+
+ ```Ruby
+ # плохо
+ class Someclass
+ ...
+ end
+
+ class Some_Class
+ ...
+ end
+
+ class SomeXml
+ ...
+ end
+
+ # хорошо
+ class SomeClass
+ ...
+ end
+
+ class SomeXML
+ ...
+ end
+ ```
+
+* Используйте `snake_case`, называя файлы,
+ например, `hello_world.rb`.[[ссылка](#snake-case-files)]
+
+* Используйте `snake_case`, называя каталоги,
+ например, `lib/hello_world/hello_world.rb`.
+ [[ссылка](#snake-case-dirs)]
+
+* Старайтесь создавать только один класс или
+ модуль в каждом файле исходного кода. Называйте эти файлы по имени класса или
+ модуля, изменив запись в форме `CamelCase` на `snake_case`.
+ [[ссылка](#one-class-per-file)]
+
+* Используйте `SCREAMING_SNAKE_CASE` для
+ всех других констант кроме имен классов и модулей.
+ [[ссылка](#screaming-snake-case)]
+
+ ```Ruby
+ # плохо
+ SomeConst = 5
+
+ # хорошо
+ SOME_CONST = 5
+ ```
+
+* Идентификаторы предикативных методов, т.е.
+ методов, возвращающих логическое значение, должны оканчиваться вопросительным
+ знаком. Например, `Array#empty?`. Методы, не возвращающие логическое значение,
+ не должны оканчиваться вопросительным знаком.
+ [[ссылка](#bool-methods-qmark)]
+
+* Идентификаторы потенциально *опасных*
+ методов, т.е. таких методов, которые могут именить `self` или его аргументы,
+ должны оканчиваться восклицательным знаком, если есть соответствующий
+ *безопасный* вариант такого метода. Например, `exit!`, который не вызывает
+ завершающий скрипт в отличии от `exit`, выполняющего финализацию.
+ [[ссылка](#dangerous-method-bang)]
+
+ ```Ruby
+ # плохо (нет соответсвующего безопасного аналога)
+ class Person
+ def update!
+ end
+ end
+
+ # хорошо
+ class Person
+ def update
+ end
+ end
+
+ # хорошо
+ class Person
+ def update!
+ end
+
+ def update
+ end
+ end
+ ```
+
+* Определяйте безопасный метод (вариант
+ без восклицательного знака) при помощи вызова опасного метода (с
+ восклицательным знаком), если это возможно.
+ [[ссылка](#safe-because-unsafe)]
+
+ ```Ruby
+ class Array
+ def flatten_once!
+ res = []
+
+ each do |e|
+ [*e].each { |f| res << f }
+ end
+
+ replace(res)
+ end
+
+ def flatten_once
+ dup.flatten_once!
+ end
+ end
+ ```
+
+* При использовании `#reduce` с коротким блоком,
+ называйте аргументы `|a, e|` (accumulator, element).
+ [[ссылка](#reduce-blocks)]
+
+*
+ При определении бинарных операторов называйте параметр `other`. Исключение
+ составляют методы `#<<` и `#[]`, так как их семантика сильно отличается.
+ [[ссылка](#other-arg)]
+
+ ```Ruby
+ def +(other)
+ # некоторый код
+ end
+ ```
+
+* Используйте `#map` вместо
+ `#collect`, `#find` вместо `#detect`, `#select` вместо `#find_all`,
+ `#reduce` вместо `#inject` и `#size` вместо `#length`. Это требование
+ не сложно реализовать. Если использование альтернатив улучшит восприятие кода,
+ то можно использовать и их. Все описанные варианты были взяты из языка
+ Smalltalk и не распространены в других языках программирования. Причиной,
+ почему не следует использовать `#find_all` вместо `#select`, является хорошая
+ сочетаемость с методом `#reject`, и эти наименования очевидны.
+ [[ссылка](#map-find-select-reduce-size)]
+
+* Не используйте `#count` в качестве заметы для
+ `#size`. Для объектов классов с включенным `Enumerable` (кроме класса`Array`)
+ это приведет к затратному полному обходу всех элементов для определения
+ размера.[[ссылка](#count-vs-size)]
+
+ ```Ruby
+ # плохо
+ some_hash.count
+
+ # хорошо
+ some_hash.size
+ ```
+
+* Используйте `#flat_map` вместо `#map` + `#flatten`.
+ Это правило не относится к массивам с глубиной больше 2, например, если
+ `users.first.songs == ['a', ['b', 'c']]`, то используйте `#map` + `#flatten`,
+ а не `#flat_map`. Метод `#flat_map` уменьшает глубину на один уровень. Метод
+ `#flatten` сглаживает вложенность любого уровня.
+ [[ссылка](#flat-map)]
+
+ ```Ruby
+ # плохо
+ all_songs = users.map(&:songs).flatten.uniq
+
+ # хорошо
+ all_songs = users.flat_map(&:songs).uniq
+ ```
+
+*
+ Используйте метод `#reverse_each` вместо `#reverse.each`, так как некоторые
+ классы, включающие в себя модуль `Enumerable`, дадут вам очень эффективную
+ реализацию. Даже в худшем случае, когда класс не реализует этот метод
+ отдельно, наследуемая реализация из модуля `Enumerable` будет по меньшей мере
+ такой же эффективной, как и для `#reverse.each`.
+ [[ссылка](#reverse-each)]
+
+ ```Ruby
+ # плохо
+ array.reverse.each { ... }
+
+ # хорошо
+ array.reverse_each { ... }
+ ```
+
+## Комментарии
+
+> Хороший код является лучшей документацией для себя. Каждый раз, когда вы
+> готовитесь добавить комментарий, спросите себя: "Как я могу улучшить код,
+> чтобы это комментарий стал ненужным?" Улучшите код и добавьте комментарий,
+> чтобы сделать его еще понятнее.
+> -- Стив Макконнел (Steve McConnell)
+
+*
+ Пишите говорящий за себя код и смело пропускайте все остальное в этом разделе.
+ Серьезно!
+ [[ссылка](#no-comments)]
+
+*
+ Пишите комментарии по-английски.
+ [[ссылка](#english-comments)]
+
+*
+ Используйте один пробел между символом `#` в начале и текстом самого
+ комментария.
+ [[ссылка](#hash-space)]
+
+* Комментарии длиной больше одного слова должны
+ оформляться в виде законченных предложений (с большой буквы и со знаками
+ препинания).
+ Разделяйте предложения [одним пробелом](http://en.wikipedia.org/wiki/Sentence_spacing).
+ [[ссылка](#english-syntax)]
+
+* Избегайте избыточного комментирования.
+ [[ссылка](#no-superfluous-comments)]
+
+ ```Ruby
+ # плохо
+ counter += 1 # Увеличивает счетчик на единицу.
+ ```
+
+* Актуализируйте существующие комментарии.
+ Устаревший комментарий гораздо хуже отсутствующего комментария.
+ [[ссылка](#comment-upkeep)]
+
+> Хороший код подобен хорошей шутке: он не нуждается в пояснениях.
+> -- Рус Ольсен (Russ Olsen)
+
+* Не пишите комментарии для объяснения
+ плохого кода. Перепишите код, чтобы он говорил сам за себя.
+ [[ссылка](#refactor-dont-comment)]
+
+> Делай или не делай, тут нет места попыткам.
+> -- Мастер Йода
+
+### Пометки в комментариях
+
+* Обычно пометки следует записывать
+ на предшествующей описываемому коду строке.[[ссылка](#annotate-above)]
+
+* Пометка отделяется двоеточием и пробелом, потом
+ следует примечание, описывающее проблему.[[ссылка](#annotate-keywords)]
+
+*
+ Если для описания проблемы потребуются несколько строк, то на каждой
+ последующей строке следует сделать отступ в три пробела после символа `#`.
+ [[ссылка](#indent-annotations)]
+
+ ```Ruby
+ def bar
+ # FIXME: This has crashed occasionally since v3.2.1. It may
+ # be related to the BarBazUtil upgrade.
+ baz(:quux)
+ end
+ ```
+
+* В тех случаях, когда проблема настолько
+ очевидна, что любые описания покажутся избыточными, пометки можно поставить
+ в конце вызывающей проблему строки. Однако такое применение должно быть
+ исключением, а не правилом.[[ссылка](#rare-eol-annotations)]
+
+ ```Ruby
+ def bar
+ sleep 100 # OPTIMIZE
+ end
+ ```
+
+*
+ Используйте `TODO`, чтобы пометить отсутствующие возможности или функционал,
+ которые должны быть добавлены позже.
+ [[ссылка](#todo)]
+
+*
+ Используйте `FIXME`, чтобы пометить код с ошибками, который должен быть
+ исправлен.
+ [[ссылка](#fixme)]
+
+*
+ Используйте `OPTIMIZE`, чтобы пометить медленный или неэффективный код,
+ который может вызвать проблемы с производительностью.
+ [[ссылка](#optimize)]
+
+*
+ Используйте `HACK`, чтобы пометить код "с душком", который должен быть
+ переработан и использует сомнительные практики разработки.
+ [[ссылка](#hack)]
+
+*
+ Используйте `REVIEW`, чтобы пометить все, что должно быть проверено на
+ работоспособность. Например, `REVIEW: Are we sure this is how the client does
+ X currently?`.
+ [[ссылка](#review)]
+
+*
+ Используйте персональные пометки, если это подходит по месту, но обязательно
+ опишите их смысл в файле `README` (или похожем) для вашего проекта.
+ [[ссылка](#document-annotations)]
+
+## Классы и модули
+
+* Придерживайтесь единообразной структуры
+ классов.[[ссылка](#consistent-classes)]
+
+ ```Ruby
+ class Person
+ # extend и include в начале
+ extend SomeModule
+ include AnotherModule
+
+ # вложенные классы
+ CustomErrorKlass = Class.new(StandardError)
+
+ # после этого константы
+ SOME_CONSTANT = 20
+
+ # после этого макросы методов доступа к атрибутам
+ attr_reader :name
+
+ # и все прочие макросы (если имеются)
+ validates :name
+
+ # следующими по списку будут публичные методы класса
+ def self.some_method
+ end
+
+ # инициализация объекта стоит между методами класса и экземпляров
+ def initialize
+ end
+
+ # и следующие за ними публичные методы экземпляров этого класса
+ def some_method
+ end
+
+ # защищенные и частные методы нужно собрать ближе к концу
+ protected
+
+ def some_protected_method
+ end
+
+ private
+
+ def some_private_method
+ end
+ end
+ ```
+
+*
+ Если определение класса занимает несколько строк, постарайтесь вынести такой
+ класс в отдельный файл. Файл с определением стоит поместить в директорию,
+ названную по имени родительского класса, внутри которого определяется
+ вложенный класс.
+ [[ссылка](#file-classes)]
+
+ ```Ruby
+ # плохо
+
+ # foo.rb
+ class Foo
+ class Bar
+ # 30 методов внутри
+ end
+
+ class Car
+ # 20 методов внутри
+ end
+
+ # 30 методов внутри
+ end
+
+ # хорошо
+
+ # foo.rb
+ class Foo
+ # 30 методов внутри
+ end
+
+ # foo/bar.rb
+ class Foo
+ class Bar
+ # 30 методов внутри
+ end
+ end
+
+ # foo/car.rb
+ class Foo
+ class Car
+ # 20 методов внутри
+ end
+ end
+ ```
+
+* Если класс определяет только методы класса,
+ то трансформируйте такой класс в модуль. Использовать классы логично в тех
+ ситуациях, когда нужно создавать экземпляры класса.
+ [[ссылка](#modules-vs-classes)]
+
+ ```Ruby
+ # плохо
+ class SomeClass
+ def self.some_method
+ # некоторый код
+ end
+
+ def self.some_other_method
+ end
+ end
+
+ # хорошо
+ module SomeModule
+ module_function
+
+ def some_method
+ # некоторый код
+ end
+
+ def some_other_method
+ end
+ end
+ ```
+
+* Используйте `module_function` вместо
+ `extend self`, когда вам нужно преобразовать включаемые методы модуля в
+ методы модуля.
+ [[ссылка](#module-function)]
+
+ ```Ruby
+ # плохо
+ module Utilities
+ extend self
+
+ def parse_something(string)
+ # здесь реализуется логика
+ end
+
+ def other_utility_method(number, string)
+ # здесь реализуется дополнительная логика
+ end
+ end
+
+ # хорошо
+ module Utilities
+ module_function
+
+ def parse_something(string)
+ # здесь реализуется логика
+ end
+
+ def other_utility_method(number, string)
+ # здесь реализуется дополнительная логика
+ end
+ end
+ ```
+
+* Создавая иерархии классов, проверяйте их на
+ соответствие [принципу подстановки Барбары Лисков][Liskov].
+ [[ссылка](#liskov)]
+
+* Проверяйте дизайн ваших классов на
+ соответствие принципу [SOLID](http://en.wikipedia.org/wiki/SOLID_\(object-oriented_design\)),
+ если такая возможность есть.
+ [[ссылка](#solid-design)]
+
+* Для описывающих предметные области объектов всегда
+ определяйте метод `#to_s`.
+ [[ссылка](#define-to-s)]
+
+ ```Ruby
+ class Person
+ attr_reader :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+
+ def to_s
+ "#{@first_name} #{@last_name}"
+ end
+ end
+ ```
+
+* Применяйте макросы из семества `attr_` для
+ тривиальных методов доступа к объекту.
+ [[ссылка](#attr_family)]
+
+ ```Ruby
+ # плохо
+ class Person
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+
+ def first_name
+ @first_name
+ end
+
+ def last_name
+ @last_name
+ end
+ end
+
+ # хорошо
+ class Person
+ attr_reader :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+ end
+ ```
+
+* Не используйте обобщенную форму `attr`. Используйте
+ `attr_reader` и `attr_accessor` вместо нее.
+ [[ссылка](#attr)]
+
+ ```Ruby
+ # плохо (создает единый метод доступа атрибуту, объявлено нежелательным 1.9)
+ attr :something, true
+ attr :one, :two, :three # ведет себя как attr_reader
+
+ # хорошо
+ attr_accessor :something
+ attr_reader :one, :two, :three
+ ```
+
+* Подумайте об использовании `Struct.new`, эта
+ конструкция даст вам сразу простейшие методы доступа к состоянию,
+ метод инициализации и методы сравнения.
+ [[ссылка](#struct-new)]
+
+ ```Ruby
+ # хорошо
+ class Person
+ attr_accessor :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+ end
+
+ # лучше
+ Person = Struct.new(:first_name, :last_name) do
+ end
+ ````
+
+*
+ Не дополняйте `Struct.new` при помощи `#extend`. В этом случае уже создается
+ новый класс. При дополнении вы создадите избыточный уровень абстракции, это
+ может привезти к странным ошибкам при многократной загрузке кода из файла.
+ [[ссылка](#no-extend-struct-new)]
+
+ ```Ruby
+ # плохо
+ class Person < Struct.new(:first_name, :last_name)
+ end
+
+ # хорошо
+ Person = Struct.new(:first_name, :last_name)
+ ```
+
+*
+ Продумывайте варианты добавления фабричных методов как дополнительной
+ возможности создавать экземпляры конкретного класса.
+ [[ссылка](#factory-methods)]
+
+ ```Ruby
+ class Person
+ def self.create(options_hash)
+ # некоторый код
+ end
+ end
+ ```
+
+*
+ Используйте технику [утиной типизации][duck-typing] (duck typing) вместо
+ наследования.
+ [[ссылка](#duck-typing)]
+
+ ```Ruby
+ # плохо
+ class Animal
+ # abstract method
+ def speak
+ end
+ end
+
+ # extend superclass
+ class Duck < Animal
+ def speak
+ puts 'Quack! Quack'
+ end
+ end
+
+ # extend superclass
+ class Dog < Animal
+ def speak
+ puts 'Bau! Bau!'
+ end
+ end
+
+ # хорошо
+ class Duck
+ def speak
+ puts 'Quack! Quack'
+ end
+ end
+
+ class Dog
+ def speak
+ puts 'Bau! Bau!'
+ end
+ end
+ ```
+
+* Избегайте переменных класса (`@@`) из-за их
+ "непристойного" поведения при наследовании.
+ [[ссылка](#no-class-vars)]
+
+ ```Ruby
+ 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 # => вернет "child"
+ ```
+
+ Как вы видите, все классы в иерархии фактически делять одну и ту же
+ переменную класса. Как правило, вам следует использовать переменные
+ экземпляра класса вместо переменной класса.
+
+*
+ Ограничивайте область видимости методов (`private`, `protected`) в зависимости
+ от их планируемого применения. Не оставляйте все в области `public` (это
+ стандартное значение). В конце концов мы пишем на *Руби*, а не на *Питоне*.
+ [[ссылка](#visibility)]
+
+*
+ Делайте отступы для указателей `public`, `protected` и `private` такими же,
+ как и у самих определений методов, к которым они относятся. Оставляйте пустую
+ строку выше, а также после указателя, чтобы подчеркнуть, что он относится ко
+ всем определяемым ниже методам.
+ [[ссылка](#indent-public-private-protected)]
+
+ ```Ruby
+ class SomeClass
+ def public_method
+ # некоторый код
+ end
+
+ private
+
+ def private_method
+ # некоторый код
+ end
+
+ def another_private_method
+ # некоторый код
+ end
+ end
+ ```
+
+*
+ Для определения синглетных методов используйте `def self.method`. Это упростит
+ рефакторинг, так как имя класса будет использоваться только один раз.
+ [[ссылка](#def-self-singletons)]
+
+ ```Ruby
+ class TestClass
+ # плохо
+ def TestClass.some_method
+ # некоторый код
+ end
+
+ # хорошо
+ def self.some_other_method
+ # body omitted
+ end
+
+ # Также допускается и будет удобным, когда
+ # нужно определить много синглетных методов.
+ class << self
+ def first_method
+ # некоторый код
+ end
+
+ def second_method_etc
+ # некоторый код
+ end
+ end
+ end
+ ```
+
+*
+ Используйте `alias` при определении алиасов методов в лексической области
+ видимости класса. `self` в данном случае также имеет лексическую область
+ видимости, и это подчеркивает тот факт, что алиас будет указывать на метод
+ того класса, в котором определен. Вызов не будет перенаправлен неявно.
+ [[link](#alias-method-lexically)]
+
+ ```Ruby
+ class Westerner
+ def first_name
+ @names.first
+ end
+
+ alias given_name first_name
+ end
+ ```
+
+ Так как `alias`, как и `def`, является ключевым словом, используйте простые
+ имена методов, а не символы или строки в качестве аргументов. Другими словами,
+ пишите `alias foo bar`, а не `alias :foo :bar`.
+
+ Также обратите внимание, как Ruby обрабатывает алиасы при наследовании: алиас
+ будет привязан к тому методу, который находится в области видимости в момент
+ объявления. Динамическое перенаправление вызова не производится.
+
+ ```Ruby
+ class Fugitive < Westerner
+ def first_name
+ 'Nobody'
+ end
+ end
+ ```
+
+ В этом примере `Fugitive#given_name` будет вызывать метод базовго класса
+ `Westerner#first_name`, а не `Fugitive#first_name`. Чтобы переопределить
+ поведение `Fugitive#given_name`, нужно объявить алиас в классе-наследнике.
+
+ ```Ruby
+ class Fugitive < Westerner
+ def first_name
+ 'Nobody'
+ end
+
+ alias given_name first_name
+ end
+ ```
+
+*
+ Всегда применяйте `alias_method` для определения алиасов методов модулей,
+ классов или синглетных классов во время выполнения, так как `alias`
+ использует лексическую область видимости, что приводит к неопределенному
+ поведению в данном случае.
+ [[link](#alias-method)]
+
+ ```Ruby
+ module Mononymous
+ def self.included(other)
+ other.class_eval { alias_method :full_name, :given_name }
+ end
+ end
+
+ class Sting < Westerner
+ include Mononymous
+ end
+ ```
+
+
+## Исключения
+
+* Вызывайте исключения при помощи ключевого слова `fail`.
+ Используйте `raise` только при перехвате исключения и вызове его же заново.
+ В этом случае вы не вызываете исключение, а лишь намеренно передаете его дальше
+ по стеку.[[ссылка](#fail-method)]
+
+ ```Ruby
+ begin
+ fail 'Oops'
+ rescue => error
+ raise if error.message != 'Oops'
+ end
+ ```
+
+* Нет нужды задавать `RuntimeError` явно
+ в качестве аргумента при вызове `fail/raise` с двумя аргументами.
+ [[ссылка](#no-explicit-runtimeerror)]
+
+ ```Ruby
+ # плохо
+ fail RuntimeError, 'message'
+
+ # хорошо - вызывает `RuntimeError` по умолчанию
+ fail 'message'
+ ```
+
+* Передавайте класс исключения и сообщение
+ в форме двух аргументов для `fail/raise` вместо экземпляра класса исключения.
+ [[ссылка](#exception-class-messages)]
+
+ ```Ruby
+ # плохо
+ fail SomeException.new('message')
+ # Обратите внимение, что нет возможности вызвать
+ # `fail SomeException.new('message'), backtrace`.
+
+ # хорошо
+ fail SomeException, 'message'
+ # Работает с `fail SomeException, 'message', backtrace`.
+ ```
+
+* Не возвращайте значений в блоке `ensure`.
+ Если вы явным образом возвращаете значение из блока `ensure`, то возвращение
+ будет обрабатываться сначала и метод вернет значение, как если бы исключения
+ не было вовсе. По итогу исключение будет просто тихо проигнорированно.
+ [[ссылка](#no-return-ensure)]
+
+ ```Ruby
+ def foo
+ fail
+ ensure
+ return 'very bad idea'
+ end
+ ```
+
+* Используйте *имплицитную форму* блока `begin`
+ по возможности.[[ссылка](#begin-implicit)]
+
+ ```Ruby
+ # плохо
+ def foo
+ begin
+ # основной код находится здесь
+ rescue
+ # здесь происходит обработка ошибок
+ end
+ end
+
+ # хорошо
+ def foo
+ # здесь реализуется основная логика
+ rescue
+ # здесь происходит обработка ошибок
+ end
+ ```
+
+* Смягчайте неудобства, связанные с
+ использование блоков `begin` при помощи *contingency methods* (термин введен
+ Авди Гриммом).[[ссылка](#contingency-methods)]
+
+ ```Ruby
+ # плохо
+ begin
+ something_that_might_fail
+ rescue IOError
+ # handle IOError
+ end
+
+ begin
+ something_else_that_might_fail
+ rescue IOError
+ # handle IOError
+ end
+
+ # хорошо
+ def with_io_error_handling
+ yield
+ rescue IOError
+ # handle IOError
+ end
+
+ with_io_error_handling { something_that_might_fail }
+
+ with_io_error_handling { something_else_that_might_fail }
+ ```
+
+* Не подавляйте исключения без обработки.
+ [[ссылка](#dont-hide-exceptions)]
+
+ ```Ruby
+ # плохо
+ begin
+ # здесь образовалось исключение
+ rescue SomeError
+ # rescue не содержит никакой обработки
+ end
+
+ # плохо
+ do_something rescue nil
+ ```
+
+* Откажитесь от использывания `rescue` в виде
+ постмодификатора.[[ссылка](#no-rescue-modifiers)]
+
+ ```Ruby
+ # плохо - это перехватывает исключения класса `StandardError` и его наследников
+ read_file rescue handle_error($!)
+
+ # хорошо - это перехватывает только исключения класса `Errno::ENOENT` и его наследников
+ def foo
+ read_file
+ rescue Errno::ENOENT => ex
+ handle_error(ex)
+ end
+ ```
+
+* Управляйте ветвлением в программе
+ без помощи исключений.[[ссылка](#no-exceptional-flows)]
+
+ ```Ruby
+ # плохо
+ begin
+ n / d
+ rescue ZeroDivisionError
+ puts 'Cannot divide by 0!'
+ end
+
+ # хорошо
+ if d.zero?
+ puts 'Cannot divide by 0!'
+ else
+ n / d
+ end
+ ```
+
+* Не перехватывайте напрямую класс исключений
+ `Exception`. Это будет перехватывать сигналы и вызовы `exit`, что
+ потребует в крайнем случае завершения процесса при помощи `kill -9`.
+ [[ссылка](#no-blind-rescues)]
+
+ ```Ruby
+ # плохо
+ begin
+ # сигналы выхода будет перехвачены (кроме kill -9)
+ exit
+ rescue Exception
+ puts "you didn't really want to exit, right?"
+ # обработка исключений
+ end
+
+ # хорошо
+ begin
+ # `rescue` без параметров перехватывает `StandardError`, а не `Exception`,
+ # как предполагают многие разработчики.
+ rescue => e
+ # обработка исключений
+ end
+
+ # тоже хорошо
+ begin
+ # здесь вызывается исключение
+
+ rescue StandardError => e
+ # обработка ошибок
+ end
+ ```
+
+* Размещайте более специфичные исключения
+ в иерархии проверки, иначе они никогда не будут отфильтрованы.
+ [[ссылка](#exception-ordering)]
+
+ ```Ruby
+ # плохо
+ begin
+ # код с ошибкой
+ rescue Exception => e
+ # некоторое действие
+ rescue StandardError => e
+ # некоторое действие
+ end
+
+ # хорошо
+ begin
+ # код с ошибкой
+ rescue StandardError => e
+ # некоторое действие
+ rescue Exception => e
+ # некоторое действие
+ end
+ ```
+
+*
+ Освобождайте используемые вашей программой ресурсы в блоке `ensure`.
+ [[ссылка](#release-resources)]
+
+ ```Ruby
+ f = File.open('testfile')
+ begin
+ # .. process
+ rescue
+ # .. handle error
+ ensure
+ f.close unless f.nil?
+ end
+ ```
+
+*
+ Применяйте варианты доступа к ресурсам, которые гарантируют автоматический
+ возврат выделенных ресурсов, если есть такая возможность.
+ [[link](#auto-release-resources)]
+
+ ```Ruby
+ # плохо (нужно специально закрывать ранее открытый файл)
+ f = File.open('testfile')
+ # ...
+ f.close
+
+ # хорошо (открытый файл закрывается автоматически)
+ File.open('testfile') do |f|
+ # ...
+ end
+ ```
+*
+ Преимущественно используйте исключения, определенные в стандартной библиотеке,
+ не создавайте без нужды новые классы исключений.
+ [[ссылка](#standard-exceptions)]
+
+## Коллекции
+
+* При создании массивов и хешей применяйте
+ нотацию с литералами. Используйте конструкторы класса, только если вам нужно
+ передать дополнительные параметры при создании коллекций.
+ [[ссылка](#literal-array-hash)]
+
+ ```Ruby
+ # плохо
+ arr = Array.new
+ hash = Hash.new
+
+ # хорошо
+ arr = []
+ hash = {}
+ ```
+
+* Используйте нотацию `%w` для литералов массивов,
+ когда вам необходимо создать массив слов (непустых строк без пробелов и
+ метасимволов). Это правило касается лишь массивов с двумя и более
+ элементами.[[ссылка](#percent-w)]
+
+ ```Ruby
+ # плохо
+ STATES = ['draft', 'open', 'closed']
+
+ # хорошо
+ STATES = %w(draft open closed)
+ ```
+
+* Используйте нотацию `%i` для литералов массивов,
+ когда вам необходимо создать массив символов. Помните, что эта нотация
+ несовместима с синтаксисом Ruby 1.9 и старше. Это правило касается лишь
+ массивов с двумя и более элементами.[[ссылка](#percent-i)]
+
+ ```Ruby
+ # плохо
+ STATES = [:draft, :open, :closed]
+
+ # хорошо
+ STATES = %i(draft open closed)
+ ```
+
+* Не ставьте запятую после последнего
+ элемента в литералах массивов и хешей, особенно если элементы находятся не на
+ разных строках.[[ссылка](#no-trailing-array-commas)]
+
+ ```Ruby
+ # плохо (проще перемещать, добавлять и удалять элементы, но не идеально)
+ VALUES = [
+ 1001,
+ 2020,
+ 3333,
+ ]
+
+ # плохо
+ VALUES = [1001, 2020, 3333, ]
+
+ # хорошо
+ VALUES = [1001, 2020, 3333]
+ ```
+
+* Не создавайте массивы с большими незанятыми
+ промежутками адресов.[[ссылка](#no-gappy-arrays)]
+
+ ```Ruby
+ arr = []
+ arr[100] = 1 # Теперь у вас есть массив с кучей значений `nil`.
+ ```
+
+* При доступе к первому и последнему элементам
+ массива используйте методы `#first` или `#last`, а не индексы `[0]` и `[-1]`.
+ [[ссылка](#first-and-last)]
+
+* Используйте класс `Set` вместо `Array`, если вы
+ работаете с уникальными элементами. Класс `Set` реализует несортированную
+ коллекцию элементов без повторений и является гибридом интуитивных операций
+ класса `Array` и легкого и быстрого доступа класса `Hash`.
+ [[ссылка](#set-vs-array)]
+
+* Используйте символы вместо строк в качестве
+ ключей хешей.[[ссылка](#symbols-as-keys)]
+
+ ```Ruby
+ # плохо
+ hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
+
+ # хорошо
+ hash = { one: 1, two: 2, three: 3 }
+ ```
+
+* Не используйте мутируемые объекты в качестве
+ ключей для хешей.[[ссылка](#no-mutable-keys)]
+
+* Применяйте введенный в Ruby 1.9 синтаксис для
+ литералов хешей, когда ключами являются символы.
+ [[ссылка](#hash-literals)]
+
+ ```Ruby
+ # плохо
+ hash = { :one => 1, :two => 2, :three => 3 }
+
+ # хорошо
+ hash = { one: 1, two: 2, three: 3 }
+ ```
+
+* Не используйте разные способы записи
+ хешей одновременно (нотации до и после Ruby 1.9). Если вы используете не только
+ символы в качестве ключей, то применяйте только старую нотацию со стрелками.
+ [[ссылка](#no-mixed-hash-syntaces)]
+
+ ```Ruby
+ # плохо
+ { a: 1, 'b' => 2 }
+
+ # хорошо
+ { :a => 1, 'b' => 2 }
+ ```
+
+* Применяйте `Hash#key?` вместо `Hash#has_key?` и
+ `Hash#value?` вместо `Hash#has_value?`. Матц описывает
+ [здесь](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/43765)
+ свои планы исключить эти методы в будущем.
+ [[ссылка](#hash-key)]
+
+ ```Ruby
+ # плохо
+ hash.has_key?(:test)
+ hash.has_value?(value)
+
+ # хорошо
+ hash.key?(:test)
+ hash.value?(value)
+ ```
+
+* Для надежной работы с заданными ключами, о
+ существовании которых доподлинно известно, используйте `Hash#fetch`.
+ [[ссылка](#hash-fetch)]
+
+ ```Ruby
+ heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
+ # плохо (закравшуюся ошибку можно и не заметить сразу)
+ heroes[:batman] # => "Bruce Wayne"
+ heroes[:supermann] # => nil
+
+ # хорошо (`Hash#fetch` вызывает `KeyError` и явно указывает на проблему)
+ heroes.fetch(:supermann)
+ ```
+
+* Задавайте стандартные значения для хешей
+ при помощи `Hash#fetch`, не реализуйте эту логику самостоятельно.
+ [[ссылка](#hash-fetch-defaults)]
+
+ ```Ruby
+ batman = { name: 'Bruce Wayne', is_evil: false }
+
+ # плохо (например, при использование оператора `||` мы получим неожиданный
+ # результат при ложном значении первого операнда)
+ batman[:is_evil] || true # => true
+
+ # хорошо (`Hash#fetch` отрабатывает корректно)
+ batman.fetch(:is_evil, true) # => false
+ ```
+
+*
+ Используйте блоки вместо значений `Hash#fetch` по умолчанию, если вызываемый
+ код имеет сторонние эффекты или сложен для выполнения.
+ [[ссылка](#use-hash-blocks)]
+
+ ```Ruby
+ batman = { name: 'Bruce Wayne' }
+
+ # плохо (при использовании значения по умолчанию метод его расчета будет
+ # вызываться каждый раз, сильно замедляя выполнение программы при
+ # многократных вызовах)
+ batman.fetch(:powers, get_batman_powers) # get_batman_powers - нагруженный метод
+
+ # хорошо (блоки оцениваются лишь по необходимости, когда вызывается KeyError)
+ batman.fetch(:powers) { get_batman_powers }
+ ```
+
+*
+ Используйте `Hash#values_at`, когда вам нужно получить несколько значений хеша
+ за один раз.
+ [[ссылка](#hash-values-at)]
+
+ ```Ruby
+ # плохо
+ email = data['email']
+ username = data['nickname']
+
+ # хорошо
+ email, username = data.values_at('email', 'nickname')
+ ```
+
+* Вы можете положиться на то, что хеши в Ruby 1.9
+ и младше отсортированны.[[ссылка](#ordered-hashes)]
+
+* Никогда не модифицируйте коллекцию в
+ процессе ее обхода.[[ссылка](#no-modifying-collections)]
+
+*
+ Получая доступ к элементам коллекций, старайтесь избегать доступа при помощи
+ `[n]`, а используйте альтернативные методы доступа, если таковые определены.
+ Это обезопасит вас от вызова `[]` на `nil`.
+ [[link](#accessing-elements-directly)]
+
+ ```Ruby
+ # плохо
+ Regexp.last_match[1]
+
+ # хорошо
+ Regexp.last_match(1)
+ ```
+
+*
+ При определении методов доступа к коллекции, добавьте альтернативную форму,
+ чтобы оградить пользователей от необходимости проверки на `nil` перед доступом
+ к элементу коллекции.
+ [[link](#provide-alternate-accessor-to-collections)]
+
+ ```Ruby
+ # плохо
+ def awesome_things
+ @awesome_things
+ end
+
+ # хорошо
+ def awesome_things(index = nil)
+ if index && @awesome_things
+ @awesome_things[index]
+ else
+ @awesome_things
+ end
+ end
+ ```
+
+## Строки
+
+* Используйте интерполяцию строк и форматные
+ шаблоны, а не конкатенацию строк.
+ [[ссылка](#string-interpolation)]
+
+ ```Ruby
+ # плохо
+ email_with_name = user.name + ' <' + user.email + '>'
+
+ # хорошо
+ email_with_name = "#{user.name} <#{user.email}>"
+
+ # хорошо
+ email_with_name = format('%s <%s>', user.name, user.email)
+ ```
+
+*
+ Избегайте пробелов внутри скобок вокруг интерполируемых выражений в строках.
+ [[ссылка](#string-interpolation)]
+
+ ```Ruby
+ # плохо
+ "From: #{ user.first_name }, #{ user.last_name }"
+
+ # хорошо
+ "From: #{user.first_name}, #{user.last_name}"
+ "#{ user.last_name }, #{ user.first_name }"
+ ```
+
+* Постарайтесь внедрить единообразных
+ стиль кавычек для строчных литералов. В среде программистов на Руби есть два
+ популярных стиля, оба из них считаются приемлемыми. Стиль **А** подразумевает
+ одинарные кавычки по умолчанию, а стиль **B** двойные кавычки.
+ [[ссылка](#consistent-string-literals)]
+
+ * **Стиль A:** Используйте одинарные кавычки, если вам не нужна интерполяция строк
+ или специальные символы вроде `\t`, `\n`, `'` и т.д.
+
+ ```Ruby
+ # плохо
+ name = "Bozhidar"
+
+ # хорошо
+ name = 'Bozhidar'
+ ```
+
+ * **Стиль B:** Используйте двойные кавычки в ваших строчных литералах, если они не
+ содержат `"` или экранируйте символы, которые не должны интерполироваться.
+
+ ```Ruby
+ # плохо
+ name = 'Bozhidar'
+
+ # хорошо
+ name = "Bozhidar"
+ ```
+
+ Второй стиль, по некоторым мнениям, более распространен среди разработчиков на
+ Руби. Однако в этом руководстве оформление строк следует первому правилу.
+
+* Не используйте запись для литералов
+ алфавитных символов `?x`. Начиная с версии Руби 1.9, этот вариант записи
+ избыточен: `?x` будет интерпретироваться в виде `'x'` (строка
+ с единственным символом в ней).[[ссылка](#no-character-literals)]
+
+ ```Ruby
+ # плохо
+ char = ?c
+
+ # хорошо
+ char = 'c'
+ ```
+
+* Всегда применяйте фигурные скобки `{}`
+ вокруг глобальных переменных и переменных экземпляров класса при интерполяции
+ строк.[[ссылка](#curlies-interpolate)]
+
+ ```Ruby
+ class Person
+ attr_reader :first_name, :last_name
+
+ def initialize(first_name, last_name)
+ @first_name = first_name
+ @last_name = last_name
+ end
+
+ # плохо (допустимо, но вычурно)
+ def to_s
+ "#@first_name #@last_name"
+ end
+
+ # хорошо
+ def to_s
+ "#{@first_name} #{@last_name}"
+ end
+ end
+
+ $global = 0
+ # плохо
+ puts "$global = #$global"
+
+ # хорошо
+ puts "$global = #{$global}"
+ ```
+
+* Не используйте метод `Object#to_s` для интерполируемых
+ объектов, он вызывается автоматически при интерполяции.
+ [[ссылка](#no-to-s)]
+
+ ```Ruby
+ # плохо
+ message = "This is the #{result.to_s}."
+
+ # хорошо
+ message = "This is the #{result}."
+ ```
+
+* Не применяйте метод `String#+`, когда вам нужно
+ собрать вместе большие отрезки строк. Вместо этого используйте `String#<<`.
+ Конкатенация изменяет экземпляр строки и всегда работает быстрее, чем `String#+`,
+ который создает целую кучу новых строковых объектов.
+ [[ссылка](#concat-strings)]
+
+ ```Ruby
+ # хорошо и быстро
+ html = ''
+ html << 'Page title
'
+
+ paragraphs.each do |paragraph|
+ html << "#{paragraph}
"
+ end
+ ```
+
+*
+ Избегайте метода `String#gsub` в случаях, когда можно использовать более
+ быстрый и специализированный альтернативный метод.
+ [[link](#dont-abuse-gsub)]
+
+ ```Ruby
+ url = 'http://example.com'
+ str = 'lisp-case-rules'
+
+ # плохо
+ url.gsub("http://", "https://")
+ str.gsub("-", "_")
+
+ # хорошо
+ url.sub("http://", "https://")
+ str.tr("-", "_")
+ ```
+
+
+*
+ При использовании многострочных HEREDOC не забывайте, что пробелы в начале
+ строк тоже являются частью создаваемой строки. Примером хорошего стиля
+ является применение техник, основывающихся на ограничителях, для удаления
+ ненужных пробелов.
+ [[ссылка](#heredocs)]
+
+ ```Ruby
+ code = <<-END.gsub(/^\s+\|/, '')
+ |def test
+ | some_method
+ | other_method
+ |end
+ END
+ #=> "def test\n some_method\n other_method\nend\n"
+ ```
+
+## Регулярные выражения
+
+> Многие люди, встречаясь с проблемой, думают:
+> "Я знаю решение, я применю регулярные выражения!"
+> Теперь у них две проблемы.
+> -- Джейми Цавински / Jamie Zawinski
+
+*
+ Не используйте регулярные выражения, когда вам нужно просто найти в строке
+ подстроку: `string['text']`.
+ [[ссылка](#no-regexp-for-plaintext)]
+
+*
+ В простейших случаях вы просто можете использовать индексирование строк.
+ [[ссылка](#regexp-string-index)]
+
+ ```Ruby
+ match = string[/regexp/] # Возвращает найденные совпадения.
+ first_group = string[/text(grp)/, 1] # Возвращает совпадения выделенной группы.
+ string[/text (grp)/, 1] = 'replace' # string => 'text replace'
+ ```
+
+* Используйте группировку без сохранения,
+ если вы не планируете использовать содержание выделенной скобками группы.
+ [[ссылка](#non-capturing-regexp)]
+
+ ```Ruby
+ /(first|second)/ # плохо
+ /(?:first|second)/ # хорошо
+ ```
+
+* Откажитесь от использования наследия
+ Перла вроде мистических переменных, обозначающих группы совпадений (`$1`, `$2`
+ и т.д.). Вместо этого используйте `Regexp.last_match(n)`.
+ [[ссылка](#no-perl-regexp-last-matchers)]
+
+ ```Ruby
+ /(regexp)/ =~ string
+ ...
+
+ # плохо
+ process $1
+
+ # хорошо
+ process Regexp.last_match(1)
+ ```
+
+* Применение пронумерованных групп
+ совпадений может быть сложной задачей. Вместо этого используйте поименованные
+ группы с говорящими именами.[[ссылка](#no-numbered-regexes)]
+
+ ```Ruby
+ # плохо
+ /(regexp)/ =~ string
+ ...
+ process Regexp.last_match[1]
+
+ # хорошо
+ /(?regexp)/ =~ string
+ ...
+ process meaningful_var
+ ```
+
+* Классы символов используют лишь небольшой
+ набор метасимволов, которые вам придется обрабатывать: `^`, `-`, `\`, `]`,
+ поэтому нет нужды экранировать `.` или скобки внутри `[]`.
+ [[ссылка](#limit-escapes)]
+
+* Будьте осторожны с символами `^` и `$`,
+ так как они обозначают начало/конец строки в тексте, а не строчного литерала.
+ Если вам надо обозначить начало и конец литерала, то используйте `\A` и `\z`.
+ Не путайте `\Z` и `\z`: `\Z` является эквивалентом `/\n?\z/`.
+ [[ссылка](#caret-and-dollar-regexp)]
+
+ ```Ruby
+ string = "some injection\nusername"
+ string[/^username$/] # есть совпадение
+ string[/\Ausername\z/] # нет совпадения
+ ```
+
+* Используйте модификатор `x` для сложных регулярных
+ выражений. Он поможет вам сделать выражения удобочитаемыми и позволит добавлять
+ комментарии. Не забывайте при этом, что пробелы в данном случае игнорируются.
+ [[ссылка](#comment-regexes)]
+
+ ```Ruby
+ regexp = /
+ start # какой-то текст
+ \s # знак пробела
+ (group) # первая группа
+ (?:alt1|alt2) # некоторая дизъюнкция
+ end
+ /x
+ ```
+
+* В случае сложных замен либо подстановок `sub`/`gsub`
+ можно использовать с блоком или хешем параметров.
+ [[ссылка](#gsub-blocks)]
+
+## Процентные литералы
+
+* Используйте `%()` (это сокращение от `%Q`)
+ для строк без переносов, в которых реализуется интерполяция и присутствуют
+ двойные кавычки. Для строк с переносами лучше используйте формат HERE Doc.
+ [[ссылка](#percent-q-shorthand)]
+
+ ```Ruby
+ # плохо (интерполяция не нужна)
+ %(Some text
)
+ # должно быть 'Some text
'
+
+ # плохо (нет двойных кавычек)
+ %(This is #{quality} style)
+ # должно быть "This is #{quality} style"
+
+ # плохо (строка с переносами)
+ %(\n#{exclamation}\n
)
+ # лучше применить HERE Doc
+
+ # хорошо (необходима интерполяция, присутствуют кавычки, нет переносов)
+ %(#{name} | )
+ ```
+
+*
+ Избегайте `%q`, если это не случай строки с символами кавычек `'` и `"`
+ одновременно Обычные строки читаются проще, и их следует использовать, если
+ нет излишне большого количества символов, которые нужно будет экранировать.
+ [[ссылка](#percent-q)]
+
+ ```Ruby
+ # плохо
+ name = %q(Bruce Wayne)
+ time = %q(8 o'clock)
+ question = %q("What did you say?")
+
+ # хорошо
+ name = 'Bruce Wayne'
+ time = "8 o'clock"
+ question = '"What did you say?"'
+ ```
+
+*
+ Используйте `%r` для регулярных выражений, которые обрабатывают *хотя бы один*
+ символ `/`, в остальных случаях используйте стандартный синтаксис.
+ [[ссылка](#percent-r)]
+
+ ```Ruby
+ # плохо
+ %r{\s+}
+
+ # хорошо
+ %r{^/(.*)$}
+ %r{^/blog/2011/(.*)$}
+ ```
+
+*
+ Откажитесь от использования `%x` кроме случаев, когда вы хотите вызвать
+ внешнюю команду с обратными кавычками в теле (что само по себе маловероятно).
+ [[ссылка](#percent-x)]
+
+ ```Ruby
+ # плохо
+ date = %x(date)
+
+ # хорошо
+ date = `date`
+ echo = %x(echo `date`)
+ ```
+
+*
+ Старайтесь избегать `%s`. По общепринятому мнению, предпочтительным способом
+ определения символа с пробелами в имени является `:"some string"`.
+ [[ссылка](#percent-s)]
+
+* Используйте `()` в качестве ограничителей
+ для всех литералов со знаком `%` кроме `%r`. Так как круглые скобки очень
+ часто используются в самих регулярных выражениях, во многих случаях менее
+ частый символ `{` может быть лучшим выбором для ограничителя (разумеется,
+ с учетом смысла регулярного выражения).
+ [[ссылка](#percent-literal-braces)]
+
+ ```Ruby
+ # плохо
+ %w[one two three]
+ %q{"Test's king!", John said.}
+
+ # хорошо
+ %w(one two three)
+ %q("Test's king!", John said.)
+ ```
+
+## Метапрограммирование
+
+* Откажитесь от метапрограммирования
+ ради метапрограммирования как такового.
+ [[ссылка](#no-needless-metaprogramming)]
+
+* Не разводите беспорядок в базовых классах
+ при написании библиотек (не используйте "monkey patching").
+ [[ссылка](#no-monkey-patching)]
+
+* Используйте `#class_eval` с блоком вместно
+ интерполяции значений в строке. Если вы используете интерполяцию, то всегда
+ указывайте дополнительно `__FILE__` и `__LINE__`, чтобы информация о стеке
+ вызова была осмысленной:[[ссылка](#block-class-eval)]
+
+ ```Ruby
+ class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
+ ```
+
+ - `#define_method` предпочтительнее, чем `#class_eval { def ... }`
+
+* При использовании `#class_eval` (или других
+ `#eval`) с интерполяцией строк обязательно добавляйте комментарий, который
+ будет наглядно показывать, как интерполированные значения будут выглядеть
+ (примеры, используемые в исходном коде Rails):[[ссылка](#eval-comment-docs)]
+
+ ```Ruby
+ # из activesupport/lib/active_support/core_ext/string/output_safety.rb
+ UNSAFE_STRING_METHODS.each do |unsafe_method|
+ if 'String'.respond_to?(unsafe_method)
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
+ def #{unsafe_method}(*params, &block) # def capitalize(*params, &block)
+ to_str.#{unsafe_method}(*params, &block) # to_str.capitalize(*params, &block)
+ end # end
+
+ def #{unsafe_method}!(*params) # def capitalize!(*params)
+ @dirty = true # @dirty = true
+ super # super
+ end # end
+ EOT
+ end
+ end
+ ```
+
+* Избегайте `#method_missing` для целей
+ метапрограммирования, так как стек вызова становится нечитаемым, метод не виден
+ в `#methods`, опечатки в вызовах методов пройдут незамеченными, например,
+ `nukes.launch_state = false`. Используйте делегирование, проксирование или же
+ `#define_method`. Если вы используете `#method_missing`:
+ [[ссылка](#no-method-missing)]
+
+ - обязательно [задайте `#respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html);
+ - перехватывайте вызовы только с четко определенными префиксами, например,
+ `#find_by_*` -- задайте в своем коде наиболее узкие рамки для
+ неопределенностей;
+ - вызывайте `#super` в конце ваших выражений;
+ - делегируйте вызовы понятным, "немагическим" методам:
+
+ ```Ruby
+ # плохо
+ def method_missing?(meth, *params, &block)
+ if /^find_by_(?.*)/ =~ meth
+ # ... lots of code to do a find_by
+ else
+ super
+ end
+ end
+
+ # хорошо
+ def method_missing?(meth, *params, &block)
+ if /^find_by_(?.*)/ =~ meth
+ find_by(prop, *params, &block)
+ else
+ super
+ end
+ end
+
+ # Самым лучшим будет все же использование `#define_method`,
+ # так как каждый видимый аргумент будет определен.
+ ```
+
+## Разное
+
+* Пишите код, не дающий предупреждений при вызове
+ `ruby -w`.[[ссылка](#always-warn)]
+
+* Не используйте хеши в качестве
+ необязательных параметров. Возможно, ваш метод просто делает слишком много.
+ Это не касается, однако, методов инициализации объектов.
+ [[ссылка](#no-optional-hash-params)]
+
+* Старайтесь не писать методы длиннее 10 строк. В
+ идеальном случае большинство методов должны быть короче 5 строк. Пустные строки
+ не подсчитываются.[[ссылка](#short-methods)]
+
+* Не создаваете методы с более чем тремя-четырьмя
+ параметрами.[[ссылка](#too-many-params)]
+
+* Если вам действительно нужны глобальные
+ функции, включайте их в модуль Kernel и сделайте их приватными.
+ [[ссылка](#private-global-methods)]
+
+* Используйте переменные модулей вместо глобальных
+ переменных.[[ссылка](#instance-vars)]
+
+ ```Ruby
+ # плохо
+ $foo_bar = 1
+
+ # хорошо
+ module Foo
+ class << self
+ attr_accessor :bar
+ end
+ end
+
+ Foo.bar = 1
+ ```
+
+* Используйте `OptionParser` для анализа сложных
+ аргуметов командрой строки и `ruby -s` для элеметарных случаев.
+ [[ссылка](#optionparser)]
+
+* Используйте вариант `Time.now`, а не `Time.new`,
+ когда хотите получить текущее значение системного времени.
+ [[ссылка](#time-now)]
+
+* Пишите код в функциональном стиле без изменения
+ значений, когда это подходит по смыслу.[[ссылка](#functional-code)]
+
+*
+ Не изменяйте значения параметров, если только это не есть цель метода.
+ [[ссылка](#no-param-mutations)]
+
+* Старайтесь не создавать
+ вложенные структуры с уровнем вложения больше третьего.
+ [[ссылка](#three-is-the-number-thou-shalt-count)]
+
+* Будьте последовательны. В идеальном мире
+ последовательно придерживайтесь данного руководства.
+ [[ссылка](#be-consistent)]
+
+* Руководствуйтесь здравым смыслом.
+ [[ссылка](#common-sense)]
+
+## Инструментарий
+
+В этом разделе собраны инструменты, которые могут помочь вам автоматически
+сверить ваш код на Руби с предписаниями этого руководства.
+
+### РубоКоп
+
+[RuboCop][] — это утилита проверки стиля
+программного кода на Руби, который основывается на этом руководстве.
+РубоКоп уже реализует большую часть этого руководства, поддерживает MRI 1.9
+и MRI 2.0 и хорошо интегрируется с редактором Емакс.
+
+### RubyMine
+
+Модуль проверки кода [RubyMine](http://www.jetbrains.com/ruby/)
+[частично основывается](http://confluence.jetbrains.com/display/RUBYDEV/RubyMine+Inspections)
+на этом руководстве.
+
+# Сотрудничество
+
+Ничто, описанное в этом руководстве, не высечено в камне. И я очень хотел бы
+сотрудничать со всеми, кто интересуется стилистикой оформления кода на Руби,
+чтобы мы смогли вместе создать ресурс, который был бы полезен для всего
+сообщества программистов на Руби.
+
+Не стесняйтесь создавать отчеты об ошибках и присылать мне запросы на интеграцию
+вашего кода. И заранее большое спасибо за вашу помощь!
+
+Вы можете поддержать проект (и РубоКоп) денежным взносом при помощи
+[gittip](https://www.gittip.com/bbatsov).
+
+[](https://www.gittip.com/bbatsov)
+
+## Как сотрудничать в проекте?
+
+Это просто! Следуйте [руководству по
+сотрудничеству](https://github.com/bbatsov/ruby-style-guide/blob/master/CONTRIBUTING.md).
+
+# Лицензирование
+
+
+Данная работа опубликована на условиях лицензии [Creative Commons Attribution
+3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US)
+
+# Расскажи другому
+
+Создаваемое сообществом руководство по стилю оформления будет малопригодным для
+сообщества, которое об этом руководстве ничего не знает. Делитесь ссылками на
+это руководство с вашими друзьями и коллегами доступными вам средствами. Каждый
+получаемый нами комментарий, предложение или мнение сделает это руководство еще
+чуточку лучше. А ведь мы хотим самое лучшее руководство из возможных, не так ли?
+
+Всего,
+[Божидар](https://twitter.com/bbatsov)
+
+
+[PEP-8]: http://www.python.org/dev/peps/pep-0008/
+[rails-style-guide]: https://github.com/arbox/rails-style-guide/blob/master/README-ruRU.md
+[pickaxe]: http://pragprog.com/book/ruby4/programming-ruby-1-9-2-0
+[trpl]: http://www.ozon.ru/context/detail/id/5704300/
+[entrpl]: http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177
+[transmuter]: https://github.com/TechnoGate/transmuter
+[RuboCop]: https://github.com/bbatsov/rubocop
+[Liskov]: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8_%D0%91%D0%B0%D1%80%D0%B1%D0%B0%D1%80%D1%8B_%D0%9B%D0%B8%D1%81%D0%BA%D0%BE%D0%B2
+[duck-typing]: https://ru.wikipedia.org/wiki/%D0%A3%D1%82%D0%B8%D0%BD%D0%B0%D1%8F_%D1%82%D0%B8%D0%BF%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F
diff --git a/README.md b/README.md
index dea7f9e15..2a53ea781 100644
--- a/README.md
+++ b/README.md
@@ -1,3478 +1,50 @@
-# Prelude
+# Руби: руководство по стилю оформления
-> Role models are important.
-> -- Officer Alex J. Murphy / RoboCop
+Это руководство по оформлению кода на Руби дает передовые рекомендации. С его
+помощью обычный программист на Руби будет создавать код, который с легкостью
+смогут поддерживать и развивать другие обычные разработчики.
-One thing has always bothered me as a Ruby developer - Python developers have a
-great programming style reference
-([PEP-8][]) and we never got an official
-guide, documenting Ruby coding style and best practices. And I do believe that
-style matters. I also believe that a great hacker community, such as Ruby has,
-should be quite capable of producing this coveted document.
+Читайте [руководство][russian] на русском языке.
-This guide started its life as our internal company Ruby coding guidelines
-(written by yours truly). At some point I decided that the work I was doing
-might be interesting to members of the Ruby community in general and that the
-world had little need for another internal company guideline. But the world
-could certainly benefit from a community-driven and community-sanctioned set of
-practices, idioms and style prescriptions for Ruby programming.
+[Оригинал][english] этого руководства был составлен [Божидаром Бацовым
+][bbatsov]. Переводы данного руководства доступны на следующих языках:
-Since the inception of the guide I've received a lot of feedback from members of
-the exceptional Ruby community around the world. Thanks for all the suggestions
-and the support! Together we can make a resource beneficial to each and every
-Ruby developer out there.
+* [английский (исходная версия)][english]
+* [вьетнамский](https://github.com/scrum2b/ruby-style-guide/blob/master/README-viVN.md)
+* [испанский](https://github.com/alemohamad/ruby-style-guide/blob/master/README-esLA.md)
+* [китайский традиционный](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
+* [китайский упрощенный](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
+* [корейский](https://github.com/dalzony/ruby-style-guide/blob/master/README-koKR.md)
+* [немецкий](https://github.com/arbox/ruby-style-guide/blob/master/README-deDE.md)
+* [французский](https://github.com/porecreat/ruby-style-guide/blob/master/README-frFR.md)
+* [португальский](https://github.com/rubensmabueno/ruby-style-guide/blob/master/README-PT-BR.md)
+* [русский (данный документ)](https://github.com/arbox/ruby-style-guide/blob/master/README-ruRU.md)
+* [японский](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
-By the way, if you're into Rails you might want to check out the complementary
-[Ruby on Rails Style Guide][rails-style-guide].
+В дополнение к настоящему сборнику вас может заинтересовать
+[Rails: руководство по стилю оформления](https://github.com/arbox/rails-style-guide/blob/master/README-ruRU.md).
-# The Ruby Style Guide
+Если вы хотите оставаться в курсе актуальных изменений, следите за репозиторием
+и жмите на звездочку!
-This Ruby style guide recommends best practices so that real-world Ruby
-programmers can write code that can be maintained by other real-world Ruby
-programmers. A style guide that reflects real-world usage gets used, and a style
-guide that holds to an ideal that has been rejected by the people it is supposed
-to help risks not getting used at all – no matter how good it is.
+## Другие руководства:
-The guide is separated into several sections of related rules. I've tried to add
-the rationale behind the rules (if it's omitted I've assumed it's pretty
-obvious).
+* https://github.com/bestie/objective-ruby-style-guide
+* https://github.com/chneukirchen/styleguide/blob/master/RUBY-STYLE
+* https://github.com/styleguide/ruby
+* https://github.com/airbnb/ruby
+* https://github.com/thoughtbot/guides/tree/master/style/ruby
-I didn't come up with all the rules out of nowhere - they are mostly
-based on my extensive career as a professional software engineer,
-feedback and suggestions from members of the Ruby community and
-various highly regarded Ruby programming resources, such as
-["Programming Ruby 1.9"][pickaxe] and
-["The Ruby Programming Language"][trpl].
+## Непрерывная интеграция:
-There are some areas in which there is no clear consensus in the Ruby community
-regarding a particular style (like string literal quoting, spacing inside hash
-literals, dot position in multi-line method chaining, etc.). In such scenarios
-all popular styles are acknowledged and it's up to you to pick one and apply it
-consistently.
+* https://houndci.com/
-This style guide evolves over time as additional conventions are
-identified and past conventions are rendered obsolete by changes in
-Ruby itself.
-Many projects have their own coding style guidelines (often derived
-from this guide). In the event of any conflicts, such
-project-specific guides take precedence for that project.
+## Buttons
-You can generate a PDF or an HTML copy of this guide using
-[Transmuter][].
+
+Follow @arbox
-[RuboCop][] is a code analyzer, based on this
-style guide.
-
-Translations of the guide are available in the following languages:
-
-* [Chinese Simplified](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhCN.md)
-* [Chinese Traditional](https://github.com/JuanitoFatas/ruby-style-guide/blob/master/README-zhTW.md)
-* [French](https://github.com/porecreat/ruby-style-guide/blob/master/README-frFR.md)
-* [Japanese](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
-* [Korean](https://github.com/dalzony/ruby-style-guide/blob/master/README-koKO.md)
-* [Portuguese](https://github.com/rubensmabueno/ruby-style-guide/blob/master/README-PT-BR.md)
-* [Russian](https://github.com/arbox/ruby-style-guide/blob/master/README-ruRU.md)
-* [Spanish](https://github.com/alemohamad/ruby-style-guide/blob/master/README-esLA.md)
-* [Vietnamese](https://github.com/scrum2b/ruby-style-guide/blob/master/README-viVN.md)
-
-## Table of Contents
-
-* [Source Code Layout](#source-code-layout)
-* [Syntax](#syntax)
-* [Naming](#naming)
-* [Comments](#comments)
- * [Comment Annotations](#comment-annotations)
-* [Classes](#classes--modules)
-* [Exceptions](#exceptions)
-* [Collections](#collections)
-* [Strings](#strings)
-* [Regular Expressions](#regular-expressions)
-* [Percent Literals](#percent-literals)
-* [Metaprogramming](#metaprogramming)
-* [Misc](#misc)
-* [Tools](#tools)
-
-## Source Code Layout
-
-> Nearly everybody is convinced that every style but their own is
-> ugly and unreadable. Leave out the "but their own" and they're
-> probably right...
-> -- Jerry Coffin (on indentation)
-
-*
- Use `UTF-8` as the source file encoding.
-[[link](#utf-8)]
-
-*
- Use two **spaces** per indentation level (aka soft tabs). No hard tabs.
-[[link](#spaces-indentation)]
-
- ```Ruby
- # bad - four spaces
- def some_method
- do_something
- end
-
- # good
- def some_method
- do_something
- end
- ```
-
-*
- Use Unix-style line endings. (*BSD/Solaris/Linux/OS X users are covered by
- default, Windows users have to be extra careful.)
-[[link](#crlf)]
-
- * If you're using Git you might want to add the following
- configuration setting to protect your project from Windows line
- endings creeping in:
-
- ```bash
- $ git config --global core.autocrlf true
- ```
-
-*
- Don't use `;` to separate statements and expressions. As a corollary - use one
- expression per line.
-[[link](#no-semicolon)]
-
- ```Ruby
- # bad
- puts 'foobar'; # superfluous semicolon
-
- puts 'foo'; puts 'bar' # two expressions on the same line
-
- # good
- puts 'foobar'
-
- puts 'foo'
- puts 'bar'
-
- puts 'foo', 'bar' # this applies to puts in particular
- ```
-
-*
- Prefer a single-line format for class definitions with no body.
-[[link](#single-line-classes)]
-
- ```Ruby
- # bad
- class FooError < StandardError
- end
-
- # okish
- class FooError < StandardError; end
-
- # good
- FooError = Class.new(StandardError)
- ```
-
-*
- Avoid single-line methods. Although they are somewhat popular in the wild,
- there are a few peculiarities about their definition syntax that make their
- use undesirable. At any rate - there should be no more than one expression in
- a single-line method.
-[[link](#no-single-line-methods)]
-
- ```Ruby
- # bad
- def too_much; something; something_else; end
-
- # okish - notice that the first ; is required
- def no_braces_method; body end
-
- # okish - notice that the second ; is optional
- def no_braces_method; body; end
-
- # okish - valid syntax, but no ; makes it kind of hard to read
- def some_method() body end
-
- # good
- def some_method
- body
- end
- ```
-
- One exception to the rule are empty-body methods.
-
- ```Ruby
- # good
- def no_op; end
- ```
-
-*
- Use spaces around operators, after commas, colons and semicolons, around `{`
- and before `}`. Whitespace might be (mostly) irrelevant to the Ruby
- interpreter, but its proper use is the key to writing easily readable code.
-[[link](#spaces-operators)]
-
- ```Ruby
- sum = 1 + 2
- a, b = 1, 2
- [1, 2, 3].each { |e| puts e }
- class FooError < StandardError; end
- ```
-
- The only exception, regarding operators, is the exponent operator:
-
- ```Ruby
- # bad
- e = M * c ** 2
-
- # good
- e = M * c**2
- ```
-
- `{` and `}` deserve a bit of clarification, since they are used
- for block and hash literals, as well as embedded expressions in
- strings. For hash literals two styles are considered acceptable.
-
- ```Ruby
- # good - space after { and before }
- { one: 1, two: 2 }
-
- # good - no space after { and before }
- {one: 1, two: 2}
- ```
-
- The first variant is slightly more readable (and arguably more
- popular in the Ruby community in general). The second variant has
- the advantage of adding visual difference between block and hash
- literals. Whichever one you pick - apply it consistently.
-
- As far as embedded expressions go, there are also two acceptable
- options:
-
- ```Ruby
- # good - no spaces
- "string#{expr}"
-
- # ok - arguably more readable
- "string#{ expr }"
- ```
-
- The first style is extremely more popular and you're generally
- advised to stick with it. The second, on the other hand, is
- (arguably) a bit more readable. As with hashes - pick one style
- and apply it consistently.
-
-*
- No spaces after `(`, `[` or before `]`, `)`.
-[[link](#no-spaces-braces)]
-
- ```Ruby
- some(arg).other
- [1, 2, 3].size
- ```
-
-*
- No space after `!`.
-[[link](#no-space-bang)]
-
- ```Ruby
- # bad
- ! something
-
- # good
- !something
- ```
-
-*
- No space inside range literals.
-[[link](#no-space-inside-range-literals)]
-
- ```Ruby
- # bad
- 1 .. 3
- 'a' ... 'z'
-
- # good
- 1..3
- 'a'..'z'
- ```
-
-*
- Indent `when` as deep as `case`. I know that many would disagree
- with this one, but it's the style established in both "The Ruby
- Programming Language" and "Programming Ruby".
-[[link](#indent-when-to-case)]
-
- ```Ruby
- # bad
- 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
-
- # good
- 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
- ```
-
-*
- When assigning the result of a conditional expression to a variable,
- preserve the usual alignment of its branches.
-[[link](#indent-conditional-assignment)]
-
- ```Ruby
- # bad - pretty convoluted
- 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
-
- result = if some_cond
- calc_something
- else
- calc_something_else
- end
-
- # good - it's apparent what's going on
- 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
-
- result = if some_cond
- calc_something
- else
- calc_something_else
- end
-
- # good (and a bit more width efficient)
- 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
-
- result =
- if some_cond
- calc_something
- else
- calc_something_else
- end
- ```
-
-*
- Use empty lines between method definitions and also to break up a method
- into logical paragraphs internally.
-[[link](#empty-lines-between-methods)]
-
- ```Ruby
- def some_method
- data = initialize(options)
-
- data.manipulate!
-
- data.result
- end
-
- def some_method
- result
- end
- ```
-
-*
- Avoid comma after the last parameter in a method call, especially when the
- parameters are not on separate lines.
-[[link](#no-trailing-params-comma)]
-
- ```Ruby
- # bad - easier to move/add/remove parameters, but still not preferred
- some_method(
- size,
- count,
- color,
- )
-
- # bad
- some_method(size, count, color, )
-
- # good
- some_method(size, count, color)
- ```
-
-*
- Use spaces around the `=` operator when assigning default values to method
- parameters:
-[[link](#spaces-around-equals)]
-
- ```Ruby
- # bad
- def some_method(arg1=:default, arg2=nil, arg3=[])
- # do something...
- end
-
- # good
- def some_method(arg1 = :default, arg2 = nil, arg3 = [])
- # do something...
- end
- ```
-
- While several Ruby books suggest the first style, the second is much more
- prominent in practice (and arguably a bit more readable).
-
-*
- Avoid line continuation `\` where not required. In practice, avoid using
- line continuations for anything but string concatenation.
-[[link](#no-trailing-backslash)]
-
- ```Ruby
- # bad
- result = 1 - \
- 2
-
- # good (but still ugly as hell)
- result = 1 \
- - 2
-
- long_string = 'First part of the long string' \
- ' and second part of the long string'
- ```
-
-*
- Adopt a consistent multi-line method chaining style. There are two
- popular styles in the Ruby community, both of which are considered
- good - leading `.` (Option A) and trailing `.` (Option B).
-[[link](#consistent-multi-line-chains)]
-
- * **(Option A)** When continuing a chained method invocation on
- another line keep the `.` on the second line.
-
- ```Ruby
- # bad - need to consult first line to understand second line
- one.two.three.
- four
-
- # good - it's immediately clear what's going on the second line
- one.two.three
- .four
- ```
-
- * **(Option B)** When continuing a chained method invocation on another line,
- include the `.` on the first line to indicate that the
- expression continues.
-
- ```Ruby
- # bad - need to read ahead to the second line to know that the chain continues
- one.two.three
- .four
-
- # good - it's immediately clear that the expression continues beyond the first line
- one.two.three.
- four
- ```
-
- A discussion on the merits of both alternative styles can be found
- [here](https://github.com/bbatsov/ruby-style-guide/pull/176).
-
-*
- Align the parameters of a method call if they span more than one
- line. When aligning parameters is not appropriate due to line-length
- constraints, single indent for the lines after the first is also
- acceptable.
-[[link](#no-double-indent)]
-
- ```Ruby
- # starting point (line is too long)
- def send_mail(source)
- Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
- end
-
- # bad (double indent)
- def send_mail(source)
- Mailer.deliver(
- to: 'bob@example.com',
- from: 'us@example.com',
- subject: 'Important message',
- body: source.text)
- end
-
- # good
- def send_mail(source)
- Mailer.deliver(to: 'bob@example.com',
- from: 'us@example.com',
- subject: 'Important message',
- body: source.text)
- end
-
- # good (normal indent)
- def send_mail(source)
- Mailer.deliver(
- to: 'bob@example.com',
- from: 'us@example.com',
- subject: 'Important message',
- body: source.text
- )
- end
- ```
-
-*
- Align the elements of array literals spanning multiple lines.
-[[link](#align-multiline-arrays)]
-
- ```Ruby
- # bad - single indent
- menu_item = ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
- 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
-
- # good
- menu_item = [
- 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
- 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam'
- ]
-
- # good
- menu_item =
- ['Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam',
- 'Baked beans', 'Spam', 'Spam', 'Spam', 'Spam', 'Spam']
- ```
-
-*
- Add underscores to large numeric literals to improve their readability.
-[[link](#underscores-in-numerics)]
-
- ```Ruby
- # bad - how many 0s are there?
- num = 1000000
-
- # good - much easier to parse for the human brain
- num = 1_000_000
- ```
-
-*
- Use RDoc and its conventions for API documentation. Don't put an
- empty line between the comment block and the `def`.
-[[link](#rdoc-conventions)]
-
-*
- Limit lines to 80 characters.
-[[link](#80-character-limits)]
-
-*
- Avoid trailing whitespace.
-[[link](#no-trailing-whitespace)]
-
-*
- End each file with a newline.
-[[link](#newline-eof)]
-
-*
- Don't use block comments. They cannot be preceded by whitespace and are not
- as easy to spot as regular comments.
-[[link](#no-block-comments)]
-
- ```Ruby
- # bad
- =begin
- comment line
- another comment line
- =end
-
- # good
- # comment line
- # another comment line
- ```
-
-## Syntax
-
-*
- Use `::` only to reference constants(this includes classes and
- modules) and constructors (like `Array()` or `Nokogiri::HTML()`).
- Do not use `::` for regular method invocation.
-[[link](#double-colons)]
-
- ```Ruby
- # bad
- SomeClass::some_method
- some_object::some_method
-
- # good
- SomeClass.some_method
- some_object.some_method
- SomeModule::SomeClass::SOME_CONST
- SomeModule::SomeClass()
- ```
-
-*
- Use `def` with parentheses when there are arguments. Omit the
- parentheses when the method doesn't accept any arguments.
-[[link](#method-parens)]
-
- ```Ruby
- # bad
- def some_method()
- # body omitted
- end
-
- # good
- def some_method
- # body omitted
- end
-
- # bad
- def some_method_with_arguments arg1, arg2
- # body omitted
- end
-
- # good
- def some_method_with_arguments(arg1, arg2)
- # body omitted
- end
- ```
-
-*
- Do not use `for`, unless you know exactly why. Most of the time iterators
- should be used instead. `for` is implemented in terms of `each` (so
- you're adding a level of indirection), but with a twist - `for`
- doesn't introduce a new scope (unlike `each`) and variables defined
- in its block will be visible outside it.
-[[link](#no-for-loops)]
-
- ```Ruby
- arr = [1, 2, 3]
-
- # bad
- for elem in arr do
- puts elem
- end
-
- # note that elem is accessible outside of the for loop
- elem # => 3
-
- # good
- arr.each { |elem| puts elem }
-
- # elem is not accessible outside each's block
- elem # => NameError: undefined local variable or method `elem'
- ```
-
-*
- Do not use `then` for multi-line `if/unless`.
-[[link](#no-then)]
-
- ```Ruby
- # bad
- if some_condition then
- # body omitted
- end
-
- # good
- if some_condition
- # body omitted
- end
- ```
-
-*
- Always put the condition on the same line as the `if`/`unless` in a
- multi-line conditional.
-[[link](#same-line-condition)]
-
- ```Ruby
- # bad
- if
- some_condition
- do_something
- do_something_else
- end
-
- # good
- if some_condition
- do_something
- do_something_else
- end
- ```
-
-*
- Favor the ternary operator(`?:`) over `if/then/else/end` constructs.
- It's more common and obviously more concise.
-[[link](#ternary-operator)]
-
- ```Ruby
- # bad
- result = if some_condition then something else something_else end
-
- # good
- result = some_condition ? something : something_else
- ```
-
-*
- Use one expression per branch in a ternary operator. This
- also means that ternary operators must not be nested. Prefer
- `if/else` constructs in these cases.
-[[link](#no-nested-ternary)]
-
- ```Ruby
- # 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
- ```
-
-*
- Do not use `if x; ...`. Use the ternary
- operator instead.
-[[link](#no-semicolon-ifs)]
-
- ```Ruby
- # bad
- result = if some_condition; something else something_else end
-
- # good
- result = some_condition ? something : something_else
- ```
-
-*
- Leverage the fact that `if` and `case` are expressions which return a
- result.
-[[link](#use-if-case-returns)]
-
- ```Ruby
- # bad
- if condition
- result = x
- else
- result = y
- end
-
- # good
- result =
- if condition
- x
- else
- y
- end
- ```
-
-*
- Use `when x then ...` for one-line cases. The alternative syntax `when x:
- ...` has been removed as of Ruby 1.9.
-[[link](#one-line-cases)]
-
-*
- Do not use `when x; ...`. See the previous rule.
-[[link](#no-when-semicolons)]
-
-*
- Use `!` instead of `not`.
-[[link](#bang-not-not)]
-
- ```Ruby
- # bad - braces are required because of op precedence
- x = (not something)
-
- # good
- x = !something
- ```
-
-*
- Avoid the use of `!!`.
-[[link](#no-bang-bang)]
-
- ```Ruby
- # bad
- x = 'test'
- # obscure nil check
- if !!x
- # body omitted
- end
-
- x = false
- # double negation is useless on booleans
- !!x # => false
-
- # good
- x = 'test'
- unless x.nil?
- # body omitted
- end
- ```
-
-*
- The `and` and `or` keywords are banned. It's just not worth it. Always use
- `&&` and `||` instead.
-[[link](#no-and-or-or)]
-
- ```Ruby
- # bad
- # boolean expression
- if some_condition and some_other_condition
- do_something
- end
-
- # control flow
- document.saved? or document.save!
-
- # good
- # boolean expression
- if some_condition && some_other_condition
- do_something
- end
-
- # control flow
- document.saved? || document.save!
- ```
-
-*
- Avoid multi-line `?:` (the ternary operator); use `if/unless` instead.
-[[link](#no-multiline-ternary)]
-
-*
- Favor modifier `if/unless` usage when you have a single-line body. Another
- good alternative is the usage of control flow `&&/||`.
-[[link](#if-as-a-modifier)]
-
- ```Ruby
- # bad
- if some_condition
- do_something
- end
-
- # good
- do_something if some_condition
-
- # another good option
- some_condition && do_something
- ```
-
-*
- Avoid modifier `if/unless` usage at the end of a non-trivial multi-line
- block.
-[[link](#no-multiline-if-modifiers)]
-
- ```Ruby
- # bad
- 10.times do
- # multi-line body omitted
- end if some_condition
-
- # good
- if some_condition
- 10.times do
- # multi-line body omitted
- end
- end
- ```
-
-*
- Favor `unless` over `if` for negative conditions (or control flow `||`).
-[[link](#unless-for-negatives)]
-
- ```Ruby
- # bad
- do_something if !some_condition
-
- # bad
- do_something if not some_condition
-
- # good
- do_something unless some_condition
-
- # another good option
- some_condition || do_something
- ```
-
-*
- Do not use `unless` with `else`. Rewrite these with the positive case first.
-[[link](#no-else-with-unless)]
-
- ```Ruby
- # bad
- unless success?
- puts 'failure'
- else
- puts 'success'
- end
-
- # good
- if success?
- puts 'success'
- else
- puts 'failure'
- end
- ```
-
-*
- Don't use parentheses around the condition of an `if/unless/while/until`.
-[[link](#no-parens-if)]
-
- ```Ruby
- # bad
- if (x > 10)
- # body omitted
- end
-
- # good
- if x > 10
- # body omitted
- end
- ```
-
-Note that there is an exception to this rule, namely [safe assignment in
-condition](#safe-assignment-in-condition).
-
-*
- Do not use `while/until condition do` for multi-line `while/until`.
-[[link](#no-multiline-while-do)]
-
- ```Ruby
- # bad
- while x > 5 do
- # body omitted
- end
-
- until x > 5 do
- # body omitted
- end
-
- # good
- while x > 5
- # body omitted
- end
-
- until x > 5
- # body omitted
- end
- ```
-
-*
- Favor modifier `while/until` usage when you have a single-line body.
-[[link](#while-as-a-modifier)]
-
- ```Ruby
- # bad
- while some_condition
- do_something
- end
-
- # good
- do_something while some_condition
- ```
-
-*
- Favor `until` over `while` for negative conditions.
-[[link](#until-for-negatives)]
-
- ```Ruby
- # bad
- do_something while !some_condition
-
- # good
- do_something until some_condition
- ```
-
-*
- Use `Kernel#loop` instead of `while/until` when you need an infinite loop.
-[[link](#infinite-loop)]
-
- ```ruby
- # bad
- while true
- do_something
- end
-
- until false
- do_something
- end
-
- # good
- loop do
- do_something
- end
- ```
-
-*
- Use `Kernel#loop` with `break` rather than `begin/end/until` or
- `begin/end/while` for post-loop tests.
-[[link](#loop-with-break)]
-
- ```Ruby
- # bad
- begin
- puts val
- val += 1
- end while val < 0
-
- # good
- loop do
- puts val
- val += 1
- break unless val < 0
- end
- ```
-
-*
- Omit parentheses around parameters for methods that are part of an internal
- DSL (e.g. Rake, Rails, RSpec), methods that have "keyword" status in Ruby
- (e.g. `attr_reader`, `puts`) and attribute access methods. Use parentheses
- around the arguments of all other method invocations.
-[[link](#no-dsl-parens)]
-
- ```Ruby
- class Person
- attr_reader :name, :age
-
- # omitted
- end
-
- temperance = Person.new('Temperance', 30)
- temperance.name
-
- puts temperance.age
-
- x = Math.sin(y)
- array.delete(e)
-
- bowling.score.should == 0
- ```
-
-*
- Omit the outer braces around an implicit options hash.
-[[link](#no-braces-opts-hash)]
-
- ```Ruby
- # bad
- user.set({ name: 'John', age: 45, permissions: { read: true } })
-
- # good
- user.set(name: 'John', age: 45, permissions: { read: true })
- ```
-
-*
- Omit both the outer braces and parentheses for methods that are part of an
- internal DSL.
-[[link](#no-dsl-decorating)]
-
- ```Ruby
- class Person < ActiveRecord::Base
- # bad
- validates(:name, { presence: true, length: { within: 1..10 } })
-
- # good
- validates :name, presence: true, length: { within: 1..10 }
- end
- ```
-
-*
- Omit parentheses for method calls with no arguments.
-[[link](#no-args-no-parens)]
-
- ```Ruby
- # bad
- Kernel.exit!()
- 2.even?()
- fork()
- 'test'.upcase()
-
- # good
- Kernel.exit!
- 2.even?
- fork
- 'test'.upcase
- ```
-
-*
- Prefer `{...}` over `do...end` for single-line blocks. Avoid using `{...}`
- for multi-line blocks (multiline chaining is always ugly). Always use
- `do...end` for "control flow" and "method definitions" (e.g. in Rakefiles and
- certain DSLs). Avoid `do...end` when chaining.
-[[link](#single-line-blocks)]
-
- ```Ruby
- names = ['Bozhidar', 'Steve', 'Sarah']
-
- # bad
- names.each do |name|
- puts name
- end
-
- # good
- names.each { |name| puts name }
-
- # bad
- names.select do |name|
- name.start_with?('S')
- end.map { |name| name.upcase }
-
- # good
- names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
- ```
-
- Some will argue that multiline chaining would look OK with the use of {...},
- but they should ask themselves - is this code really readable and can the
- blocks' contents be extracted into nifty methods?
-
-*
- Consider using explicit block argument to avoid writing block literal that
- just passes its arguments to another block. Beware of the performance impact,
- though, as the block gets converted to a Proc.
-[[link](#block-argument)]
-
- ```Ruby
- require 'tempfile'
-
- # bad
- def with_tmp_dir
- Dir.mktmpdir do |tmp_dir|
- Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments
- end
- end
-
- # good
- def with_tmp_dir(&block)
- Dir.mktmpdir do |tmp_dir|
- Dir.chdir(tmp_dir, &block)
- end
- end
-
- with_tmp_dir do |dir|
- puts "dir is accessible as a parameter and pwd is set: #{dir}"
- end
- ```
-
-*
- Avoid `return` where not required for flow of control.
-[[link](#no-explicit-return)]
-
- ```Ruby
- # bad
- def some_method(some_arr)
- return some_arr.size
- end
-
- # good
- def some_method(some_arr)
- some_arr.size
- end
- ```
-
-*
- Avoid `self` where not required. (It is only required when calling a self
- write accessor.)
-[[link](#no-self-unless-required)]
-
- ```Ruby
- # bad
- def ready?
- if self.last_reviewed_at > self.last_updated_at
- self.worker.update(self.content, self.options)
- self.status = :in_progress
- end
- self.status == :verified
- end
-
- # good
- def ready?
- if last_reviewed_at > last_updated_at
- worker.update(content, options)
- self.status = :in_progress
- end
- status == :verified
- end
- ```
-
-*
- As a corollary, avoid shadowing methods with local variables unless they are
- both equivalent.
-[[link](#no-shadowing)]
-
- ```Ruby
- class Foo
- attr_accessor :options
-
- # ok
- def initialize(options)
- self.options = options
- # both options and self.options are equivalent here
- end
-
- # bad
- def do_something(options = {})
- unless options[:when] == :later
- output(self.options[:message])
- end
- end
-
- # good
- def do_something(params = {})
- unless params[:when] == :later
- output(options[:message])
- end
- end
- end
- ```
-
-*
- Don't use the return value of `=` (an assignment) in conditional expressions
- unless the assignment is wrapped in parentheses. This is a fairly popular
- idiom among Rubyists that's sometimes referred to as *safe assignment in
- condition*.
-[[link](#safe-assignment-in-condition)]
-
- ```Ruby
- # bad (+ a warning)
- if v = array.grep(/foo/)
- do_something(v)
- ...
- end
-
- # good (MRI would still complain, but RuboCop won't)
- if (v = array.grep(/foo/))
- do_something(v)
- ...
- end
-
- # good
- v = array.grep(/foo/)
- if v
- do_something(v)
- ...
- end
- ```
-
-*
- Use shorthand self assignment operators whenever applicable.
-[[link](#self-assignment)]
-
- ```Ruby
- # bad
- x = x + y
- x = x * y
- x = x**y
- x = x / y
- x = x || y
- x = x && y
-
- # good
- x += y
- x *= y
- x **= y
- x /= y
- x ||= y
- x &&= y
- ```
-
-*
- Use `||=` to initialize variables only if they're not already initialized.
-[[link](#double-pipe-for-uninit)]
-
- ```Ruby
- # bad
- name = name ? name : 'Bozhidar'
-
- # bad
- name = 'Bozhidar' unless name
-
- # good - set name to Bozhidar, only if it's nil or false
- name ||= 'Bozhidar'
- ```
-
-*
- Don't use `||=` to initialize boolean variables. (Consider what would happen
- if the current value happened to be `false`.)
-[[link](#no-double-pipes-for-bools)]
-
- ```Ruby
- # bad - would set enabled to true even if it was false
- enabled ||= true
-
- # good
- enabled = true if enabled.nil?
- ```
-
-*
- Use `&&=` to preprocess variables that may or may not exist. Using `&&=`
- will change the value only if it exists, removing the need to check its
- existence with `if`.
-[[link](#double-amper-preprocess)]
-
- ```Ruby
- # bad
- if something
- something = something.downcase
- end
-
- # bad
- something = something ? something.downcase : nil
-
- # ok
- something = something.downcase if something
-
- # good
- something = something && something.downcase
-
- # better
- something &&= something.downcase
- ```
-
-*
- Avoid explicit use of the case equality operator `===`. As its name implies
- it is meant to be used implicitly by `case` expressions and outside of them it
- yields some pretty confusing code.
-[[link](#no-case-equality)]
-
- ```Ruby
- # bad
- Array === something
- (1..100) === 7
- /something/ === some_string
-
- # good
- something.is_a?(Array)
- (1..100).include?(7)
- some_string =~ /something/
- ```
-
-*
- Do not use `eql?` when using `==` will do. The stricter comparison semantics
- provided by `eql?` are rarely needed in practice.
-[[link](#eql)]
-
- ```Ruby
- # bad - eql? is the same as == for strings
- "ruby".eql? some_str
-
- # good
- "ruby" == some_str
- 1.0.eql? == x # eql? makes sense here if want to differentiate between Fixnum and Float 1
- ```
-
-*
- Avoid using Perl-style special variables (like `$:`, `$;`, etc. ). They are
- quite cryptic and their use in anything but one-liner scripts is discouraged.
- Use the human-friendly aliases provided by the `English` library.
-[[link](#no-cryptic-perlisms)]
-
- ```Ruby
- # bad
- $:.unshift File.dirname(__FILE__)
-
- # good
- require 'English'
- $LOAD_PATH.unshift File.dirname(__FILE__)
- ```
-
-*
- Do not put a space between a method name and the opening parenthesis.
-[[link](#parens-no-spaces)]
-
- ```Ruby
- # bad
- f (3 + 2) + 1
-
- # good
- f(3 + 2) + 1
- ```
-
-*
- If the first argument to a method begins with an open parenthesis, always
- use parentheses in the method invocation. For example, write `f((3 + 2) + 1)`.
-[[link](#parens-as-args)]
-
-*
- Always run the Ruby interpreter with the `-w` option so it will warn you if
- you forget either of the rules above!
-[[link](#always-warn-at-runtime)]
-
-*
- Use the new lambda literal syntax for single line body blocks. Use the
- `lambda` method for multi-line blocks.
-[[link](#lambda-multi-line)]
-
- ```Ruby
- # bad
- l = lambda { |a, b| a + b }
- l.call(1, 2)
-
- # correct, but looks extremely awkward
- l = ->(a, b) do
- tmp = a * 7
- tmp * b / 50
- end
-
- # good
- l = ->(a, b) { a + b }
- l.call(1, 2)
-
- l = lambda do |a, b|
- tmp = a * 7
- tmp * b / 50
- end
- ```
-
-*
- Prefer `proc` over `Proc.new`.
-[[link](#proc)]
-
- ```Ruby
- # bad
- p = Proc.new { |n| puts n }
-
- # good
- p = proc { |n| puts n }
- ```
-
-*
- Prefer `proc.call()` over `proc[]` or `proc.()` for both lambdas and procs.
-[[link](#proc-call)]
-
- ```Ruby
- # bad - looks similar to Enumeration access
- l = ->(v) { puts v }
- l[1]
-
- # also bad - uncommon syntax
- l = ->(v) { puts v }
- l.(1)
-
- # good
- l = ->(v) { puts v }
- l.call(1)
- ```
-
-*
- Prefix with `_` unused block parameters and local variables. It's also
- acceptable to use just `_` (although it's a bit less descriptive). This
- convention is recognized by the Ruby interpreter and tools like RuboCop and
- will suppress their unused variable warnings.
-[[link](#underscore-unused-vars)]
-
- ```Ruby
- # bad
- result = hash.map { |k, v| v + 1 }
-
- def something(x)
- unused_var, used_var = something_else(x)
- # ...
- end
-
- # good
- result = hash.map { |_k, v| v + 1 }
-
- def something(x)
- _unused_var, used_var = something_else(x)
- # ...
- end
-
- # good
- result = hash.map { |_, v| v + 1 }
-
- def something(x)
- _, used_var = something_else(x)
- # ...
- end
- ```
-
-*
- Use `$stdout/$stderr/$stdin` instead of `STDOUT/STDERR/STDIN`.
- `STDOUT/STDERR/STDIN` are constants, and while you can actually reassign
- (possibly to redirect some stream) constants in Ruby, you'll get an
- interpreter warning if you do so.
-[[link](#global-stdout)]
-
-*
- Use `warn` instead of `$stderr.puts`. Apart from being more concise and
- clear, `warn` allows you to suppress warnings if you need to (by setting the
- warn level to 0 via `-W0`).
-[[link](#warn)]
-
-*
- Favor the use of `sprintf` and its alias `format` over the fairly cryptic
- `String#%` method.
-[[link](#sprintf)]
-
- ```Ruby
- # bad
- '%d %d' % [20, 10]
- # => '20 10'
-
- # good
- sprintf('%d %d', 20, 10)
- # => '20 10'
-
- # good
- sprintf('%{first} %{second}', first: 20, second: 10)
- # => '20 10'
-
- format('%d %d', 20, 10)
- # => '20 10'
-
- # good
- format('%{first} %{second}', first: 20, second: 10)
- # => '20 10'
- ```
-
-*
- Favor the use of `Array#join` over the fairly cryptic `Array#*` with
-[[link](#array-join)]
- a string argument.
-
- ```Ruby
- # bad
- %w(one two three) * ', '
- # => 'one, two, three'
-
- # good
- %w(one two three).join(', ')
- # => 'one, two, three'
- ```
-
-*
- Use `[*var]` or `Array()` instead of explicit `Array` check, when dealing
- with a variable you want to treat as an Array, but you're not certain it's an
- array.
-[[link](#splat-arrays)]
-
- ```Ruby
- # bad
- paths = [paths] unless paths.is_a? Array
- paths.each { |path| do_something(path) }
-
- # good
- [*paths].each { |path| do_something(path) }
-
- # good (and a bit more readable)
- Array(paths).each { |path| do_something(path) }
- ```
-
-*
- Use ranges or `Comparable#between?` instead of complex comparison logic when
- possible.
-[[link](#ranges-or-between)]
-
- ```Ruby
- # bad
- do_something if x >= 1000 && x <= 2000
-
- # good
- do_something if (1000..2000).include?(x)
-
- # good
- do_something if x.between?(1000, 2000)
- ```
-
-*
- Favor the use of predicate methods to explicit comparisons with `==`.
- Numeric comparisons are OK.
-[[link](#predicate-methods)]
-
- ```Ruby
- # bad
- if x % 2 == 0
- end
-
- if x % 2 == 1
- end
-
- if x == nil
- end
-
- # good
- if x.even?
- end
-
- if x.odd?
- end
-
- if x.nil?
- end
-
- if x.zero?
- end
-
- if x == 0
- end
- ```
-
-*
- Don't do explicit non-`nil` checks unless you're dealing with boolean
- values.
-[[link](#no-non-nil-checks)]
-
- ```ruby
- # bad
- do_something if !something.nil?
- do_something if something != nil
-
- # good
- do_something if something
-
- # good - dealing with a boolean
- def value_set?
- !@some_boolean.nil?
- end
- ```
-
-*
- Avoid the use of `BEGIN` blocks.
-[[link](#no-BEGIN-blocks)]
-
-*
- Do not use `END` blocks. Use `Kernel#at_exit` instead.
-[[link](#no-END-blocks)]
-
- ```ruby
- # bad
- END { puts 'Goodbye!' }
-
- # good
- at_exit { puts 'Goodbye!' }
- ```
-
-*
- Avoid the use of flip-flops.
-[[link](#no-flip-flops)]
-
-*
- Avoid use of nested conditionals for flow of control.
-[[link](#no-nested-conditionals)]
-
- Prefer a guard clause when you can assert invalid data. A guard clause
- is a conditional statement at the top of a function that bails out as
- soon as it can.
-
- ```Ruby
- # bad
- def compute_thing(thing)
- if thing[:foo]
- update_with_bar(thing)
- if thing[:foo][:bar]
- partial_compute(thing)
- else
- re_compute(thing)
- end
- end
- end
-
- # good
- def compute_thing(thing)
- return unless thing[:foo]
- update_with_bar(thing[:foo])
- return re_compute(thing) unless thing[:foo][:bar]
- partial_compute(thing)
- end
- ```
-
- Prefer `next` in loops instead of conditional blocks.
-
- ```Ruby
- # bad
- [0, 1, 2, 3].each do |item|
- if item > 1
- puts item
- end
- end
-
- # good
- [0, 1, 2, 3].each do |item|
- next unless item > 1
- puts item
- end
- ```
-
-*
- Prefer `map` over `collect`, `find` over `detect`, `select` over `find_all`,
- `reduce` over `inject` and `size` over `length`. This is not a hard
- requirement; if the use of the alias enhances readability, it's ok to use it.
- The rhyming methods are inherited from Smalltalk and are not common in other
- programming languages. The reason the use of `select` is encouraged over
- `find_all` is that it goes together nicely with `reject` and its name is
- pretty self-explanatory.
-[[link](#map-fine-select-reduce-size)]
-
-*
- Don't use `count` as a substitute for `size`. For `Enumerable` objects other
- than `Array` it will iterate the entire collection in order to determine its
- size.
-[[link](#count-vs-size)]
-
- ```Ruby
- # bad
- some_hash.count
-
- # good
- some_hash.size
- ```
-
-*
- Use `flat_map` instead of `map` + `flatten`. This does not apply for arrays
- with a depth greater than 2, i.e. if `users.first.songs == ['a', ['b','c']]`,
- then use `map + flatten` rather than `flat_map`. `flat_map` flattens the
- array by 1, whereas `flatten` flattens it all the way.
-[[link](#flat-map)]
-
- ```Ruby
- # bad
- all_songs = users.map(&:songs).flatten.uniq
-
- # good
- all_songs = users.flat_map(&:songs).uniq
- ```
-
-*
- Use `reverse_each` instead of `reverse.each`. `reverse_each` doesn't do a
- new array allocation and that's a good thing.
-[[link](#reverse-each)]
-
- ```Ruby
- # bad
- array.reverse.each { ... }
-
- # good
- array.reverse_each { ... }
- ```
-
-## Naming
-
-> The only real difficulties in programming are cache invalidation and
-> naming things.
-> -- Phil Karlton
-
-*
- Name identifiers in English.
-[[link](#english-identifiers)]
-
- ```Ruby
- # bad - identifier using non-ascii characters
- заплата = 1_000
-
- # bad - identifier is a Bulgarian word, written with Latin letters (instead of Cyrillic)
- zaplata = 1_000
-
- # good
- salary = 1_000
- ```
-
-*
- Use `snake_case` for symbols, methods and variables.
-[[link](#snake-case-symbols-methods-vars)]
-
- ```Ruby
- # bad
- :'some symbol'
- :SomeSymbol
- :someSymbol
-
- someVar = 5
-
- def someMethod
- ...
- end
-
- def SomeMethod
- ...
- end
-
- # good
- :some_symbol
-
- def some_method
- ...
- end
- ```
-
-*
- Use `CamelCase` for classes and modules. (Keep acronyms like HTTP, RFC, XML
- uppercase.)
-[[link](#camelcase-classes)]
-
- ```Ruby
- # bad
- class Someclass
- ...
- end
-
- class Some_Class
- ...
- end
-
- class SomeXml
- ...
- end
-
- # good
- class SomeClass
- ...
- end
-
- class SomeXML
- ...
- end
- ```
-
-*
- Use `snake_case` for naming files, e.g. `hello_world.rb`.
-[[link](#snake-case-files)]
-
-*
- Use `snake_case` for naming directories, e.g.
- `lib/hello_world/hello_world.rb`.
-[[link](#snake-case-dirs)]
-
-*
- Aim to have just a single class/module per source file. Name the file name
- as the class/module, but replacing CamelCase with snake_case.
-[[link](#one-class-per-file)]
-
-*
- Use `SCREAMING_SNAKE_CASE` for other constants.
-[[link](#screaming-snake-case)]
-
- ```Ruby
- # bad
- SomeConst = 5
-
- # good
- SOME_CONST = 5
- ```
-
-*
- The names of predicate methods (methods that return a boolean value) should
- end in a question mark. (i.e. `Array#empty?`). Methods that don't return a
- boolean, shouldn't end in a question mark.
-[[link](#bool-methods-qmark)]
-
-*
- The names of potentially *dangerous* methods (i.e. methods that modify
- `self` or the arguments, `exit!` (doesn't run the finalizers like `exit`
- does), etc.) should end with an exclamation mark if there exists a safe
- version of that *dangerous* method.
-[[link](#dangerous-method-bang)]
-
- ```Ruby
- # bad - there is no matching 'safe' method
- class Person
- def update!
- end
- end
-
- # good
- class Person
- def update
- end
- end
-
- # good
- class Person
- def update!
- end
-
- def update
- end
- end
- ```
-
-*
- Define the non-bang (safe) method in terms of the bang (dangerous) one if
- possible.
-[[link](#safe-because-unsafe)]
-
- ```Ruby
- class Array
- def flatten_once!
- res = []
-
- each do |e|
- [*e].each { |f| res << f }
- end
-
- replace(res)
- end
-
- def flatten_once
- dup.flatten_once!
- end
- end
- ```
-
-*
- When using `reduce` with short blocks, name the arguments `|a, e|`
- (accumulator, element).
-[[link](#reduce-blocks)]
-
-*
- When defining binary operators, name the argument `other`(`<<` and `[]` are
- exceptions to the rule, since their semantics are different).
-[[link](#other-arg)]
-
- ```Ruby
- def +(other)
- # body omitted
- end
- ```
-
-## Comments
-
-> Good code is its own best documentation. As you're about to add a
-> comment, ask yourself, "How can I improve the code so that this
-> comment isn't needed?" Improve the code and then document it to make
-> it even clearer.
-> -- Steve McConnell
-
-*
- Write self-documenting code and ignore the rest of this section. Seriously!
-[[link](#no-comments)]
-
-*
- Write comments in English.
-[[link](#english-comments)]
-
-*
- Use one space between the leading `#` character of the comment and the text
- of the comment.
-[[link](#hash-space)]
-
-*
- Comments longer than a word are capitalized and use punctuation. Use [one
- space](http://en.wikipedia.org/wiki/Sentence_spacing) after periods.
-[[link](#english-syntax)]
-
-*
- Avoid superfluous comments.
-[[link](#no-superfluous-comments)]
-
- ```Ruby
- # bad
- counter += 1 # Increments counter by one.
- ```
-
-*
- Keep existing comments up-to-date. An outdated comment is worse than no
- comment at all.
-[[link](#comment-upkeep)]
-
-> Good code is like a good joke - it needs no explanation.
-> -- Russ Olsen
-
-*
- Avoid writing comments to explain bad code. Refactor the code to make it
- self-explanatory. (Do or do not - there is no try. --Yoda)
-[[link](#refactor-dont-comment)]
-
-### Comment Annotations
-
-*
- Annotations should usually be written on the line immediately above the
- relevant code.
-[[link](#annotate-above)]
-
-*
- The annotation keyword is followed by a colon and a space, then a note
- describing the problem.
-[[link](#annotate-keywords)]
-
-*
- If multiple lines are required to describe the problem, subsequent lines
- should be indented two spaces after the `#`.
-[[link](#indent-annotations)]
-
- ```Ruby
- def bar
- # FIXME: This has crashed occasionally since v3.2.1. It may
- # be related to the BarBazUtil upgrade.
- baz(:quux)
- end
- ```
-
-*
- In cases where the problem is so obvious that any documentation would be
- redundant, annotations may be left at the end of the offending line with no
- note. This usage should be the exception and not the rule.
-[[link](#rare-eol-annotations)]
-
- ```Ruby
- def bar
- sleep 100 # OPTIMIZE
- end
- ```
-
-*
- Use `TODO` to note missing features or functionality that should be added at
- a later date.
-[[link](#todo)]
-
-*
- Use `FIXME` to note broken code that needs to be fixed.
-[[link](#fixme)]
-
-*
- Use `OPTIMIZE` to note slow or inefficient code that may cause performance
- problems.
-[[link](#optimize)]
-
-*
- Use `HACK` to note code smells where questionable coding practices were used
- and should be refactored away.
-[[link](#hack)]
-
-*
- Use `REVIEW` to note anything that should be looked at to confirm it is
- working as intended. For example: `REVIEW: Are we sure this is how the client
- does X currently?`
-[[link](#review)]
-
-*
- Use other custom annotation keywords if it feels appropriate, but be sure to
- document them in your project's `README` or similar.
-[[link](#document-annotations)]
-
-## Classes & Modules
-
-*
- Use a consistent structure in your class definitions.
-[[link](#consistent-classes)]
-
- ```Ruby
- class Person
- # extend and include go first
- extend SomeModule
- include AnotherModule
-
- # inner classes
- CustomErrorKlass = Class.new(StandardError)
-
- # constants are next
- SOME_CONSTANT = 20
-
- # afterwards we have attribute macros
- attr_reader :name
-
- # followed by other macros (if any)
- validates :name
-
- # public class methods are next in line
- def self.some_method
- end
-
- # followed by public instance methods
- def some_method
- end
-
- # protected and private methods are grouped near the end
- protected
-
- def some_protected_method
- end
-
- private
-
- def some_private_method
- end
- end
- ```
-
-*
- Don't nest multi line classes within classes. Try to have such nested
- classes each in their own file in a folder named like the containing class.
-[[link](#file-classes)]
-
- ```Ruby
- # bad
-
- # foo.rb
- class Foo
- class Bar
- # 30 methods inside
- end
-
- class Car
- # 20 methods inside
- end
-
- # 30 methods inside
- end
-
- # good
-
- # foo.rb
- class Foo
- # 30 methods inside
- end
-
- # foo/bar.rb
- class Foo
- class Bar
- # 30 methods inside
- end
- end
-
- # foo/car.rb
- class Foo
- class Car
- # 20 methods inside
- end
- end
- ```
-
-*
- Prefer modules to classes with only class methods. Classes should be used
- only when it makes sense to create instances out of them.
-[[link](#modules-vs-classes)]
-
- ```Ruby
- # bad
- class SomeClass
- def self.some_method
- # body omitted
- end
-
- def self.some_other_method
- end
- end
-
- # good
- module SomeModule
- module_function
-
- def some_method
- # body omitted
- end
-
- def some_other_method
- end
- end
- ```
-
-*
- Favor the use of `module_function` over `extend self` when you want to turn
- a module's instance methods into class methods.
-[[link](#module-function)]
-
- ```Ruby
- # bad
- module Utilities
- extend self
-
- def parse_something(string)
- # do stuff here
- end
-
- def other_utility_method(number, string)
- # do some more stuff
- end
- end
-
- # good
- module Utilities
- module_function
-
- def parse_something(string)
- # do stuff here
- end
-
- def other_utility_method(number, string)
- # do some more stuff
- end
- end
- ```
-
-*
- When designing class hierarchies make sure that they conform to the [Liskov
- Substitution
- Principle](http://en.wikipedia.org/wiki/Liskov_substitution_principle).
-[[link](#liskov)]
-
-*
- Try to make your classes as
- [SOLID](http://en.wikipedia.org/wiki/SOLID_\(object-oriented_design\)) as
- possible.
-[[link](#solid-design)]
-
-*
- Always supply a proper `to_s` method for classes that represent domain
- objects.
-[[link](#define-to-s)]
-
- ```Ruby
- class Person
- attr_reader :first_name, :last_name
-
- def initialize(first_name, last_name)
- @first_name = first_name
- @last_name = last_name
- end
-
- def to_s
- "#{@first_name} #{@last_name}"
- end
- end
- ```
-
-*
- Use the `attr` family of functions to define trivial accessors or mutators.
-[[link](#attr_family)]
-
- ```Ruby
- # bad
- class Person
- def initialize(first_name, last_name)
- @first_name = first_name
- @last_name = last_name
- end
-
- def first_name
- @first_name
- end
-
- def last_name
- @last_name
- end
- end
-
- # good
- class Person
- attr_reader :first_name, :last_name
-
- def initialize(first_name, last_name)
- @first_name = first_name
- @last_name = last_name
- end
- end
- ```
-
-*
- Avoid the use of `attr`. Use `attr_reader` and `attr_accessor` instead.
-[[link](#attr)]
-
- ```Ruby
- # bad - creates a single attribute accessor (deprecated in 1.9)
- attr :something, true
- attr :one, :two, :three # behaves as attr_reader
-
- # good
- attr_accessor :something
- attr_reader :one, :two, :three
- ```
-
-*
- Consider using `Struct.new`, which defines the trivial accessors,
- constructor and comparison operators for you.
-[[link](#struct-new)]
-
- ```Ruby
- # good
- class Person
- attr_accessor :first_name, :last_name
-
- def initialize(first_name, last_name)
- @first_name = first_name
- @last_name = last_name
- end
- end
-
- # better
- Person = Struct.new(:first_name, :last_name) do
- end
- ````
-
-*
- Don't extend a `Struct.new` - it already is a new class. Extending it
- introduces a superfluous class level and may also introduce weird errors if
- the file is required multiple times.
-[[link](#no-extend-struct-new)]
-
-*
- Consider adding factory methods to provide additional sensible ways to
- create instances of a particular class.
-[[link](#factory-methods)]
-
- ```Ruby
- class Person
- def self.create(options_hash)
- # body omitted
- end
- end
- ```
-
-*
- Prefer [duck-typing](http://en.wikipedia.org/wiki/Duck_typing) over
- inheritance.
-[[link](#duck-typing)]
-
- ```Ruby
- # bad
- class Animal
- # abstract method
- def speak
- end
- end
-
- # extend superclass
- class Duck < Animal
- def speak
- puts 'Quack! Quack'
- end
- end
-
- # extend superclass
- class Dog < Animal
- def speak
- puts 'Bau! Bau!'
- end
- end
-
- # good
- class Duck
- def speak
- puts 'Quack! Quack'
- end
- end
-
- class Dog
- def speak
- puts 'Bau! Bau!'
- end
- end
- ```
-
-*
- Avoid the usage of class (`@@`) variables due to their "nasty" behavior in
- inheritance.
-[[link](#no-class-vars)]
-
- ```Ruby
- 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"
- ```
-
- As you can see all the classes in a class hierarchy actually share one
- class variable. Class instance variables should usually be preferred
- over class variables.
-
-*
- Assign proper visibility levels to methods (`private`, `protected`) in
- accordance with their intended usage. Don't go off leaving everything `public`
- (which is the default). After all we're coding in *Ruby* now, not in *Python*.
-[[link](#visibility)]
-
-*
- Indent the `public`, `protected`, and `private` methods as much the method
- definitions they apply to. Leave one blank line above the visibility modifier
- and one blank line below in order to emphasize that it applies to all methods
- below it.
-[[link](#indent-public-private-protected)]
-
- ```Ruby
- class SomeClass
- def public_method
- # ...
- end
-
- private
-
- def private_method
- # ...
- end
-
- def another_private_method
- # ...
- end
- end
- ```
-
-*
- Use `def self.method` to define singleton methods. This makes the code
- easier to refactor since the class name is not repeated.
-[[link](#def-self-singletons)]
-
- ```Ruby
- class TestClass
- # bad
- def TestClass.some_method
- # body omitted
- end
-
- # good
- def self.some_other_method
- # body omitted
- end
-
- # Also possible and convenient when you
- # have to define many singleton methods.
- class << self
- def first_method
- # body omitted
- end
-
- def second_method_etc
- # body omitted
- end
- end
- end
- ```
-
-## Exceptions
-
-*
- Signal exceptions using the `fail` method. Use `raise` only when catching an
- exception and re-raising it (because here you're not failing, but explicitly
- and purposefully raising an exception).
-[[link](#fail-method)]
-
- ```Ruby
- begin
- fail 'Oops'
- rescue => error
- raise if error.message != 'Oops'
- end
- ```
-
-*
- Don't specify `RuntimeError` explicitly in the two argument version of
- `fail/raise`.
-[[link](#no-explicit-runtimeerror)]
-
- ```Ruby
- # bad
- fail RuntimeError, 'message'
-
- # good - signals a RuntimeError by default
- fail 'message'
- ```
-
-*
- Prefer supplying an exception class and a message as two separate arguments
- to `fail/raise`, instead of an exception instance.
-[[link](#exception-class-messages)]
-
- ```Ruby
- # bad
- fail SomeException.new('message')
- # Note that there is no way to do `fail SomeException.new('message'), backtrace`.
-
- # good
- fail SomeException, 'message'
- # Consistent with `fail SomeException, 'message', backtrace`.
- ```
-
-*
- Do not return from an `ensure` block. If you explicitly return from a method
- inside an `ensure` block, the return will take precedence over any exception
- being raised, and the method will return as if no exception had been raised at
- all. In effect, the exception will be silently thrown away.
-[[link](#no-return-ensure)]
-
- ```Ruby
- def foo
- begin
- fail
- ensure
- return 'very bad idea'
- end
- end
- ```
-
-*
- Use *implicit begin blocks* where possible.
-[[link](#begin-implicit)]
-
- ```Ruby
- # bad
- def foo
- begin
- # main logic goes here
- rescue
- # failure handling goes here
- end
- end
-
- # good
- def foo
- # main logic goes here
- rescue
- # failure handling goes here
- end
- ```
-
-*
- Mitigate the proliferation of `begin` blocks by using *contingency methods*
- (a term coined by Avdi Grimm).
-[[link](#contingency-methods)]
-
- ```Ruby
- # bad
- begin
- something_that_might_fail
- rescue IOError
- # handle IOError
- end
-
- begin
- something_else_that_might_fail
- rescue IOError
- # handle IOError
- end
-
- # good
- def with_io_error_handling
- yield
- rescue IOError
- # handle IOError
- end
-
- with_io_error_handling { something_that_might_fail }
-
- with_io_error_handling { something_else_that_might_fail }
- ```
-
-*
- Don't suppress exceptions.
-[[link](#dont-hide-exceptions)]
-
- ```Ruby
- # bad
- begin
- # an exception occurs here
- rescue SomeError
- # the rescue clause does absolutely nothing
- end
-
- # bad
- do_something rescue nil
- ```
-
-*
- Avoid using `rescue` in its modifier form.
-[[link](#no-rescue-modifiers)]
-
- ```Ruby
- # bad - this catches exceptions of StandardError class and its descendant classes
- read_file rescue handle_error($!)
-
- # good - this catches only the exceptions of Errno::ENOENT class and its descendant classes
- def foo
- read_file
- rescue Errno::ENOENT => ex
- handle_error(ex)
- end
- ```
-
-*
- Don't use exceptions for flow of control.
-[[link](#no-exceptional-flows)]
-
- ```Ruby
- # 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
- ```
-
-*
- Avoid rescuing the `Exception` class. This will trap signals and calls to
- `exit`, requiring you to `kill -9` the process.
-[[link](#no-blind-rescues)]
-
- ```Ruby
- # bad
- begin
- # calls to exit and kill signals will be caught (except kill -9)
- exit
- rescue Exception
- puts "you didn't really want to exit, right?"
- # exception handling
- end
-
- # good
- begin
- # a blind rescue rescues from StandardError, not Exception as many
- # programmers assume.
- rescue => e
- # exception handling
- end
-
- # also good
- begin
- # an exception occurs here
-
- rescue StandardError => e
- # exception handling
- end
- ```
-
-*
- Put more specific exceptions higher up the rescue chain, otherwise they'll
- never be rescued from.
-[[link](#exception-ordering)]
-
- ```Ruby
- # bad
- begin
- # some code
- rescue Exception => e
- # some handling
- rescue StandardError => e
- # some handling that will never be executed
- end
-
- # good
- begin
- # some code
- rescue StandardError => e
- # some handling
- rescue Exception => e
- # some handling
- end
- ```
-
-*
- Release external resources obtained by your program in an ensure block.
-[[link](#file-close)]
-
- ```Ruby
- f = File.open('testfile')
- begin
- # .. process
- rescue
- # .. handle error
- ensure
- f.close if f
- end
- ```
-
-*
- Favor the use of exceptions for the standard library over introducing new
- exception classes.
-[[link](#standard-exceptions)]
-
-## Collections
-
-*
- Prefer literal array and hash creation notation (unless you need to pass
- parameters to their constructors, that is).
-[[link](#literal-array-hash)]
-
- ```Ruby
- # bad
- arr = Array.new
- hash = Hash.new
-
- # good
- arr = []
- hash = {}
- ```
-
-*
- Prefer `%w` to the literal array syntax when you need an array of words
- (non-empty strings without spaces and special characters in them). Apply this
- rule only to arrays with two or more elements.
-[[link](#percent-w)]
-
- ```Ruby
- # bad
- STATES = ['draft', 'open', 'closed']
-
- # good
- STATES = %w(draft open closed)
- ```
-
-*
- Prefer `%i` to the literal array syntax when you need an array of symbols
- (and you don't need to maintain Ruby 1.9 compatibility). Apply this rule only
- to arrays with two or more elements.
-[[link](#percent-i)]
-
- ```Ruby
- # bad
- STATES = [:draft, :open, :closed]
-
- # good
- STATES = %i(draft open closed)
- ```
-
-*
- Avoid comma after the last item of an `Array` or `Hash` literal, especially
- when the items are not on separate lines.
-[[link](#no-trailing-array-commas)]
-
- ```Ruby
- # bad - easier to move/add/remove items, but still not preferred
- VALUES = [
- 1001,
- 2020,
- 3333,
- ]
-
- # bad
- VALUES = [1001, 2020, 3333, ]
-
- # good
- VALUES = [1001, 2020, 3333]
- ```
-
-*
- Avoid the creation of huge gaps in arrays.
-[[link](#no-gappy-arrays)]
-
- ```Ruby
- arr = []
- arr[100] = 1 # now you have an array with lots of nils
- ```
-
-*
- When accessing the first or last element from an array, prefer `first` or
- `last` over `[0]` or `[-1]`.
-[[link](#first-and-last)]
-
-*
- Use `Set` instead of `Array` when dealing with unique elements. `Set`
- implements a collection of unordered values with no duplicates. This is a
- hybrid of `Array`'s intuitive inter-operation facilities and `Hash`'s fast
- lookup.
-[[link](#set-vs-array)]
-
-*
- Prefer symbols instead of strings as hash keys.
-[[link](#symbols-as-keys)]
-
- ```Ruby
- # bad
- hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
-
- # good
- hash = { one: 1, two: 2, three: 3 }
- ```
-
-*
- Avoid the use of mutable objects as hash keys.
-[[link](#no-mutable-keys)]
-
-*
- Use the Ruby 1.9 hash literal syntax when your hash keys are symbols.
-[[link](#hash-literals)]
-
- ```Ruby
- # bad
- hash = { :one => 1, :two => 2, :three => 3 }
-
- # good
- hash = { one: 1, two: 2, three: 3 }
- ```
-
-*
- Don't mix the Ruby 1.9 hash syntax with hash rockets in the same hash
- literal. When you've got keys that are not symbols stick to the hash rockets
- syntax.
-[[link](#no-mixed-hash-syntaces)]
-
- ```Ruby
- # bad
- { a: 1, 'b' => 2 }
-
- # good
- { :a => 1, 'b' => 2 }
- ```
-
-*
- Use `Hash#key?` instead of `Hash#has_key?` and `Hash#value?` instead of
- `Hash#has_value?`. As noted
- [here](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/43765) by
- Matz, the longer forms are considered deprecated.
-[[link](#hash-key)]
-
- ```Ruby
- # bad
- hash.has_key?(:test)
- hash.has_value?(value)
-
- # good
- hash.key?(:test)
- hash.value?(value)
- ```
-
-*
- Use `Hash#fetch` when dealing with hash keys that should be present.
-[[link](#hash-fetch)]
-
- ```Ruby
- heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
- # bad - if we make a mistake we might not spot it right away
- heroes[:batman] # => "Bruce Wayne"
- heroes[:supermann] # => nil
-
- # good - fetch raises a KeyError making the problem obvious
- heroes.fetch(:supermann)
- ```
-
-*
- Introduce default values for hash keys via `Hash#fetch` as opposed to using
- custom logic.
-[[link](#hash-fetch-defaults)]
-
- ```Ruby
- batman = { name: 'Bruce Wayne', is_evil: false }
-
- # bad - if we just use || operator with falsy value we won't get the expected result
- batman[:is_evil] || true # => true
-
- # good - fetch work correctly with falsy values
- batman.fetch(:is_evil, true) # => false
- ```
-
-*
- Prefer the use of the block instead of the default value in `Hash#fetch`.
-[[link](#use-hash-blocks)]
-
- ```Ruby
- batman = { name: 'Bruce Wayne' }
-
- # bad - if we use the default value, we eager evaluate it
- # so it can slow the program down if done multiple times
- batman.fetch(:powers, get_batman_powers) # get_batman_powers is an expensive call
-
- # good - blocks are lazy evaluated, so only triggered in case of KeyError exception
- batman.fetch(:powers) { get_batman_powers }
- ```
-
-*
- Use `Hash#values_at` when you need to retrieve several values consecutively
- from a hash.
-[[link](#hash-values-at)]
-
- ```Ruby
- # bad
- email = data['email']
- nickname = data['nickname']
-
- # good
- email, username = data.values_at('email', 'nickname')
- ```
-
-*
- Rely on the fact that as of Ruby 1.9 hashes are ordered.
-[[link](#ordered-hashes)]
-
-*
- Do not modify a collection while traversing it.
-[[link](#no-modifying-collections)]
-
-## Strings
-
-*
- Prefer string interpolation and string formatting instead of string
- concatenation:
-[[link](#string-interpolation)]
-
- ```Ruby
- # bad
- email_with_name = user.name + ' <' + user.email + '>'
-
- # good
- email_with_name = "#{user.name} <#{user.email}>"
-
- # good
- email_with_name = format('%s <%s>', user.name, user.email)
- ```
-
-*
- Consider padding string interpolation code with space. It more clearly sets
- the code apart from the string.
-[[link](#pad-string-interpolation)]
-
- ```Ruby
- "#{ user.last_name }, #{ user.first_name }"
- ```
-
-*
- Adopt a consistent string literal quoting style. There are two popular
- styles in the Ruby community, both of which are considered good - single
- quotes by default (Option A) and double quotes by default (Option B).
-[[link](#consistent-string-literals)]
-
- * **(Option A)** Prefer single-quoted strings when you don't need
- string interpolation or special symbols such as `\t`, `\n`, `'`,
- etc.
-
- ```Ruby
- # bad
- name = "Bozhidar"
-
- # good
- name = 'Bozhidar'
- ```
-
- * **(Option B)** Prefer double-quotes unless your string literal
- contains `"` or escape characters you want to suppress.
-
- ```Ruby
- # bad
- name = 'Bozhidar'
-
- # good
- name = "Bozhidar"
- ```
-
- The second style is arguably a bit more popular in the Ruby
- community. The string literals in this guide, however, are
- aligned with the first style.
-
-*
- Don't use the character literal syntax `?x`. Since Ruby 1.9 it's basically
- redundant - `?x` would interpreted as `'x'` (a string with a single character
- in it).
-[[link](#no-character-literals)]
-
- ```Ruby
- # bad
- char = ?c
-
- # good
- char = 'c'
- ```
-
-*
- Don't leave out `{}` around instance and global variables being interpolated
- into a string.
-[[link](#curlies-interpolate)]
-
- ```Ruby
- class Person
- attr_reader :first_name, :last_name
-
- def initialize(first_name, last_name)
- @first_name = first_name
- @last_name = last_name
- end
-
- # bad - valid, but awkward
- def to_s
- "#@first_name #@last_name"
- end
-
- # good
- def to_s
- "#{@first_name} #{@last_name}"
- end
- end
-
- $global = 0
- # bad
- puts "$global = #$global"
-
- # good
- puts "$global = #{$global}"
- ```
-
-*
- Don't use `Object#to_s` on interpolated objects. It's invoked on them
- automatically.
-[[link](#no-to-s)]
-
- ```Ruby
- # bad
- message = "This is the #{result.to_s}."
-
- # good
- message = "This is the #{result}."
- ```
-
-*
- Avoid using `String#+` when you need to construct large data chunks.
- Instead, use `String#<<`. Concatenation mutates the string instance in-place
- and is always faster than `String#+`, which creates a bunch of new string
- objects.
-[[link](#concat-strings)]
-
- ```Ruby
- # good and also fast
- html = ''
- html << 'Page title
'
-
- paragraphs.each do |paragraph|
- html << "#{paragraph}
"
- end
- ```
-
-*
- When using heredocs for multi-line strings keep in mind the fact that they
- preserve leading whitespace. It's a good practice to employ some margin based
- on which to trim the excessive whitespace.
-[[link](#heredocs)]
-
- ```Ruby
- code = <<-END.gsub(/^\s+\|/, '')
- |def test
- | some_method
- | other_method
- |end
- END
- # => "def test\n some_method\n other_method\nend\n"
- ```
-
-## Regular Expressions
-
-> Some people, when confronted with a problem, think
-> "I know, I'll use regular expressions." Now they have two problems.
-> -- Jamie Zawinski
-
-*
- Don't use regular expressions if you just need plain text search in string:
- `string['text']`
-[[link](#no-regexp-for-plaintext)]
-
-*
- For simple constructions you can use regexp directly through string index.
-[[link](#regexp-string-index)]
-
- ```Ruby
- match = string[/regexp/] # get content of matched regexp
- first_group = string[/text(grp)/, 1] # get content of captured group
- string[/text (grp)/, 1] = 'replace' # string => 'text replace'
- ```
-
-*
- Use non-capturing groups when you don't use captured result of parentheses.
-[[link](#non-capturing-regexp)]
-
- ```Ruby
- /(first|second)/ # bad
- /(?:first|second)/ # good
- ```
-
-*
- Don't use the cryptic Perl-legacy variables denoting last regexp group
- matches (`$1`, `$2`, etc). Use `Regexp.last_match[n]` instead.
-[[link](#no-perl-regexp-last-matchers)]
-
- ```Ruby
- /(regexp)/ =~ string
- ...
-
- # bad
- process $1
-
- # good
- process Regexp.last_match[1]
- ```
-
-*
- Avoid using numbered groups as it can be hard to track what they contain.
- Named groups can be used instead.
-[[link](#no-numbered-regexes)]
-
- ```Ruby
- # bad
- /(regexp)/ =~ string
- ...
- process Regexp.last_match[1]
-
- # good
- /(?regexp)/ =~ string
- ...
- process meaningful_var
- ```
-
-*
- Character classes have only a few special characters you should care about:
- `^`, `-`, `\`, `]`, so don't escape `.` or brackets in `[]`.
-[[link](#limit-escapes)]
-
-*
- Be careful with `^` and `$` as they match start/end of line, not string
- endings. If you want to match the whole string use: `\A` and `\z` (not to be
- confused with `\Z` which is the equivalent of `/\n?\z/`).
-[[link](#caret-and-dollar-regexp)]
-
- ```Ruby
- string = "some injection\nusername"
- string[/^username$/] # matches
- string[/\Ausername\z/] # doesn't match
- ```
-
-*
- Use `x` modifier for complex regexps. This makes them more readable and you
- can add some useful comments. Just be careful as spaces are ignored.
-[[link](#comment-regexes)]
-
- ```Ruby
- regexp = /
- start # some text
- \s # white space char
- (group) # first group
- (?:alt1|alt2) # some alternation
- end
- /x
- ```
-
-*
- For complex replacements `sub`/`gsub` can be used with block or hash.
-[[link](#gsub-blocks)]
-
-## Percent Literals
-
-*
- Use `%()`(it's a shorthand for `%Q`) for single-line strings which require
- both interpolation and embedded double-quotes. For multi-line strings, prefer
- heredocs.
-[[link](#percent-q-shorthand)]
-
- ```Ruby
- # bad (no interpolation needed)
- %(Some text
)
- # should be 'Some text
'
-
- # bad (no double-quotes)
- %(This is #{quality} style)
- # should be "This is #{quality} style"
-
- # bad (multiple lines)
- %(\n#{exclamation}\n
)
- # should be a heredoc.
-
- # good (requires interpolation, has quotes, single line)
- %(#{name} | )
- ```
-
-*
- Avoid `%q` unless you have a string with both `'` and `"` in it. Regular
- string literals are more readable and should be preferred unless a lot of
- characters would have to be escaped in them.
-[[link](#percent-q)]
-
- ```Ruby
- # bad
- name = %q(Bruce Wayne)
- time = %q(8 o'clock)
- question = %q("What did you say?")
-
- # good
- name = 'Bruce Wayne'
- time = "8 o'clock"
- question = '"What did you say?"'
- ```
-
-*
- Use `%r` only for regular expressions matching *more than* one '/'
- character.
-[[link](#percent-r)]
-
- ```Ruby
- # bad
- %r(\s+)
-
- # still bad
- %r(^/(.*)$)
- # should be /^\/(.*)$/
-
- # good
- %r(^/blog/2011/(.*)$)
- ```
-
-*
- Avoid the use of `%x` unless you're going to invoke a command with
- backquotes in it(which is rather unlikely).
-[[link](#percent-x)]
-
- ```Ruby
- # bad
- date = %x(date)
-
- # good
- date = `date`
- echo = %x(echo `date`)
- ```
-
-*
- Avoid the use of `%s`. It seems that the community has decided `:"some
- string"` is the preferred way to create a symbol with spaces in it.
-[[link](#percent-s)]
-
-*
- Prefer `()` as delimiters for all `%` literals, except `%r`. Since parentheses
- often appear inside regular expressions in many scenarios a less common
- character like `{` might be a better choice for a delimiter, depending on the
- regexp's content.
-[[link](#percent-literal-braces)]
-
- ```Ruby
- # bad
- %w[one two three]
- %q{"Test's king!", John said.}
-
- # good
- %w(one two three)
- %q("Test's king!", John said.)
- ```
-
-## Metaprogramming
-
-*
- Avoid needless metaprogramming.
-[[link](#no-metaprogramming-masturbation)]
-
-*
- Do not mess around in core classes when writing libraries. (Do not
- monkey-patch them.)
-[[link](#no-monkey-patching)]
-
-*
- The block form of `class_eval` is preferable to the string-interpolated
- form. - when you use the string-interpolated form, always supply `__FILE__`
- and `__LINE__`, so that your backtraces make sense:
-[[link](#block-class-eval)]
-
- ```ruby
- class_eval 'def use_relative_model_naming?; true; end', __FILE__, __LINE__
- ```
-
- - `define_method` is preferable to `class_eval{ def ... }`
-
-*
- When using `class_eval` (or other `eval`) with string interpolation, add a
- comment block showing its appearance if interpolated (a practice used in Rails
- code):
-[[link](#eval-comment-docs)]
-
- ```ruby
- # from activesupport/lib/active_support/core_ext/string/output_safety.rb
- UNSAFE_STRING_METHODS.each do |unsafe_method|
- if 'String'.respond_to?(unsafe_method)
- class_eval <<-EOT, __FILE__, __LINE__ + 1
- def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
- to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
- end # end
-
- def #{unsafe_method}!(*args) # def capitalize!(*args)
- @dirty = true # @dirty = true
- super # super
- end # end
- EOT
- end
- end
- ```
-
-*
- Avoid using `method_missing` for metaprogramming because backtraces become
- messy, the behavior is not listed in `#methods`, and misspelled method calls
- might silently work, e.g. `nukes.launch_state = false`. Consider using
- delegation, proxy, or `define_method` instead. If you must use
- `method_missing`:
-[[link](#no-method-missing)]
-
- - Be sure to [also define `respond_to_missing?`](http://blog.marc-andre.ca/2010/11/methodmissing-politely.html)
- - Only catch methods with a well-defined prefix, such as `find_by_*` -- make your code as assertive as possible.
- - Call `super` at the end of your statement
- - Delegate to assertive, non-magical methods:
-
- ```ruby
- # bad
- def method_missing?(meth, *args, &block)
- if /^find_by_(?.*)/ =~ meth
- # ... lots of code to do a find_by
- else
- super
- end
- end
-
- # good
- def method_missing?(meth, *args, &block)
- if /^find_by_(?.*)/ =~ meth
- find_by(prop, *args, &block)
- else
- super
- end
- end
-
- # best of all, though, would to define_method as each findable attribute is declared
- ```
-
-*
- Prefer `public_send` over `send` so as not to circumvent `private`/`protected` visibility.
-[[link](#prefer-public-send)]
-
-## Misc
-
-*
- Write `ruby -w` safe code.
-[[link](#always-warn)]
-
-*
- Avoid hashes as optional parameters. Does the method do too much? (Object
- initializers are exceptions for this rule).
-[[link](#no-optional-hash-params)]
-
-*
- Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will
- be shorter than 5 LOC. Empty lines do not contribute to the relevant LOC.
-[[link](#short-methods)]
-
-*
- Avoid parameter lists longer than three or four parameters.
-[[link](#too-many-params)]
-
-*
- If you really need "global" methods, add them to Kernel and make them
- private.
-[[link](#private-global-methods)]
-
-*
- Use module instance variables instead of global variables.
-[[link](#instance-vars)]
-
- ```Ruby
- # bad
- $foo_bar = 1
-
- # good
- module Foo
- class << self
- attr_accessor :bar
- end
- end
-
- Foo.bar = 1
- ```
-
-*
- Avoid `alias` when `alias_method` will do.
-[[link](#alias-method)]
-
-*
- Use `OptionParser` for parsing complex command line options and `ruby -s`
- for trivial command line options.
-[[link](#optionparser)]
-
-*
- Prefer `Time.now` over `Time.new` when retrieving the current system time.
-[[link](#time-now)]
-
-*
- Code in a functional way, avoiding mutation when that makes sense.
-[[link](#functional-code)]
-
-*
- Do not mutate arguments unless that is the purpose of the method.
-[[link](#no-arg-mutations)]
-
-*
- Avoid more than three levels of block nesting.
-[[link](#three-is-the-number-thou-shalt-count)]
-
-*
- Be consistent. In an ideal world, be consistent with these guidelines.
-[[link](#be-consistent)]
-
-*
- Use common sense.
-[[link](#common-sense)]
-
-## Tools
-
-Here's some tools to help you automatically check Ruby code against
-this guide.
-
-### RuboCop
-
-[RuboCop][] is a Ruby code style
-checker based on this style guide. RuboCop already covers a
-significant portion of the Guide, supports both MRI 1.9 and MRI 2.0
-and has good Emacs integration.
-
-### RubyMine
-
-[RubyMine](http://www.jetbrains.com/ruby/)'s code inspections are
-[partially based](http://confluence.jetbrains.com/display/RUBYDEV/RubyMine+Inspections)
-on this guide.
-
-# Contributing
-
-The guide is still a work in progress - some rules are lacking examples, some
-rules don't have examples that illustrate them clearly enough. Improving such rules
-is a great (and simple way) to help the Ruby community!
-
-In due time these issues will (hopefully) be addressed - just keep them in mind
-for now.
-
-Nothing written in this guide is set in stone. It's my desire to work
-together with everyone interested in Ruby coding style, so that we could
-ultimately create a resource that will be beneficial to the entire Ruby
-community.
-
-Feel free to open tickets or send pull requests with improvements. Thanks in
-advance for your help!
-
-You can also support the project (and RuboCop) with financial
-contributions via [gittip](https://www.gittip.com/bbatsov).
-
-[](https://www.gittip.com/bbatsov)
-
-## How to Contribute?
-
-It's easy, just follow the [contribution guidelines](https://github.com/bbatsov/ruby-style-guide/blob/master/CONTRIBUTING.md).
-
-# License
-
-
-This work is licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US)
-
-# Spread the Word
-
-A community-driven style guide is of little use to a community that
-doesn't know about its existence. Tweet about the guide, share it with
-your friends and colleagues. Every comment, suggestion or opinion we
-get makes the guide just a little bit better. And we want to have the
-best possible guide, don't we?
-
-Cheers,
-[Bozhidar](https://twitter.com/bbatsov)
-
-[PEP-8]: http://www.python.org/dev/peps/pep-0008/
-[rails-style-guide]: https://github.com/bbatsov/rails-style-guide
-[pickaxe]: http://pragprog.com/book/ruby4/programming-ruby-1-9-2-0
-[trpl]: http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177
-[transmuter]: https://github.com/TechnoGate/transmuter
-[RuboCop]: https://github.com/bbatsov/rubocop
+[russian]: https://github.com/arbox/ruby-style-guide/blob/master/README-ruRU.md
+[english]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md
+[bbatsov]: https://github.com/bbatsov
diff --git a/glossary.md b/glossary.md
new file mode 100644
index 000000000..e8246824b
--- /dev/null
+++ b/glossary.md
@@ -0,0 +1,3 @@
+# Glossary
+
+* "body ommited" - "некоторый код"