rubocop-github 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +31 -32
- data/STYLEGUIDE.md +208 -90
- data/config/default.yml +1657 -2
- data/config/default_cops.yml +3 -0
- data/config/rails.yml +414 -2
- data/config/{_rails_shared.yml → rails_cops.yml} +10 -68
- data/lib/rubocop/cop/github/insecure_hash_algorithm.rb +1 -1
- data/lib/rubocop/cop/github/rails_application_record.rb +2 -2
- data/lib/rubocop/cop/github/rails_controller_render_action_symbol.rb +11 -5
- data/lib/rubocop/cop/github/rails_controller_render_literal.rb +7 -7
- data/lib/rubocop/cop/github/rails_controller_render_paths_exist.rb +4 -4
- data/lib/rubocop/cop/github/rails_controller_render_shorthand.rb +4 -11
- data/lib/rubocop/cop/github/rails_render_inline.rb +2 -2
- data/lib/rubocop/cop/github/rails_render_object_collection.rb +3 -3
- data/lib/rubocop/cop/github/rails_view_render_literal.rb +6 -6
- data/lib/rubocop/cop/github/rails_view_render_paths_exist.rb +3 -3
- data/lib/rubocop/cop/github/rails_view_render_shorthand.rb +3 -3
- data/lib/rubocop/cop/github.rb +2 -11
- data/lib/rubocop/github/inject.rb +27 -0
- data/lib/rubocop/github.rb +9 -0
- data/lib/rubocop-github-rails.rb +18 -0
- data/lib/rubocop-github.rb +9 -0
- metadata +15 -15
- data/config/_default_shared.yml +0 -329
- data/config/default_deprecated.yml +0 -4
- data/config/default_edge.yml +0 -4
- data/config/rails_deprecated.yml +0 -7
- data/config/rails_edge.yml +0 -4
data/STYLEGUIDE.md
CHANGED
@@ -1,37 +1,42 @@
|
|
1
1
|
# Ruby Style Guide
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
[
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
[
|
26
|
-
|
27
|
-
|
28
|
-
|
3
|
+
This is GitHub's Ruby Style Guide, inspired by [RuboCop's guide][rubocop-guide].
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
1. [Layout](#layout)
|
7
|
+
1. [Indentation](#indentation)
|
8
|
+
2. [Inline](#inline)
|
9
|
+
3. [Newlines](#newlines)
|
10
|
+
2. [Maximum Line Length](#line-length)
|
11
|
+
3. [Classes](#classes)
|
12
|
+
4. [Collections](#collections)
|
13
|
+
5. [Documentation](#documentation)
|
14
|
+
6. [Dynamic Dispatch](#dynamic-dispatch)
|
15
|
+
7. [Exceptions](#exceptions)
|
16
|
+
8. [Hashes](#hashes)
|
17
|
+
9. [Keyword Arguments](#keyword-arguments)
|
18
|
+
10. [Naming](#naming)
|
19
|
+
11. [Percent Literals](#percent-literals)
|
20
|
+
12. [Regular Expressions](#regular-expressions)
|
21
|
+
13. [Requires](#requires)
|
22
|
+
14. [Strings](#strings)
|
23
|
+
15. [Methods](#methods)
|
24
|
+
1. [Method definitions](#method-definitions)
|
25
|
+
2. [Method calls](#method-calls)
|
26
|
+
16. [Conditional Expressions](#conditional-expressions)
|
27
|
+
1. [Conditional keywords](#conditional-keywords)
|
28
|
+
2. [Ternary operator](#ternary-operator)
|
29
|
+
17. [Syntax](#syntax)
|
30
|
+
|
31
|
+
## Layout
|
32
|
+
|
33
|
+
### Indentation
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
```
|
35
|
+
* Use soft-tabs with a two space indent.
|
36
|
+
<a name="default-indentation"></a><sup>[[link](#default-indentation)]</sup>
|
33
37
|
|
34
38
|
* Indent `when` with the start of the `case` expression.
|
39
|
+
<a name="indent-when-as-start-of-case"></a><sup>[[link](#indent-when-as-start-of-case)]</sup>
|
35
40
|
|
36
41
|
``` ruby
|
37
42
|
# bad
|
@@ -71,8 +76,45 @@ else
|
|
71
76
|
end
|
72
77
|
```
|
73
78
|
|
79
|
+
### Inline
|
80
|
+
|
81
|
+
* Never leave trailing whitespace.
|
82
|
+
<a name="trailing-whitespace"></a><sup>[[link](#trailing-whitespace)]</sup>
|
83
|
+
|
84
|
+
* Use spaces around operators, after commas, colons and semicolons, around `{`
|
85
|
+
and before `}`.
|
86
|
+
<a name="spaces-operators"></a><sup>[[link](#spaces-operators)]</sup>
|
87
|
+
|
88
|
+
``` ruby
|
89
|
+
sum = 1 + 2
|
90
|
+
a, b = 1, 2
|
91
|
+
1 > 2 ? true : false; puts "Hi"
|
92
|
+
[1, 2, 3].each { |e| puts e }
|
93
|
+
```
|
94
|
+
|
95
|
+
* No spaces after `(`, `[` or before `]`, `)`.
|
96
|
+
<a name="no-spaces-braces"></a><sup>[[link](#no-spaces-braces)]</sup>
|
97
|
+
|
98
|
+
``` ruby
|
99
|
+
some(arg).other
|
100
|
+
[1, 2, 3].length
|
101
|
+
```
|
102
|
+
|
103
|
+
* No spaces after `!`.
|
104
|
+
<a name="no-spaces-bang"></a><sup>[[link](#no-spaces-bang)]</sup>
|
105
|
+
|
106
|
+
``` ruby
|
107
|
+
!array.include?(element)
|
108
|
+
```
|
109
|
+
|
110
|
+
### Newlines
|
111
|
+
|
112
|
+
* End each file with a [newline](https://github.com/bbatsov/ruby-style-guide#newline-eof).
|
113
|
+
<a name="newline-eof"></a><sup>[[link](#newline-eof)]</sup>
|
114
|
+
|
74
115
|
* Use empty lines between `def`s and to break up a method into logical
|
75
116
|
paragraphs.
|
117
|
+
<a name="empty-lines-def"></a><sup>[[link](#empty-lines-def)]</sup>
|
76
118
|
|
77
119
|
``` ruby
|
78
120
|
def some_method
|
@@ -88,10 +130,16 @@ def some_method
|
|
88
130
|
end
|
89
131
|
```
|
90
132
|
|
133
|
+
## Maximum Line Length
|
134
|
+
|
135
|
+
* Keep each line of code to a readable length. Unless you have a reason to, keep lines to a maximum of 118 characters. Why 118? That's the width at which the pull request diff UI needs horizontal scrolling (making pull requests harder to review).
|
136
|
+
<a name="line-length"></a><sup>[[link](#line-length)]</sup>
|
137
|
+
|
91
138
|
## Classes
|
92
139
|
|
93
140
|
* Avoid the usage of class (`@@`) variables due to their unusual behavior
|
94
141
|
in inheritance.
|
142
|
+
<a name="class-variables"></a><sup>[[link](#class-variables)]</sup>
|
95
143
|
|
96
144
|
``` ruby
|
97
145
|
class Parent
|
@@ -115,6 +163,7 @@ Parent.print_class_var # => will print "child"
|
|
115
163
|
|
116
164
|
* Use `def self.method` to define singleton methods. This makes the methods
|
117
165
|
more resistant to refactoring changes.
|
166
|
+
<a name="singleton-methods"></a><sup>[[link](#singleton-methods)]</sup>
|
118
167
|
|
119
168
|
``` ruby
|
120
169
|
class TestClass
|
@@ -131,6 +180,7 @@ class TestClass
|
|
131
180
|
|
132
181
|
* Avoid `class << self` except when necessary, e.g. single accessors and aliased
|
133
182
|
attributes.
|
183
|
+
<a name="class-method-definitions"></a><sup>[[link](#class-method-definitions)]</sup>
|
134
184
|
|
135
185
|
``` ruby
|
136
186
|
class TestClass
|
@@ -163,6 +213,7 @@ end
|
|
163
213
|
|
164
214
|
* Indent the `public`, `protected`, and `private` methods as much the
|
165
215
|
method definitions they apply to. Leave one blank line above them.
|
216
|
+
<a name="access-modifier-identation"></a><sup>[[link](#access-modifier-identation)]</sup>
|
166
217
|
|
167
218
|
``` ruby
|
168
219
|
class SomeClass
|
@@ -179,6 +230,7 @@ end
|
|
179
230
|
|
180
231
|
* Avoid explicit use of `self` as the recipient of internal class or instance
|
181
232
|
messages unless to specify a method shadowed by a variable.
|
233
|
+
<a name="self-messages"></a><sup>[[link](#self-messages)]</sup>
|
182
234
|
|
183
235
|
``` ruby
|
184
236
|
class SomeClass
|
@@ -195,6 +247,7 @@ end
|
|
195
247
|
|
196
248
|
* Prefer `%w` to the literal array syntax when you need an array of
|
197
249
|
strings.
|
250
|
+
<a name="percent-w"></a><sup>[[link](#percent-w)]</sup>
|
198
251
|
|
199
252
|
``` ruby
|
200
253
|
# bad
|
@@ -208,8 +261,10 @@ STATES = %w(draft open closed)
|
|
208
261
|
implements a collection of unordered values with no duplicates. This
|
209
262
|
is a hybrid of `Array`'s intuitive inter-operation facilities and
|
210
263
|
`Hash`'s fast lookup.
|
264
|
+
<a name="prefer-set"></a><sup>[[link](#prefer-set)]</sup>
|
211
265
|
|
212
266
|
* Use symbols instead of strings as hash keys.
|
267
|
+
<a name="symbols-as-keys"></a><sup>[[link](#symbols-as-keys)]</sup>
|
213
268
|
|
214
269
|
``` ruby
|
215
270
|
# bad
|
@@ -222,6 +277,7 @@ hash = { one: 1, two: 2, three: 3 }
|
|
222
277
|
## Documentation
|
223
278
|
|
224
279
|
Use [TomDoc](http://tomdoc.org) to the best of your ability. It's pretty sweet:
|
280
|
+
<a name="tomdoc"></a><sup>[[link](#tomdoc)]</sup>
|
225
281
|
|
226
282
|
``` ruby
|
227
283
|
# Public: Duplicate some text an arbitrary number of times.
|
@@ -243,6 +299,7 @@ end
|
|
243
299
|
## Dynamic Dispatch
|
244
300
|
|
245
301
|
Avoid calling `send` and its cousins unless you really need it. Metaprogramming can be extremely powerful, but in most cases you can write code that captures your meaning by being explicit:
|
302
|
+
<a name="avoid-send"></a><sup>[[link](#avoid-send)]</sup>
|
246
303
|
|
247
304
|
``` ruby
|
248
305
|
# avoid
|
@@ -268,6 +325,7 @@ end
|
|
268
325
|
## Exceptions
|
269
326
|
|
270
327
|
* Don't use exceptions for flow of control.
|
328
|
+
<a name="exceptions-flow-control"></a><sup>[[link](#exceptions-flow-control)]</sup>
|
271
329
|
|
272
330
|
``` ruby
|
273
331
|
# bad
|
@@ -286,6 +344,7 @@ end
|
|
286
344
|
```
|
287
345
|
|
288
346
|
* Rescue specific exceptions, not `StandardError` or its superclasses.
|
347
|
+
<a name="specific-exceptions"></a><sup>[[link](#specific-exceptions)]</sup>
|
289
348
|
|
290
349
|
``` ruby
|
291
350
|
# bad
|
@@ -306,6 +365,7 @@ end
|
|
306
365
|
## Hashes
|
307
366
|
|
308
367
|
Use the Ruby 1.9 syntax for hash literals when all the keys are symbols:
|
368
|
+
<a name="symbols-as-hash-keys"></a><sup>[[link](#symbols-as-hash-keys)]</sup>
|
309
369
|
|
310
370
|
``` ruby
|
311
371
|
# bad
|
@@ -322,6 +382,7 @@ user = {
|
|
322
382
|
```
|
323
383
|
|
324
384
|
Use the 1.9 syntax when calling a method with Hash options arguments or named arguments:
|
385
|
+
<a name="symbols-as-hash-method-arguments"></a><sup>[[link](#symbols-as-hash-method-arguments)]</sup>
|
325
386
|
|
326
387
|
``` ruby
|
327
388
|
# bad
|
@@ -334,6 +395,9 @@ link_to("Account", controller: "users", action: "show", id: user)
|
|
334
395
|
```
|
335
396
|
|
336
397
|
If you have a hash with mixed key types, use the legacy hashrocket style to avoid mixing styles within the same hash:
|
398
|
+
<a name="consistent-hash-syntax"></a><sup>[[link](#consistent-hash-syntax)]</sup>
|
399
|
+
|
400
|
+
``` ruby
|
337
401
|
|
338
402
|
``` ruby
|
339
403
|
# bad
|
@@ -352,8 +416,10 @@ hsh = {
|
|
352
416
|
## Keyword Arguments
|
353
417
|
|
354
418
|
[Keyword arguments](http://magazine.rubyist.net/?Ruby200SpecialEn-kwarg) are recommended but not required when a method's arguments may otherwise be opaque or non-obvious when called. Additionally, prefer them over the old "Hash as pseudo-named args" style from pre-2.0 ruby.
|
419
|
+
<a name="keyword-arguments"></a><sup>[[link](#keyword-arguments)]</sup>
|
355
420
|
|
356
421
|
So instead of this:
|
422
|
+
|
357
423
|
``` ruby
|
358
424
|
def remove_member(user, skip_membership_check=false)
|
359
425
|
# ...
|
@@ -363,7 +429,8 @@ end
|
|
363
429
|
remove_member(user, true)
|
364
430
|
```
|
365
431
|
|
366
|
-
Do this, which is much clearer
|
432
|
+
Do this, which is much clearer:
|
433
|
+
|
367
434
|
``` ruby
|
368
435
|
def remove_member(user, skip_membership_check: false)
|
369
436
|
# ...
|
@@ -376,22 +443,29 @@ remove_member(user, skip_membership_check: true)
|
|
376
443
|
## Naming
|
377
444
|
|
378
445
|
* Use `snake_case` for methods and variables.
|
446
|
+
<a name="snake-case-methods-vars"></a><sup>[[link](#snake-case-methods-vars)]</sup>
|
379
447
|
|
380
448
|
* Use `CamelCase` for classes and modules. (Keep acronyms like HTTP,
|
381
449
|
RFC, XML uppercase.)
|
450
|
+
<a name="camelcase-classes-modules"></a><sup>[[link](#camelcase-classes-modules)]</sup>
|
382
451
|
|
383
452
|
* Use `SCREAMING_SNAKE_CASE` for other constants.
|
453
|
+
<a name="screaming-snake-case-constants"></a><sup>[[link](#screaming-snake-case-constants)]</sup>
|
384
454
|
|
385
455
|
* The names of predicate methods (methods that return a boolean value)
|
386
456
|
should end in a question mark. (i.e. `Array#empty?`).
|
457
|
+
<a name="bool-methods-qmark"></a><sup>[[link](#bool-methods-qmark)]</sup>
|
387
458
|
|
388
459
|
* The names of potentially "dangerous" methods (i.e. methods that modify `self` or the
|
389
460
|
arguments, `exit!`, etc.) should end with an exclamation mark. Bang methods
|
390
|
-
should only exist if a non-bang method
|
461
|
+
should only exist if a non-bang counterpart (method name which does NOT end with !)
|
462
|
+
also exists.
|
463
|
+
<a name="dangerous-method-bang"></a><sup>[[link](#dangerous-method-bang)]</sup>
|
391
464
|
|
392
465
|
## Percent Literals
|
393
466
|
|
394
467
|
* Use `%w` freely.
|
468
|
+
<a name="use-percent-w-freely"></a><sup>[[link](#use-percent-w-freely)]</sup>
|
395
469
|
|
396
470
|
``` ruby
|
397
471
|
STATES = %w(draft open closed)
|
@@ -399,6 +473,7 @@ STATES = %w(draft open closed)
|
|
399
473
|
|
400
474
|
* Use `%()` for single-line strings which require both interpolation
|
401
475
|
and embedded double-quotes. For multi-line strings, prefer heredocs.
|
476
|
+
<a name="percent-parens-single-line"></a><sup>[[link](#percent-parens-single-line)]</sup>
|
402
477
|
|
403
478
|
``` ruby
|
404
479
|
# bad (no interpolation needed)
|
@@ -418,6 +493,7 @@ STATES = %w(draft open closed)
|
|
418
493
|
```
|
419
494
|
|
420
495
|
* Use `%r` only for regular expressions matching *more than* one '/' character.
|
496
|
+
<a name="percent-r-regular-expressions"></a><sup>[[link](#percent-r-regular-expressions)]</sup>
|
421
497
|
|
422
498
|
``` ruby
|
423
499
|
# bad
|
@@ -435,6 +511,7 @@ STATES = %w(draft open closed)
|
|
435
511
|
|
436
512
|
* Avoid using $1-9 as it can be hard to track what they contain. Named groups
|
437
513
|
can be used instead.
|
514
|
+
<a name="capture-with-named-groups"></a><sup>[[link](#capture-with-named-groups)]</sup>
|
438
515
|
|
439
516
|
``` ruby
|
440
517
|
# bad
|
@@ -450,6 +527,7 @@ process meaningful_var
|
|
450
527
|
|
451
528
|
* Be careful with `^` and `$` as they match start/end of line, not string endings.
|
452
529
|
If you want to match the whole string use: `\A` and `\z`.
|
530
|
+
<a name="regex-begin-end-markers"></a><sup>[[link](#regex-begin-end-markers)]</sup>
|
453
531
|
|
454
532
|
``` ruby
|
455
533
|
string = "some injection\nusername"
|
@@ -459,6 +537,7 @@ string[/\Ausername\z/] # don't match
|
|
459
537
|
|
460
538
|
* Use `x` modifier for complex regexps. This makes them more readable and you
|
461
539
|
can add some useful comments. Just be careful as spaces are ignored.
|
540
|
+
<a name="x-modifier-complex-regex"></a><sup>[[link](#x-modifier-complex-regex)]</sup>
|
462
541
|
|
463
542
|
``` ruby
|
464
543
|
regexp = %r{
|
@@ -475,6 +554,7 @@ regexp = %r{
|
|
475
554
|
Always `require` dependencies used directly in a script at the start of the same file.
|
476
555
|
Resources that will get autoloaded on first use—such as Rails models, controllers, or
|
477
556
|
helpers—don't need to be required.
|
557
|
+
<a name="require-dependencies-directly"></a><sup>[[link](#require-dependencies-directly)]</sup>
|
478
558
|
|
479
559
|
``` ruby
|
480
560
|
require "set"
|
@@ -490,6 +570,7 @@ documentation about the libraries that the current file uses.
|
|
490
570
|
## Strings
|
491
571
|
|
492
572
|
* Prefer string interpolation instead of string concatenation:
|
573
|
+
<a name="string-interpolation"></a><sup>[[link](#string-interpolation)]</sup>
|
493
574
|
|
494
575
|
``` ruby
|
495
576
|
# bad
|
@@ -502,6 +583,7 @@ email_with_name = "#{user.name} <#{user.email}>"
|
|
502
583
|
* Use double-quoted strings. Interpolation and escaped characters
|
503
584
|
will always work without a delimiter change, and `'` is a lot more
|
504
585
|
common than `"` in string literals.
|
586
|
+
<a name="double-quotes"></a><sup>[[link](#double-quotes)]</sup>
|
505
587
|
|
506
588
|
``` ruby
|
507
589
|
# bad
|
@@ -514,6 +596,7 @@ name = "Bozhidar"
|
|
514
596
|
* Avoid using `String#+` when you need to construct large data chunks.
|
515
597
|
Instead, use `String#<<`. Concatenation mutates the string instance in-place
|
516
598
|
and is always faster than `String#+`, which creates a bunch of new string objects.
|
599
|
+
<a name="string-concatenation"></a><sup>[[link](#string-concatenation)]</sup>
|
517
600
|
|
518
601
|
``` ruby
|
519
602
|
# good and also fast
|
@@ -525,10 +608,13 @@ paragraphs.each do |paragraph|
|
|
525
608
|
end
|
526
609
|
```
|
527
610
|
|
528
|
-
##
|
611
|
+
## Methods
|
612
|
+
|
613
|
+
### Method definitions
|
529
614
|
|
530
615
|
* Use `def` with parentheses when there are arguments. Omit the
|
531
616
|
parentheses when the method doesn't accept any arguments.
|
617
|
+
<a name="method-parens-when-arguments"></a><sup>[[link](#method-parens-when-arguments)]</sup>
|
532
618
|
|
533
619
|
``` ruby
|
534
620
|
def some_method
|
@@ -540,25 +626,30 @@ end
|
|
540
626
|
end
|
541
627
|
```
|
542
628
|
|
543
|
-
|
544
|
-
should be used instead. `for` is implemented in terms of `each` (so
|
545
|
-
you're adding a level of indirection), but with a twist - `for`
|
546
|
-
doesn't introduce a new scope (unlike `each`) and variables defined
|
547
|
-
in its block will be visible outside it.
|
629
|
+
### Method calls
|
548
630
|
|
549
|
-
|
550
|
-
|
631
|
+
* If the first argument to a method begins with an open parenthesis,
|
632
|
+
always use parentheses in the method invocation. For example, write
|
633
|
+
`f((3 + 2) + 1)`.
|
634
|
+
<a name="parens-no-spaces"></a><sup>[[link](#parens-no-spaces)]</sup>
|
635
|
+
|
636
|
+
* Never put a space between a method name and the opening parenthesis.
|
637
|
+
<a name="no-spaces-method-parens"></a><sup>[[link](#no-spaces-method-parens)]</sup>
|
551
638
|
|
639
|
+
``` ruby
|
552
640
|
# bad
|
553
|
-
|
554
|
-
puts elem
|
555
|
-
end
|
641
|
+
f (3 + 2) + 1
|
556
642
|
|
557
643
|
# good
|
558
|
-
|
644
|
+
f(3 + 2) + 1
|
559
645
|
```
|
560
646
|
|
647
|
+
## Conditional Expressions
|
648
|
+
|
649
|
+
### Conditional keywords
|
650
|
+
|
561
651
|
* Never use `then` for multi-line `if/unless`.
|
652
|
+
<a name="no-then-for-multi-line-if-unless"></a><sup>[[link](#no-then-for-multi-line-if-unless)]</sup>
|
562
653
|
|
563
654
|
``` ruby
|
564
655
|
# bad
|
@@ -572,40 +663,12 @@ if some_condition
|
|
572
663
|
end
|
573
664
|
```
|
574
665
|
|
575
|
-
* Avoid the ternary operator (`?:`) except in cases where all expressions are extremely
|
576
|
-
trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs
|
577
|
-
for single line conditionals.
|
578
|
-
|
579
|
-
``` ruby
|
580
|
-
# bad
|
581
|
-
result = if some_condition then something else something_else end
|
582
|
-
|
583
|
-
# good
|
584
|
-
result = some_condition ? something : something_else
|
585
|
-
```
|
586
|
-
|
587
|
-
* Use one expression per branch in a ternary operator. This
|
588
|
-
also means that ternary operators must not be nested. Prefer
|
589
|
-
`if/else` constructs in these cases.
|
590
|
-
|
591
|
-
``` ruby
|
592
|
-
# bad
|
593
|
-
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
|
594
|
-
|
595
|
-
# good
|
596
|
-
if some_condition
|
597
|
-
nested_condition ? nested_something : nested_something_else
|
598
|
-
else
|
599
|
-
something_else
|
600
|
-
end
|
601
|
-
```
|
602
|
-
|
603
666
|
* The `and` and `or` keywords are banned. It's just not worth it. Always use `&&` and `||` instead.
|
604
|
-
|
605
|
-
* Avoid multi-line `?:` (the ternary operator), use `if/unless` instead.
|
667
|
+
<a name="no-and-or-or"></a><sup>[[link](#no-and-or-or)]</sup>
|
606
668
|
|
607
669
|
* Favor modifier `if/unless` usage when you have a single-line
|
608
670
|
body.
|
671
|
+
<a name="favor-modifier-if-unless"></a><sup>[[link](#favor-modifier-if-unless)]</sup>
|
609
672
|
|
610
673
|
``` ruby
|
611
674
|
# bad
|
@@ -618,6 +681,7 @@ do_something if some_condition
|
|
618
681
|
```
|
619
682
|
|
620
683
|
* Never use `unless` with `else`. Rewrite these with the positive case first.
|
684
|
+
<a name="no-else-with-unless"></a><sup>[[link](#no-else-with-unless)]</sup>
|
621
685
|
|
622
686
|
``` ruby
|
623
687
|
# bad
|
@@ -636,6 +700,7 @@ end
|
|
636
700
|
```
|
637
701
|
|
638
702
|
* Don't use parentheses around the condition of an `if/unless/while`.
|
703
|
+
<a name="no-parens-if-unless-while"></a><sup>[[link](#no-parens-if-unless-while)]</sup>
|
639
704
|
|
640
705
|
``` ruby
|
641
706
|
# bad
|
@@ -649,11 +714,68 @@ if x > 10
|
|
649
714
|
end
|
650
715
|
```
|
651
716
|
|
717
|
+
### Ternary operator
|
718
|
+
|
719
|
+
* Avoid the ternary operator (`?:`) except in cases where all expressions are extremely
|
720
|
+
trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs
|
721
|
+
for single line conditionals.
|
722
|
+
<a name="trivial-ternary"></a><sup>[[link](#trivial-ternary)]</sup>
|
723
|
+
|
724
|
+
``` ruby
|
725
|
+
# bad
|
726
|
+
result = if some_condition then something else something_else end
|
727
|
+
|
728
|
+
# good
|
729
|
+
result = some_condition ? something : something_else
|
730
|
+
```
|
731
|
+
|
732
|
+
* Avoid multi-line `?:` (the ternary operator), use `if/unless` instead.
|
733
|
+
<a name="no-multiline-ternary"></a><sup>[[link](#no-multiline-ternary)]</sup>
|
734
|
+
|
735
|
+
* Use one expression per branch in a ternary operator. This
|
736
|
+
also means that ternary operators must not be nested. Prefer
|
737
|
+
`if/else` constructs in these cases.
|
738
|
+
<a name="one-expression-per-branch"></a><sup>[[link](#one-expression-per-branch)]</sup>
|
739
|
+
|
740
|
+
``` ruby
|
741
|
+
# bad
|
742
|
+
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
|
743
|
+
|
744
|
+
# good
|
745
|
+
if some_condition
|
746
|
+
nested_condition ? nested_something : nested_something_else
|
747
|
+
else
|
748
|
+
something_else
|
749
|
+
end
|
750
|
+
```
|
751
|
+
|
752
|
+
## Syntax
|
753
|
+
|
754
|
+
* Never use `for`, unless you know exactly why. Most of the time iterators
|
755
|
+
should be used instead. `for` is implemented in terms of `each` (so
|
756
|
+
you're adding a level of indirection), but with a twist - `for`
|
757
|
+
doesn't introduce a new scope (unlike `each`) and variables defined
|
758
|
+
in its block will be visible outside it.
|
759
|
+
<a name="avoid-for"></a><sup>[[link](#avoid-for)]</sup>
|
760
|
+
|
761
|
+
``` ruby
|
762
|
+
arr = [1, 2, 3]
|
763
|
+
|
764
|
+
# bad
|
765
|
+
for elem in arr do
|
766
|
+
puts elem
|
767
|
+
end
|
768
|
+
|
769
|
+
# good
|
770
|
+
arr.each { |elem| puts elem }
|
771
|
+
```
|
772
|
+
|
652
773
|
* Prefer `{...}` over `do...end` for single-line blocks. Avoid using
|
653
774
|
`{...}` for multi-line blocks (multiline chaining is always
|
654
775
|
ugly). Always use `do...end` for "control flow" and "method
|
655
776
|
definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end`
|
656
777
|
when chaining.
|
778
|
+
<a name="squiggly-braces"></a><sup>[[link](#squiggly-braces)]</sup>
|
657
779
|
|
658
780
|
``` ruby
|
659
781
|
names = ["Bozhidar", "Steve", "Sarah"]
|
@@ -675,11 +797,12 @@ names.select do |name|
|
|
675
797
|
end.map { |name| name.upcase }
|
676
798
|
```
|
677
799
|
|
678
|
-
|
679
|
-
|
680
|
-
|
800
|
+
* Some will argue that multiline chaining would look OK with the use of `{...}`,
|
801
|
+
but they should ask themselves: is this code really readable and can't the block's
|
802
|
+
contents be extracted into nifty methods?
|
681
803
|
|
682
804
|
* Avoid `return` where not required.
|
805
|
+
<a name="avoid-return"></a><sup>[[link](#avoid-return)]</sup>
|
683
806
|
|
684
807
|
``` ruby
|
685
808
|
# bad
|
@@ -694,6 +817,7 @@ end
|
|
694
817
|
```
|
695
818
|
|
696
819
|
* Use spaces around the `=` operator when assigning default values to method parameters:
|
820
|
+
<a name="spaces-around-equals"></a><sup>[[link](#spaces-around-equals)]</sup>
|
697
821
|
|
698
822
|
``` ruby
|
699
823
|
# bad
|
@@ -711,6 +835,7 @@ While several Ruby books suggest the first style, the second is much more promin
|
|
711
835
|
in practice (and arguably a bit more readable).
|
712
836
|
|
713
837
|
* Using the return value of `=` (an assignment) is ok.
|
838
|
+
<a name="use-return-value-of-assignment"></a><sup>[[link](#use-return-value-of-assignment)]</sup>
|
714
839
|
|
715
840
|
``` ruby
|
716
841
|
# bad
|
@@ -724,6 +849,7 @@ if (v = next_value) == "hello" ...
|
|
724
849
|
```
|
725
850
|
|
726
851
|
* Use `||=` freely to initialize variables.
|
852
|
+
<a name="memoization-for-initialization"></a><sup>[[link](#memoize-away)]</sup>
|
727
853
|
|
728
854
|
``` ruby
|
729
855
|
# set name to Bozhidar, only if it's nil or false
|
@@ -732,6 +858,7 @@ name ||= "Bozhidar"
|
|
732
858
|
|
733
859
|
* Don't use `||=` to initialize boolean variables. (Consider what
|
734
860
|
would happen if the current value happened to be `false`.)
|
861
|
+
<a name="no-memoization-for-boolean"></a><sup>[[link](#no-memoization-for-boolean)]</sup>
|
735
862
|
|
736
863
|
``` ruby
|
737
864
|
# bad - would set enabled to true even if it was false
|
@@ -745,22 +872,10 @@ enabled = true if enabled.nil?
|
|
745
872
|
etc. ). They are quite cryptic and their use in anything but
|
746
873
|
one-liner scripts is discouraged. Prefer long form versions such as
|
747
874
|
`$PROGRAM_NAME`.
|
748
|
-
|
749
|
-
* Never put a space between a method name and the opening parenthesis.
|
750
|
-
|
751
|
-
``` ruby
|
752
|
-
# bad
|
753
|
-
f (3 + 2) + 1
|
754
|
-
|
755
|
-
# good
|
756
|
-
f(3 + 2) + 1
|
757
|
-
```
|
758
|
-
|
759
|
-
* If the first argument to a method begins with an open parenthesis,
|
760
|
-
always use parentheses in the method invocation. For example, write
|
761
|
-
`f((3 + 2) + 1)`.
|
875
|
+
<a name="no-cryptic-vars"></a><sup>[[link](#no-cryptic-vars)]</sup>
|
762
876
|
|
763
877
|
* Use `_` for unused block parameters.
|
878
|
+
<a name="underscore-unused-vars"></a><sup>[[link](#underscore-unused-vars)]</sup>
|
764
879
|
|
765
880
|
``` ruby
|
766
881
|
# bad
|
@@ -774,5 +889,8 @@ result = hash.map { |_, v| v + 1 }
|
|
774
889
|
implementation detail to support Ruby features like `case`, and it's not commutative.
|
775
890
|
For example, `String === "hi"` is true and `"hi" === String` is false.
|
776
891
|
Instead, use `is_a?` or `kind_of?` if you must.
|
892
|
+
<a name="type-checking-is-a-kind-of"></a><sup>[[link](#type-checking-is-a-kind-of)]</sup>
|
777
893
|
|
778
894
|
Refactoring is even better. It's worth looking hard at any code that explicitly checks types.
|
895
|
+
|
896
|
+
[rubocop-guide]: https://github.com/rubocop-hq/ruby-style-guide
|