xmp2assert 1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rubocop.yml +172 -0
- data/.yardopts +5 -0
- data/Gemfile +27 -0
- data/LICENSE.txt +19 -0
- data/README.md +40 -0
- data/Rakefile +61 -0
- data/Stylegiude.md +284 -0
- data/exe/xmpcheck.rb +75 -0
- data/lib/xmp2assert/assertions.rb +157 -0
- data/lib/xmp2assert/classifier.rb +71 -0
- data/lib/xmp2assert/converter.rb +113 -0
- data/lib/xmp2assert/prettier_inspect.rb +50 -0
- data/lib/xmp2assert/quasifile.rb +144 -0
- data/lib/xmp2assert/template.erb +37 -0
- data/lib/xmp2assert/version.rb +27 -0
- data/lib/xmp2assert/xmp2rexp.rb +56 -0
- data/lib/xmp2assert.rb +41 -0
- data/xmp2assert.gemspec +71 -0
- metadata +249 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 359f8dd94e42daf5ec326092ce2a5f6f0e7c2e12
|
4
|
+
data.tar.gz: b8b3d51036e2e0f6747de9f5cc5b7ac6f8ba21a0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8e30f7caa4f14ba03804fb9a2e5f4ed6f911d32324051d9e50130e3146fd85a233de37061e6be7e294818c018441314a8092da6b098abf0a1d8ca8d5ca15017d
|
7
|
+
data.tar.gz: 3fb6f258658deec6fb473b1c57fe1925dabaf96f9213c6ec84bf4f7c541a33cc32f5cf3489249bac8e8c6de21e3641c9cee24a501e83fe096e71967931582e81
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
#! /your/favourite/path/to/rubocop
|
2
|
+
# -*- mode: yaml; coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2017 Urabe, Shyouhei
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
AllCops:
|
25
|
+
DisabledByDefault: false # true
|
26
|
+
DisplayCopNames: true
|
27
|
+
Exclude:
|
28
|
+
- "vendor/**/*"
|
29
|
+
TargetRubyVersion: 2.2 # 2.3 # 2.4 # 2.5
|
30
|
+
|
31
|
+
Lint/AmbiguousBlockAssociation:
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Lint/EmptyWhen:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Rails:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/AlignHash:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/AlignParameters:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/BracesAroundHashParameters:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/CaseEquality:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Style/CaseIndentation:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Style/ClassAndModuleChildren:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Style/ClassVars:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Style/ElseAlignment:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Style/EmptyCaseCondition:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Style/EmptyLineAfterMagicComment:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
Style/EmptyLinesAroundClassBody:
|
71
|
+
Enabled: false
|
72
|
+
|
73
|
+
Style/EmptyLinesAroundModuleBody:
|
74
|
+
Enabled: false
|
75
|
+
|
76
|
+
Style/EmptyLiteral:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
Style/ExtraSpacing:
|
80
|
+
Enabled: false
|
81
|
+
|
82
|
+
Style/FormatString:
|
83
|
+
Enabled: false
|
84
|
+
|
85
|
+
Style/IndentHash:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
Style/IndentHeredoc:
|
89
|
+
Enabled: false
|
90
|
+
|
91
|
+
Style/IndentationWidth:
|
92
|
+
Enabled: false
|
93
|
+
|
94
|
+
Style/MethodDefParentheses:
|
95
|
+
Enabled: false
|
96
|
+
|
97
|
+
Style/MultilineIfThen:
|
98
|
+
Enabled: false
|
99
|
+
|
100
|
+
Style/ParallelAssignment:
|
101
|
+
Enabled: false
|
102
|
+
|
103
|
+
Style/PercentLiteralDelimiters:
|
104
|
+
Enabled: false
|
105
|
+
|
106
|
+
Style/RedundantReturn:
|
107
|
+
Enabled: false
|
108
|
+
|
109
|
+
Style/SpaceAroundOperators:
|
110
|
+
Enabled: false
|
111
|
+
|
112
|
+
Style/SpaceInsideBrackets:
|
113
|
+
Enabled: false
|
114
|
+
|
115
|
+
Style/StringLiterals:
|
116
|
+
Enabled: false
|
117
|
+
|
118
|
+
Style/StringLiteralsInInterpolation:
|
119
|
+
Enabled: false
|
120
|
+
|
121
|
+
Style/SymbolArray:
|
122
|
+
Enabled: false
|
123
|
+
|
124
|
+
Style/TrailingCommaInLiteral:
|
125
|
+
Enabled: false
|
126
|
+
|
127
|
+
Style/TrailingUnderscoreVariable:
|
128
|
+
Enabled: false
|
129
|
+
|
130
|
+
Style/VariableName:
|
131
|
+
Enabled: false
|
132
|
+
|
133
|
+
Style/WordArray:
|
134
|
+
Enabled: false
|
135
|
+
|
136
|
+
Lint/UselessAssignment:
|
137
|
+
Exclude:
|
138
|
+
- 'test/**/*'
|
139
|
+
- '*.gemspec'
|
140
|
+
|
141
|
+
Metrics/AbcSize:
|
142
|
+
Exclude:
|
143
|
+
- 'test/**/*'
|
144
|
+
- '*.gemspec'
|
145
|
+
|
146
|
+
Metrics/BlockLength:
|
147
|
+
Exclude:
|
148
|
+
- 'test/**/*'
|
149
|
+
- '*.gemspec'
|
150
|
+
|
151
|
+
Metrics/ClassLength:
|
152
|
+
Exclude:
|
153
|
+
- 'test/**/*'
|
154
|
+
- '*.gemspec'
|
155
|
+
|
156
|
+
Style/ClassAndModuleCamelCase:
|
157
|
+
Exclude:
|
158
|
+
- 'test/**/*'
|
159
|
+
- '*.gemspec'
|
160
|
+
|
161
|
+
Style/Semicolon:
|
162
|
+
Exclude:
|
163
|
+
- 'lib/*/version.rb' # for YARD
|
164
|
+
|
165
|
+
Metrics/LineLength:
|
166
|
+
AllowURI: true
|
167
|
+
Max: 79
|
168
|
+
|
169
|
+
Metrics/MethodLength:
|
170
|
+
CountComments: false
|
171
|
+
Enabled: true
|
172
|
+
Max: 30
|
data/.yardopts
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#! /your/favourite/path/to/bundler
|
2
|
+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level 2 -*-
|
3
|
+
# -*- frozen_string_literal: true -*-
|
4
|
+
# -*- warn_indent: true -*-
|
5
|
+
|
6
|
+
# Copyright (c) 2017 Urabe, Shyouhei
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be
|
16
|
+
# included in all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
+
# SOFTWARE.
|
25
|
+
|
26
|
+
source 'https://rubygems.org'
|
27
|
+
gemspec require: false
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2017 Urabe, Shyouhei
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be
|
11
|
+
included in all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
You might have experience of encountering something like
|
2
|
+
|
3
|
+
```ruby:
|
4
|
+
1 + 2 # => 3
|
5
|
+
```
|
6
|
+
|
7
|
+
What is this comment? This means when you evaluate `1 + 2`, the result is `3`.
|
8
|
+
|
9
|
+
This kind of comments are handy. But one thing remains uncertain is: do they actually are right?
|
10
|
+
|
11
|
+
There are tools like [JoshCheek/seeing_is_believing] who generates such comments, but so far I have never seen a tool that does vice versa.
|
12
|
+
|
13
|
+
So I made this library.
|
14
|
+
|
15
|
+
## Basic usage as script
|
16
|
+
|
17
|
+
I made a fairly simple script named xmpcheck.rb. Run that with a list of ruby script.
|
18
|
+
|
19
|
+
```sh
|
20
|
+
% bundle exec xmpcheck.rb file file file ...
|
21
|
+
```
|
22
|
+
|
23
|
+
It automatically checks for those comments and see if they are right.
|
24
|
+
|
25
|
+
## Library usage
|
26
|
+
|
27
|
+
Really sorry but we have no dedicated document than the YARD. Pro-tip: look at `XMP2Assert::Assertions`
|
28
|
+
|
29
|
+
## What if I want to contribute?
|
30
|
+
|
31
|
+
Before proceeding any further, you have to take this action:
|
32
|
+
|
33
|
+
1. Clone this project.
|
34
|
+
2. Run the test at least once.
|
35
|
+
3. Read through the [style guide].
|
36
|
+
4. Create your own topic branch and do your stuff.
|
37
|
+
5. Send us a pull request.
|
38
|
+
|
39
|
+
[JoshCheek/seeing_is_believing]: https://github.com/JoshCheek/seeing_is_believing
|
40
|
+
[style guide]: Styleguide.md
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#! /your/favourite/path/to/rake
|
2
|
+
# -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level 2 -*-
|
3
|
+
# -*- frozen_string_literal: true -*-
|
4
|
+
# -*- warn_indent: true -*-
|
5
|
+
|
6
|
+
# Copyright (c) 2017 Urabe, Shyouhei
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be
|
16
|
+
# included in all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
+
# SOFTWARE.
|
25
|
+
|
26
|
+
require 'rubygems'
|
27
|
+
require 'bundler/setup'
|
28
|
+
Bundler.setup :development
|
29
|
+
require 'rake'
|
30
|
+
require 'yard'
|
31
|
+
require 'bundler/gem_tasks'
|
32
|
+
require 'rake/testtask'
|
33
|
+
require 'rubocop/rake_task'
|
34
|
+
|
35
|
+
YARD::Rake::YardocTask.new
|
36
|
+
RuboCop::RakeTask.new
|
37
|
+
|
38
|
+
task default: :test
|
39
|
+
task spec: :test
|
40
|
+
desc "run tests"
|
41
|
+
Rake::TestTask.new do |t|
|
42
|
+
t.test_files = FileList['test/**/*.rb'] - ['test/test_helper.rb']
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "a la rails console"
|
46
|
+
task :console do
|
47
|
+
require_relative 'lib/xmp2assert'
|
48
|
+
require 'irb'
|
49
|
+
require 'irb/completion'
|
50
|
+
ARGV.clear
|
51
|
+
IRB.start
|
52
|
+
end
|
53
|
+
task c: :console
|
54
|
+
|
55
|
+
desc "pry console"
|
56
|
+
task :pry do
|
57
|
+
require_relative 'lib/xmp2assert'
|
58
|
+
require 'pry'
|
59
|
+
ARGV.clear
|
60
|
+
Pry.start
|
61
|
+
end
|
data/Stylegiude.md
ADDED
@@ -0,0 +1,284 @@
|
|
1
|
+
# Ruby style guide to use in this project
|
2
|
+
|
3
|
+
I'm not a language nazi here. This guide is for you to ease your _documenting_, not to cramp your coding. This guide tells not so much about the ruby code themselves, rather focusing on comments.
|
4
|
+
|
5
|
+
## Terminology
|
6
|
+
|
7
|
+
The key words "_MUST_", "_MUST NOT_", "_REQUIRED_", "_SHALL_", "_SHALL NOT_", "_SHOULD_", "_SHOULD NOT_", "_RECOMMENDED_", "_MAY_", and "_OPTIONAL_" in this document are to be interpreted as described in [RFC 2119].
|
8
|
+
|
9
|
+
## Use of characters in a file
|
10
|
+
|
11
|
+
### DO
|
12
|
+
|
13
|
+
- Any files under this project _MUST_ strictly be written using code points described in Unicode's "C0 Controls and Basic Latin" [1] only, and _MUST_ then be encoded using [RFC 3629].
|
14
|
+
- This is for maximum portability.
|
15
|
+
- You can't represent your name in that code range? Me too.
|
16
|
+
- A file _SHOULD_ end with a U+000A.
|
17
|
+
|
18
|
+
### DON'T
|
19
|
+
|
20
|
+
- So-called "control characters" (U+0000 to U+001F and U+007F) _SHOULD_ generally be avoided. U+000A is the only exception to this principle.
|
21
|
+
- Especially, U+0009 and U+000D _MUST NOT_ appear verbatimly in a source code. They _MUST_ be escaped as `\t` and `\r` respectively when needed.
|
22
|
+
- Whenever you cannot escape them, it indicates a serious design flaw.
|
23
|
+
- U+000A _MUST NOT_ appear right after U+0020.
|
24
|
+
- U+FEFF _MUST NOT_ appear at the very beginning of a file.
|
25
|
+
|
26
|
+
## Use of languages in a file
|
27
|
+
|
28
|
+
### DO
|
29
|
+
- Comments _MUST_ be written in modern English.
|
30
|
+
- One or more spaces _MUST_ be placed between sentences in a comment. You _MAY_ put more than one spaces.
|
31
|
+
- There are discussions as to how much spaces needed between sentences [2]. I use single spacing in this guide because that is modern, but honestly I'm used to have two spaces, because that's the default of Emacs.
|
32
|
+
- Identifiers (method names etc.) _MUST_ be named in valid modern English words, without shortening.
|
33
|
+
- This doesn't mean you should name your class Emma or Sophia.
|
34
|
+
- Local variables in a sufficiently short scope _MAY_ be named in one character like `i`, `j`, `k`. This conventional usage of variable names is a tradition to be honored.
|
35
|
+
- When you name something, that name _SHOULD_ be elegant, concise, succinct, and (most importantly) to the point.
|
36
|
+
|
37
|
+
## Comments
|
38
|
+
|
39
|
+
### DO
|
40
|
+
|
41
|
+
- Write comments in [markdown], with [YARD]'s tag extensions, and let YARD parse that.
|
42
|
+
- See the YARD section below.
|
43
|
+
|
44
|
+
### DON'T
|
45
|
+
|
46
|
+
- Comments _SHOULD NOT_ be longer than 80 characters length.
|
47
|
+
- I don't hesitate longer ruby lines but I do hesitate long comments. That should indicate a over-commenting. Try avoiding too much comments.
|
48
|
+
- Long comments in a source code _SHOULD_ be line-wrapped.
|
49
|
+
- Don't waste your time writing comments to describe bad codes; rather have time to make the code better.
|
50
|
+
|
51
|
+
## YARD
|
52
|
+
|
53
|
+
- `@param`, which is the most frequently used, _SHOULD_ be done like this:
|
54
|
+
|
55
|
+
```
|
56
|
+
# @param foo [Foo] description of foo.
|
57
|
+
# @param bar [Bar] description of bar.
|
58
|
+
```
|
59
|
+
|
60
|
+
Pro-tip here is that description _SHOULD_ start with lower character. YARD capitalizes that when necessary.
|
61
|
+
|
62
|
+
Also trailing periods are _RECOMMENDED_.
|
63
|
+
|
64
|
+
- Ruby2's explicit named parameters are preferred. But if you decide to take good-old hash-taking strategy instead, `@option` is done like this:
|
65
|
+
|
66
|
+
```
|
67
|
+
# @param opt [Hash] description of opt.
|
68
|
+
# @option opt [Foo] :foo description of foo.
|
69
|
+
# @option opt [Bar] :bar description of bar.
|
70
|
+
```
|
71
|
+
|
72
|
+
I recommend you to align things vertically for aesthetic reasons. No ugly comments are read seriously.
|
73
|
+
|
74
|
+
- `@return` is like this:
|
75
|
+
|
76
|
+
```
|
77
|
+
# @return [Foo] description when it returns Foo.
|
78
|
+
# @return [Bar] description when it returns Bar.
|
79
|
+
```
|
80
|
+
|
81
|
+
Return's descriptions _SHOULD_ also start with lower character. It is worth noting that you _SHOULD_ also provide one for `attr_` family.
|
82
|
+
|
83
|
+
```
|
84
|
+
attr_reader :foo # @return [Foo] description of foo
|
85
|
+
```
|
86
|
+
|
87
|
+
- When your method takes a block that _SHOULD_ come with `@yieldparam` and `@yieldreturn`. `@yieldreturn` _MAY_ be omitted when the block-evaluated value does not matter but that sounds something is wrong with API design.
|
88
|
+
|
89
|
+
```
|
90
|
+
# @yieldparam foo [Foo] description of foo
|
91
|
+
# @yieldreturn [Bar] description of value to be returned from the block
|
92
|
+
```
|
93
|
+
|
94
|
+
- Exceptions are, of course to be documented. But in practice it often is pretty difficult to list up all possible exceptions that can happen inside, especially when your method calls 3rd-party library or does network IO. So don't try to be perfect. Just write what you know. Less is better than nothing.
|
95
|
+
|
96
|
+
```
|
97
|
+
# @raise [Foo] description when Foo is raised.
|
98
|
+
```
|
99
|
+
## Identifiers
|
100
|
+
|
101
|
+
### DO
|
102
|
+
|
103
|
+
- Constants _SHOULD_ be named in UpperCamelCase.
|
104
|
+
- Everything except constants _SHOULD_ be named in snake_case.
|
105
|
+
|
106
|
+
### DON'T
|
107
|
+
|
108
|
+
- Bare numeric literals _SHOULD NOT_ be used as magic numbers. Assign them to appropriate variables / constants and use them instead.
|
109
|
+
- New global variables _MUST NOT_ be introduced.
|
110
|
+
- Predefined global variables _SHOULD NOT_ be (re-)assigned. There tends to be other ways without doing so.
|
111
|
+
- A bang method _MUST NOT_ be created without its bang-less counterpart.
|
112
|
+
|
113
|
+
## File-scope Structures
|
114
|
+
|
115
|
+
- A ruby file is _RECOMMENDED_ to be written like this:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
#! shebang line if this is a non-library
|
119
|
+
# -*- Emacs-compatible mode line -*-
|
120
|
+
# -*- other magic comments -*-
|
121
|
+
# -*- other magic comments (write necessary times)-*-
|
122
|
+
|
123
|
+
# Copyright notices
|
124
|
+
# ``Permission is hereby granted, ...''
|
125
|
+
|
126
|
+
require lines
|
127
|
+
require_relative lines
|
128
|
+
|
129
|
+
# class/module description in YARD
|
130
|
+
class Foo::Bar < Baz
|
131
|
+
using Something # if any
|
132
|
+
prepend Something # if any
|
133
|
+
include Something # if any
|
134
|
+
extend Something # if any
|
135
|
+
|
136
|
+
# method description in YARD
|
137
|
+
def self.method argv...
|
138
|
+
...
|
139
|
+
end
|
140
|
+
|
141
|
+
# attribute description in YARD
|
142
|
+
attr_reader :something
|
143
|
+
attr_reader :something_else # description can be here if short enough
|
144
|
+
|
145
|
+
# method description in YARD
|
146
|
+
def method argv...
|
147
|
+
...
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def private_method
|
153
|
+
# private methods can omit YARD comments
|
154
|
+
end
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
- This recommended file structure is known to be OK to feed to YARD's parser.
|
159
|
+
- You can ignore this recommendation on exceptional situations, but a good reason should come with that. I strongly encourage you to write why to that part's comment.
|
160
|
+
|
161
|
+
### DO
|
162
|
+
|
163
|
+
- Shebang line would automatically be modified appropriately on installation, by the rubygems infrastructure. So don't get nervous about what to write; just write something. I normally put `#! /your/favourite/path/to/ruby` or something like that, to indicate that the line content is not something serious.
|
164
|
+
- This is a less-known fact but there are two kinds of magic comments; those which are Emacs compatible, and those aren't. In order to interface with the editor, those compatible ones _MUST_ be placed where it looks at. On the other hand, incompatible ones _MUST NOT_ be placed there, in order to avoid harassing other processes. Ruby allows magic comments on liberal places.
|
165
|
+
|
166
|
+
This means you _SHOULD_ separate magic comments into more than two. As of writing this document, following magic comments are known to be Emacs incompatible:
|
167
|
+
- `frozen_string_literal`
|
168
|
+
- `warn_indent`
|
169
|
+
- `warn_past_scope`
|
170
|
+
- Copyright notices _SHALL_ be placed in every files, unless technically impossible. People tend to copy and paste your code without using their brain. You must be explicit.
|
171
|
+
- All dependencies _SHOULD_ be listed explicitly by `require`-ing them all, so that your file can be used stand-alone. In other words, even if your file is a part of your library, that file, alone, should be `require`-able without extra hustle.
|
172
|
+
|
173
|
+
### DON'T
|
174
|
+
|
175
|
+
- In order to prevent unnecessary reopen of classes, you _SHOULD NOT_ nest class declarations like `class Foo; class Bar`. Use `class Foo::Bar` instead for that example. If you do want to touch `Foo` as well as `Bar`, consider separate them in distinct files.
|
176
|
+
- Class singleton methods _SHOULD_ be defined using `def self.foo`, to prevent nested classes. If you want to do complex manipulations on the metaclass you can, but consider to refactor your code before doing so.
|
177
|
+
- `protected` _MUST NOT_ be used.
|
178
|
+
|
179
|
+
## Ruby Control Flows
|
180
|
+
|
181
|
+
### DON'T
|
182
|
+
|
183
|
+
- No `else` _MUST_ come with `unless`.
|
184
|
+
- No `while` _MUST_ come with `begin`.
|
185
|
+
- No `=begin` (thus no `=end`) _MUST_ appear in a source code.
|
186
|
+
- No `BEGIN` _MUST_ exist.
|
187
|
+
- No `END` _MUST_ exist.
|
188
|
+
- Postfix `rescue` modifiers _SHOULD_ be avoided whenever possible. Reasons behind this:
|
189
|
+
[Feature #6739] [Feature #10042]
|
190
|
+
- Postfix modifiers _SHOULD NOT_ be "nested" like `foo if bar while baz`. That might work, but never be understandable by mortals.
|
191
|
+
- Ternary operators _SHOULD NOT_ be "nested" like `q ? w : e ? r : t ? y : u`. That might work, but never be understandable by mortals.
|
192
|
+
- I see no need to use semicolons (`;`) except when you trick YARD parser.
|
193
|
+
|
194
|
+
### DO
|
195
|
+
|
196
|
+
- Indent using 2 spaces. Neither 4 nor 3.
|
197
|
+
- I prefer writing `then`.
|
198
|
+
- Parens _MAY_ be omitted where you can.
|
199
|
+
- My style is extremely paren-free. Try `git grep '[(]'` and see most occurrences are inside of comments.
|
200
|
+
|
201
|
+
However that doesn't mean you _can't_ use them. My way is that when you can omit parens you do. Ruby is powerful so for most cases can. But there are several situations where you can't. Don't hesitate then.
|
202
|
+
|
203
|
+
- I like what I call a case-else, which is a `case` statement that only has one `when` and optionally one `else`.
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
case expr when foo then
|
207
|
+
# then
|
208
|
+
else
|
209
|
+
# else
|
210
|
+
end
|
211
|
+
```
|
212
|
+
|
213
|
+
This can be seen as a "smarter" `if` in some sense. The position of `when` emphasizes this is not a multiple branch.
|
214
|
+
|
215
|
+
- When you do need multiple branches, you do ordinal `case` in this indentation:
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
case expr
|
219
|
+
when foo then
|
220
|
+
# foo
|
221
|
+
when bar then
|
222
|
+
# bar
|
223
|
+
when baz then
|
224
|
+
# baz
|
225
|
+
else
|
226
|
+
# otherwise
|
227
|
+
end
|
228
|
+
```
|
229
|
+
|
230
|
+
- I sometimes use heredocs this way:
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
printf <<~'end', 1, 2, 3
|
234
|
+
foo %d bar %d baz %d
|
235
|
+
end
|
236
|
+
```
|
237
|
+
|
238
|
+
Feel what's happening. When it takes a block things gets more complex:
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
OptionParser.new do |this|
|
242
|
+
this.on '-f', '--foo', <<~begin do
|
243
|
+
description of --foo
|
244
|
+
can go multiple lines
|
245
|
+
begin
|
246
|
+
# dealing with --foo
|
247
|
+
end
|
248
|
+
end
|
249
|
+
```
|
250
|
+
|
251
|
+
- When line-wrapping a "fluent" long method chain, I prefer using backslash, newline, space, then dot. Backslashes can in fact be omitted grammar-wise, but I prefer placing them because a dot at a beginning of a line is almost impossible to find at sight.
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
complex_expression \
|
255
|
+
.to_enum(:something) \
|
256
|
+
.lazy \
|
257
|
+
.filter {|i| i.something } \
|
258
|
+
.slice_before {|i| i.something } \
|
259
|
+
.map {|a| a.something } \
|
260
|
+
.take_while {|a| a.something } \
|
261
|
+
.uniq
|
262
|
+
```
|
263
|
+
|
264
|
+
- You might want to consider refactoring before writing this.
|
265
|
+
|
266
|
+
## Misc
|
267
|
+
|
268
|
+
### DO
|
269
|
+
|
270
|
+
- All ruby scripts _SHOULD_ pass `ruby -w`.
|
271
|
+
- All ruby scripts _SHOULD_ pass `rake yard`.
|
272
|
+
|
273
|
+
### DON'T
|
274
|
+
|
275
|
+
- Don't take `rake rubocop` as a canon.
|
276
|
+
|
277
|
+
[RFC 2119]:https://tools.ietf.org/html/rfc2119
|
278
|
+
[RFC 3629]: https://tools.ietf.org/html/rfc3629
|
279
|
+
[markdown]: http://commonmark.org
|
280
|
+
[YARD]: http://yardoc.org
|
281
|
+
[1]: http://unicode.org/charts/PDF/U0000.pdf
|
282
|
+
[2]: https://en.wikipedia.org/wiki/Sentence_spacing
|
283
|
+
[Feature #6739]: https://bugs.ruby-lang.org/issues/6739
|
284
|
+
[Feature #10042]: https://bugs.ruby-lang.org/issues/10042
|