rubocop-github 0.18.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 +32 -16
- data/STYLEGUIDE.md +206 -89
- data/config/default.yml +1369 -46
- data/config/default_cops.yml +3 -0
- data/config/rails.yml +361 -74
- data/config/rails_cops.yml +62 -0
- 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 +9 -3
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,23 +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
461
|
should only exist if a non-bang counterpart (method name which does NOT end with !)
|
391
462
|
also exists.
|
463
|
+
<a name="dangerous-method-bang"></a><sup>[[link](#dangerous-method-bang)]</sup>
|
392
464
|
|
393
465
|
## Percent Literals
|
394
466
|
|
395
467
|
* Use `%w` freely.
|
468
|
+
<a name="use-percent-w-freely"></a><sup>[[link](#use-percent-w-freely)]</sup>
|
396
469
|
|
397
470
|
``` ruby
|
398
471
|
STATES = %w(draft open closed)
|
@@ -400,6 +473,7 @@ STATES = %w(draft open closed)
|
|
400
473
|
|
401
474
|
* Use `%()` for single-line strings which require both interpolation
|
402
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>
|
403
477
|
|
404
478
|
``` ruby
|
405
479
|
# bad (no interpolation needed)
|
@@ -419,6 +493,7 @@ STATES = %w(draft open closed)
|
|
419
493
|
```
|
420
494
|
|
421
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>
|
422
497
|
|
423
498
|
``` ruby
|
424
499
|
# bad
|
@@ -436,6 +511,7 @@ STATES = %w(draft open closed)
|
|
436
511
|
|
437
512
|
* Avoid using $1-9 as it can be hard to track what they contain. Named groups
|
438
513
|
can be used instead.
|
514
|
+
<a name="capture-with-named-groups"></a><sup>[[link](#capture-with-named-groups)]</sup>
|
439
515
|
|
440
516
|
``` ruby
|
441
517
|
# bad
|
@@ -451,6 +527,7 @@ process meaningful_var
|
|
451
527
|
|
452
528
|
* Be careful with `^` and `$` as they match start/end of line, not string endings.
|
453
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>
|
454
531
|
|
455
532
|
``` ruby
|
456
533
|
string = "some injection\nusername"
|
@@ -460,6 +537,7 @@ string[/\Ausername\z/] # don't match
|
|
460
537
|
|
461
538
|
* Use `x` modifier for complex regexps. This makes them more readable and you
|
462
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>
|
463
541
|
|
464
542
|
``` ruby
|
465
543
|
regexp = %r{
|
@@ -476,6 +554,7 @@ regexp = %r{
|
|
476
554
|
Always `require` dependencies used directly in a script at the start of the same file.
|
477
555
|
Resources that will get autoloaded on first use—such as Rails models, controllers, or
|
478
556
|
helpers—don't need to be required.
|
557
|
+
<a name="require-dependencies-directly"></a><sup>[[link](#require-dependencies-directly)]</sup>
|
479
558
|
|
480
559
|
``` ruby
|
481
560
|
require "set"
|
@@ -491,6 +570,7 @@ documentation about the libraries that the current file uses.
|
|
491
570
|
## Strings
|
492
571
|
|
493
572
|
* Prefer string interpolation instead of string concatenation:
|
573
|
+
<a name="string-interpolation"></a><sup>[[link](#string-interpolation)]</sup>
|
494
574
|
|
495
575
|
``` ruby
|
496
576
|
# bad
|
@@ -503,6 +583,7 @@ email_with_name = "#{user.name} <#{user.email}>"
|
|
503
583
|
* Use double-quoted strings. Interpolation and escaped characters
|
504
584
|
will always work without a delimiter change, and `'` is a lot more
|
505
585
|
common than `"` in string literals.
|
586
|
+
<a name="double-quotes"></a><sup>[[link](#double-quotes)]</sup>
|
506
587
|
|
507
588
|
``` ruby
|
508
589
|
# bad
|
@@ -515,6 +596,7 @@ name = "Bozhidar"
|
|
515
596
|
* Avoid using `String#+` when you need to construct large data chunks.
|
516
597
|
Instead, use `String#<<`. Concatenation mutates the string instance in-place
|
517
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>
|
518
600
|
|
519
601
|
``` ruby
|
520
602
|
# good and also fast
|
@@ -526,10 +608,13 @@ paragraphs.each do |paragraph|
|
|
526
608
|
end
|
527
609
|
```
|
528
610
|
|
529
|
-
##
|
611
|
+
## Methods
|
612
|
+
|
613
|
+
### Method definitions
|
530
614
|
|
531
615
|
* Use `def` with parentheses when there are arguments. Omit the
|
532
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>
|
533
618
|
|
534
619
|
``` ruby
|
535
620
|
def some_method
|
@@ -541,25 +626,30 @@ end
|
|
541
626
|
end
|
542
627
|
```
|
543
628
|
|
544
|
-
|
545
|
-
should be used instead. `for` is implemented in terms of `each` (so
|
546
|
-
you're adding a level of indirection), but with a twist - `for`
|
547
|
-
doesn't introduce a new scope (unlike `each`) and variables defined
|
548
|
-
in its block will be visible outside it.
|
629
|
+
### Method calls
|
549
630
|
|
550
|
-
|
551
|
-
|
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>
|
552
638
|
|
639
|
+
``` ruby
|
553
640
|
# bad
|
554
|
-
|
555
|
-
puts elem
|
556
|
-
end
|
641
|
+
f (3 + 2) + 1
|
557
642
|
|
558
643
|
# good
|
559
|
-
|
644
|
+
f(3 + 2) + 1
|
560
645
|
```
|
561
646
|
|
647
|
+
## Conditional Expressions
|
648
|
+
|
649
|
+
### Conditional keywords
|
650
|
+
|
562
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>
|
563
653
|
|
564
654
|
``` ruby
|
565
655
|
# bad
|
@@ -573,40 +663,12 @@ if some_condition
|
|
573
663
|
end
|
574
664
|
```
|
575
665
|
|
576
|
-
* Avoid the ternary operator (`?:`) except in cases where all expressions are extremely
|
577
|
-
trivial. However, do use the ternary operator(`?:`) over `if/then/else/end` constructs
|
578
|
-
for single line conditionals.
|
579
|
-
|
580
|
-
``` ruby
|
581
|
-
# bad
|
582
|
-
result = if some_condition then something else something_else end
|
583
|
-
|
584
|
-
# good
|
585
|
-
result = some_condition ? something : something_else
|
586
|
-
```
|
587
|
-
|
588
|
-
* Use one expression per branch in a ternary operator. This
|
589
|
-
also means that ternary operators must not be nested. Prefer
|
590
|
-
`if/else` constructs in these cases.
|
591
|
-
|
592
|
-
``` ruby
|
593
|
-
# bad
|
594
|
-
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else
|
595
|
-
|
596
|
-
# good
|
597
|
-
if some_condition
|
598
|
-
nested_condition ? nested_something : nested_something_else
|
599
|
-
else
|
600
|
-
something_else
|
601
|
-
end
|
602
|
-
```
|
603
|
-
|
604
666
|
* The `and` and `or` keywords are banned. It's just not worth it. Always use `&&` and `||` instead.
|
605
|
-
|
606
|
-
* 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>
|
607
668
|
|
608
669
|
* Favor modifier `if/unless` usage when you have a single-line
|
609
670
|
body.
|
671
|
+
<a name="favor-modifier-if-unless"></a><sup>[[link](#favor-modifier-if-unless)]</sup>
|
610
672
|
|
611
673
|
``` ruby
|
612
674
|
# bad
|
@@ -619,6 +681,7 @@ do_something if some_condition
|
|
619
681
|
```
|
620
682
|
|
621
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>
|
622
685
|
|
623
686
|
``` ruby
|
624
687
|
# bad
|
@@ -637,6 +700,7 @@ end
|
|
637
700
|
```
|
638
701
|
|
639
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>
|
640
704
|
|
641
705
|
``` ruby
|
642
706
|
# bad
|
@@ -650,11 +714,68 @@ if x > 10
|
|
650
714
|
end
|
651
715
|
```
|
652
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
|
+
|
653
773
|
* Prefer `{...}` over `do...end` for single-line blocks. Avoid using
|
654
774
|
`{...}` for multi-line blocks (multiline chaining is always
|
655
775
|
ugly). Always use `do...end` for "control flow" and "method
|
656
776
|
definitions" (e.g. in Rakefiles and certain DSLs). Avoid `do...end`
|
657
777
|
when chaining.
|
778
|
+
<a name="squiggly-braces"></a><sup>[[link](#squiggly-braces)]</sup>
|
658
779
|
|
659
780
|
``` ruby
|
660
781
|
names = ["Bozhidar", "Steve", "Sarah"]
|
@@ -676,11 +797,12 @@ names.select do |name|
|
|
676
797
|
end.map { |name| name.upcase }
|
677
798
|
```
|
678
799
|
|
679
|
-
|
680
|
-
|
681
|
-
|
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?
|
682
803
|
|
683
804
|
* Avoid `return` where not required.
|
805
|
+
<a name="avoid-return"></a><sup>[[link](#avoid-return)]</sup>
|
684
806
|
|
685
807
|
``` ruby
|
686
808
|
# bad
|
@@ -695,6 +817,7 @@ end
|
|
695
817
|
```
|
696
818
|
|
697
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>
|
698
821
|
|
699
822
|
``` ruby
|
700
823
|
# bad
|
@@ -712,6 +835,7 @@ While several Ruby books suggest the first style, the second is much more promin
|
|
712
835
|
in practice (and arguably a bit more readable).
|
713
836
|
|
714
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>
|
715
839
|
|
716
840
|
``` ruby
|
717
841
|
# bad
|
@@ -725,6 +849,7 @@ if (v = next_value) == "hello" ...
|
|
725
849
|
```
|
726
850
|
|
727
851
|
* Use `||=` freely to initialize variables.
|
852
|
+
<a name="memoization-for-initialization"></a><sup>[[link](#memoize-away)]</sup>
|
728
853
|
|
729
854
|
``` ruby
|
730
855
|
# set name to Bozhidar, only if it's nil or false
|
@@ -733,6 +858,7 @@ name ||= "Bozhidar"
|
|
733
858
|
|
734
859
|
* Don't use `||=` to initialize boolean variables. (Consider what
|
735
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>
|
736
862
|
|
737
863
|
``` ruby
|
738
864
|
# bad - would set enabled to true even if it was false
|
@@ -746,22 +872,10 @@ enabled = true if enabled.nil?
|
|
746
872
|
etc. ). They are quite cryptic and their use in anything but
|
747
873
|
one-liner scripts is discouraged. Prefer long form versions such as
|
748
874
|
`$PROGRAM_NAME`.
|
749
|
-
|
750
|
-
* Never put a space between a method name and the opening parenthesis.
|
751
|
-
|
752
|
-
``` ruby
|
753
|
-
# bad
|
754
|
-
f (3 + 2) + 1
|
755
|
-
|
756
|
-
# good
|
757
|
-
f(3 + 2) + 1
|
758
|
-
```
|
759
|
-
|
760
|
-
* If the first argument to a method begins with an open parenthesis,
|
761
|
-
always use parentheses in the method invocation. For example, write
|
762
|
-
`f((3 + 2) + 1)`.
|
875
|
+
<a name="no-cryptic-vars"></a><sup>[[link](#no-cryptic-vars)]</sup>
|
763
876
|
|
764
877
|
* Use `_` for unused block parameters.
|
878
|
+
<a name="underscore-unused-vars"></a><sup>[[link](#underscore-unused-vars)]</sup>
|
765
879
|
|
766
880
|
``` ruby
|
767
881
|
# bad
|
@@ -775,5 +889,8 @@ result = hash.map { |_, v| v + 1 }
|
|
775
889
|
implementation detail to support Ruby features like `case`, and it's not commutative.
|
776
890
|
For example, `String === "hi"` is true and `"hi" === String` is false.
|
777
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>
|
778
893
|
|
779
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
|