reek 4.4.0 → 4.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +41 -4
- data/README.md +15 -3
- data/defaults.reek +1 -1
- data/docs/Basic-Smell-Options.md +2 -2
- data/docs/Code-Smells.md +4 -0
- data/docs/How-To-Write-New-Detectors.md +116 -0
- data/docs/How-reek-works-internally.md +3 -4
- data/docs/Instance-Variable-Assumption.md +134 -0
- data/docs/Simulated-Polymorphism.md +1 -1
- data/docs/Smell-Suppression.md +6 -6
- data/docs/{style-guide.md → Style-Guide.md} +0 -0
- data/docs/Unused-Private-Method.md +1 -1
- data/docs/YAML-Reports.md +0 -18
- data/features/configuration_files/directory_specific_directives.feature +4 -4
- data/features/configuration_files/unused_private_method.feature +2 -2
- data/features/samples.feature +122 -117
- data/features/smells/subclassed_from_core_class.feature +1 -1
- data/lib/reek/code_comment.rb +13 -4
- data/lib/reek/context/code_context.rb +1 -0
- data/lib/reek/examiner.rb +24 -27
- data/lib/reek/smells/class_variable.rb +1 -1
- data/lib/reek/smells/control_parameter.rb +1 -1
- data/lib/reek/smells/data_clump.rb +1 -1
- data/lib/reek/smells/duplicate_method_call.rb +1 -1
- data/lib/reek/smells/feature_envy.rb +1 -1
- data/lib/reek/smells/instance_variable_assumption.rb +1 -1
- data/lib/reek/smells/prima_donna_method.rb +1 -1
- data/lib/reek/smells/repeated_conditional.rb +1 -1
- data/lib/reek/smells/smell_detector.rb +5 -14
- data/lib/reek/smells/smell_repository.rb +1 -5
- data/lib/reek/smells/smell_warning.rb +6 -8
- data/lib/reek/smells/subclassed_from_core_class.rb +1 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +22 -12
- data/lib/reek/smells/unused_private_method.rb +1 -1
- data/lib/reek/spec.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +12 -8
- data/lib/reek/version.rb +1 -1
- data/spec/reek/code_comment_spec.rb +13 -5
- data/spec/reek/examiner_spec.rb +2 -2
- data/spec/reek/smells/attribute_spec.rb +91 -78
- data/spec/reek/smells/boolean_parameter_spec.rb +72 -64
- data/spec/reek/smells/class_variable_spec.rb +81 -68
- data/spec/reek/smells/control_parameter_spec.rb +101 -141
- data/spec/reek/smells/data_clump_spec.rb +94 -149
- data/spec/reek/smells/duplicate_method_call_spec.rb +98 -85
- data/spec/reek/smells/feature_envy_spec.rb +164 -183
- data/spec/reek/smells/instance_variable_assumption_spec.rb +51 -147
- data/spec/reek/smells/irresponsible_module_spec.rb +153 -170
- data/spec/reek/smells/long_parameter_list_spec.rb +44 -88
- data/spec/reek/smells/long_yield_list_spec.rb +41 -41
- data/spec/reek/smells/manual_dispatch_spec.rb +36 -18
- data/spec/reek/smells/module_initialize_spec.rb +31 -33
- data/spec/reek/smells/nested_iterators_spec.rb +189 -183
- data/spec/reek/smells/nil_check_spec.rb +48 -37
- data/spec/reek/smells/prima_donna_method_spec.rb +41 -26
- data/spec/reek/smells/repeated_conditional_spec.rb +75 -87
- data/spec/reek/smells/smell_warning_spec.rb +7 -0
- data/spec/reek/smells/subclassed_from_core_class_spec.rb +37 -112
- data/spec/reek/smells/too_many_constants_spec.rb +109 -199
- data/spec/reek/smells/too_many_instance_variables_spec.rb +105 -128
- data/spec/reek/smells/too_many_methods_spec.rb +38 -62
- data/spec/reek/smells/too_many_statements_spec.rb +69 -45
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +16 -29
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +24 -37
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +55 -60
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +108 -95
- data/spec/reek/smells/unused_parameters_spec.rb +73 -49
- data/spec/reek/smells/unused_private_method_spec.rb +97 -50
- data/spec/reek/smells/utility_function_spec.rb +130 -188
- data/spec/reek/spec/should_reek_of_spec.rb +2 -2
- metadata +6 -7
- data/lib/reek/cli/warning_collector.rb +0 -27
- data/spec/reek/cli/warning_collector_spec.rb +0 -25
- data/spec/reek/smells/smell_detector_shared.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f4239287ce5d453034915801d47bd07738e0a09
|
4
|
+
data.tar.gz: 717f8ac8b8a9e0093a4aaa2ee9c5f739fd27be57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccbb4be4cf7bb2d47ce72f5fd7d709ca3b3b4e49b95253aa549a14d62a7468a176c9b10cb1d21da9667963791c3f8eca66137e0f2dd03bd5507e65c94deb6953
|
7
|
+
data.tar.gz: 90eb9358f3f66271fa0a568e4582f9d473911723730a30e1b9de7771e5f79381832be59c3d511ddae81c614d772d67a6e49a07ddece6de756f482663976ee5ea
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 4.4.1 (2016-09-13)
|
4
|
+
|
5
|
+
* (troessner) Quote names in smell detector messages
|
6
|
+
* (troessner) Make our CodeComment regex more lenient
|
7
|
+
* (troessner) Fix UncommunicativeVariableName does not take regex configuration into account
|
8
|
+
|
3
9
|
## 4.4.0 (2016-08-24)
|
4
10
|
|
5
11
|
* (waldyr) Add ignored nodes parameter to local_nodes
|
data/CONTRIBUTING.md
CHANGED
@@ -27,7 +27,9 @@ version, Ruby platform (MRI, JRuby, etc.), operating system.
|
|
27
27
|
Try to provide a minimal example that reproduces the issue.
|
28
28
|
Extra kudos if you can write it as a failing test. :)
|
29
29
|
|
30
|
-
##
|
30
|
+
## Contribute features, bugfixes, documentation
|
31
|
+
|
32
|
+
### Getting started
|
31
33
|
|
32
34
|
Fork Reek, then clone it, make sure you have
|
33
35
|
[Bundler](http://bundler.io) installed, install dependencies
|
@@ -47,17 +49,52 @@ Once you’re sure your copy of Reek works create your own feature branch from o
|
|
47
49
|
git checkout -b your_feature_or_fix_name
|
48
50
|
```
|
49
51
|
|
50
|
-
Make sure you have read our [style guide](docs/
|
52
|
+
Make sure you have read our [style guide](docs/Style-Guide.md) before you
|
51
53
|
start contributing.
|
52
54
|
|
53
55
|
Then start hacking and add new tests which make sure that your new feature works or
|
54
56
|
demonstrate that your fix was needed.
|
57
|
+
|
58
|
+
### Tests
|
59
|
+
|
55
60
|
Reek is using [Rspec](http://rspec.info/) for unit and functional testing and [cucumber]() for integration tests.
|
56
61
|
|
57
62
|
When it comes to Rspec we're trying to follow [betterspecs](http://betterspecs.org/).
|
58
|
-
|
63
|
+
We're not using Rspec's [shared examples](https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples) because we find
|
64
|
+
them rather harming than helpful.
|
65
|
+
You can find an excellent cheat sheet on how to write idiomatic Rspec [here](http://www.rubypigeon.com/posts/rspec-core-cheat-sheet).
|
66
|
+
|
67
|
+
**Spec naming conventions**
|
68
|
+
|
69
|
+
We do not use the popular "foo" / "bar" naming when it comes to the question "how to come up with good example names?".
|
70
|
+
Instead, we use the [military alphabet](https://en.wikipedia.org/wiki/NATO_phonetic_alphabet) in ascending order
|
71
|
+
which means that we would write this
|
72
|
+
|
73
|
+
```Ruby
|
74
|
+
class Foo
|
75
|
+
def bar(baz)
|
76
|
+
baz.quux
|
77
|
+
end
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
rather like this:
|
82
|
+
|
83
|
+
```Ruby
|
84
|
+
class Alfa
|
85
|
+
def bravo(charlie)
|
86
|
+
charlie.delta
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
### How to write new smell detectors
|
92
|
+
|
93
|
+
Please see [our separate guide](docs/How-To-Write-New-Detectors.md) for this.
|
94
|
+
|
95
|
+
### Finishing up
|
59
96
|
|
60
|
-
We
|
97
|
+
We care a lot about [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
61
98
|
|
62
99
|
Once you’re happy with your feature / fix – or want to
|
63
100
|
share it as a work-in-progress and request comments – once
|
data/README.md
CHANGED
@@ -210,15 +210,27 @@ Reek currently includes checks for some aspects of
|
|
210
210
|
and more. See the [Code Smells](docs/Code-Smells.md)
|
211
211
|
for up to date details of exactly what Reek will check in your code.
|
212
212
|
|
213
|
-
|
213
|
+
**Special configuration for controversial detectors:**
|
214
|
+
|
215
|
+
[Unused Private Method](docs/Unused-Private-Method.md) is disabled by default
|
214
216
|
because it is [kind of controversial](https://github.com/troessner/reek/issues/844) which means
|
215
|
-
you have to explicitly activate in your configuration via
|
217
|
+
you have to explicitly activate it in your configuration via
|
216
218
|
|
217
219
|
```Yaml
|
218
220
|
UnusedPrivateMethod:
|
219
221
|
enabled: true
|
220
222
|
```
|
221
223
|
|
224
|
+
[Utility Function](docs/Utility-Function.md) is a [controversial detector](https://github.com/troessner/reek/issues/681)
|
225
|
+
as well that can turn out to be really unforgiving.
|
226
|
+
As a consequence, we made it possible to disable it for non-public methods like this:
|
227
|
+
|
228
|
+
```Yaml
|
229
|
+
---
|
230
|
+
UtilityFunction:
|
231
|
+
public_methods_only: true
|
232
|
+
```
|
233
|
+
|
222
234
|
## Configuration
|
223
235
|
|
224
236
|
### Command-line interface
|
@@ -356,7 +368,7 @@ end
|
|
356
368
|
You can even pass in smell specific configuration settings:
|
357
369
|
|
358
370
|
```Ruby
|
359
|
-
# :reek:NestedIterators
|
371
|
+
# :reek:NestedIterators { max_allowed_nesting: 2 }
|
360
372
|
def smelly_method foo
|
361
373
|
foo.each {|bar| bar.each {|baz| baz.qux}}
|
362
374
|
end
|
data/defaults.reek
CHANGED
data/docs/Basic-Smell-Options.md
CHANGED
@@ -19,7 +19,7 @@ exclusions for each smell.
|
|
19
19
|
To stop Reek reporting smells in any method called `write` you might create a configuration file containing this:
|
20
20
|
|
21
21
|
```yaml
|
22
|
-
|
22
|
+
DuplicateMethodCall:
|
23
23
|
exclude:
|
24
24
|
- write
|
25
25
|
```
|
@@ -27,7 +27,7 @@ ControlCouple:
|
|
27
27
|
Or a little more sophisticated using a Ruby regex like this:
|
28
28
|
|
29
29
|
```yaml
|
30
|
-
|
30
|
+
DuplicateMethodCall:
|
31
31
|
exclude:
|
32
32
|
- !ruby/regexp /write/
|
33
33
|
```
|
data/docs/Code-Smells.md
CHANGED
@@ -11,8 +11,10 @@ Reek currently includes checks for the following smells:
|
|
11
11
|
* [Control Parameter](Control-Parameter.md)
|
12
12
|
* [Data Clump](Data-Clump.md)
|
13
13
|
* [Duplicate Method Call](Duplicate-Method-Call.md)
|
14
|
+
* [Instance Variable Assumption](Instance-Variable-Assumption.md)
|
14
15
|
* [Irresponsible Module](Irresponsible-Module.md)
|
15
16
|
* [Large Class](Large-Class.md), including
|
17
|
+
* [Too Many Constants](Too-Many-Constants.md)
|
16
18
|
* [Too Many Instance Variables](Too-Many-Instance-Variables.md)
|
17
19
|
* [Too Many Methods](Too-Many-Methods.md)
|
18
20
|
* [Long Parameter List](Long-Parameter-List.md), and its special case [Long Yield List](Long-Yield-List.md)
|
@@ -23,8 +25,10 @@ Reek currently includes checks for the following smells:
|
|
23
25
|
* [Nested Iterators](Nested-Iterators.md)
|
24
26
|
* [Prima-Donna-Method](Prima-Donna-Method.md)
|
25
27
|
* [Simulated Polymorphism](Simulated-Polymorphism.md), including
|
28
|
+
* [Manual Dispatch](Manual-Dispatch.md)
|
26
29
|
* [Nil Check](Nil-Check.md)
|
27
30
|
* [Repeated Conditional](Repeated-Conditional.md)
|
31
|
+
* [Subclassed From Core Class](Subclassed-From-Core-Class.md)
|
28
32
|
* [Too Many Statements](Too-Many-Statements.md)
|
29
33
|
* [Uncommunicative Name](Uncommunicative-Name.md), including
|
30
34
|
* [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
|
@@ -0,0 +1,116 @@
|
|
1
|
+
## How to write new detectors
|
2
|
+
|
3
|
+
### Outline what you have in mind
|
4
|
+
|
5
|
+
Before starting to code you should discuss the overall idea for your new smell detector with
|
6
|
+
us in a corresponding github issue.
|
7
|
+
We all should have a solid understanding of what this detector actually reports, the edgecases
|
8
|
+
it covers and the overall rationale behind it.
|
9
|
+
|
10
|
+
### Structure
|
11
|
+
|
12
|
+
All smell detectors reside in `lib/reek/smells` and have the following base structure:
|
13
|
+
|
14
|
+
```Ruby
|
15
|
+
require_relative 'smell_detector'
|
16
|
+
require_relative 'smell_warning'
|
17
|
+
|
18
|
+
module Reek
|
19
|
+
module Smells
|
20
|
+
#
|
21
|
+
# Here goes your introduction for this detector.
|
22
|
+
#
|
23
|
+
# See {file:docs/Your-Detector.md} for details.
|
24
|
+
class YourDetector < SmellDetector
|
25
|
+
def self.contexts
|
26
|
+
[:class] # In case you're operating on class contexts only - just an example.
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Here you should document what you expect "ctx" to look like.
|
31
|
+
#
|
32
|
+
# @return [Array<SmellWarning>]
|
33
|
+
#
|
34
|
+
def sniff(ctx)
|
35
|
+
# "found_smells" below is just an abstraction for
|
36
|
+
# "find the smells in question" and iteratore over them.
|
37
|
+
# This can just be a method but it can also be a more sophisticated set up.
|
38
|
+
# Check out other smell detectors to get a feeling for what to do here.
|
39
|
+
found_smells(ctx).map do |smell|
|
40
|
+
# "smell_warning" is defined in SmellDetector and should be used by you
|
41
|
+
# to construct smell warnings
|
42
|
+
smell_warning(
|
43
|
+
context: ctx,
|
44
|
+
lines: [], # lines on which the smell was detected
|
45
|
+
message: "...", # the message that is printed on STDOUT
|
46
|
+
# whatever you interpolate into the "message" should go into
|
47
|
+
# parameters below - if you do not interpolate anything you
|
48
|
+
# can omit this
|
49
|
+
parameters: { })
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Here goes everything you need for finding smells.
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
### Documentation
|
63
|
+
|
64
|
+
* Above every `SmellDetector::sniff` method it should be documented what the expected AST is
|
65
|
+
* Every detector should have a separate documentation page in /docs. You can
|
66
|
+
take any arbitrary existing smell detector documentation page as template (since
|
67
|
+
they all have the same structure already)
|
68
|
+
* The detector should be listed under [Code Smells](docs/Code-Smells.md)
|
69
|
+
|
70
|
+
### Rspec examples
|
71
|
+
|
72
|
+
All smell detector specs start out with 2 generic examples like below - the second one
|
73
|
+
only if it makes sense.
|
74
|
+
Here's what it looks like for `UncommunicativeVariableName`:
|
75
|
+
|
76
|
+
```Ruby
|
77
|
+
it 'reports the right values' do
|
78
|
+
src = <<-EOS
|
79
|
+
def alfa
|
80
|
+
bravo = 5
|
81
|
+
end
|
82
|
+
EOS
|
83
|
+
|
84
|
+
expect(src).to reek_of(:UncommunicativeVariableName,
|
85
|
+
lines: [2],
|
86
|
+
context: 'alfa',
|
87
|
+
message: "has the variable name 'bravo'",
|
88
|
+
source: 'string',
|
89
|
+
name: 'bravo')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'does count all occurences' do
|
93
|
+
src = <<-EOS
|
94
|
+
def alfa
|
95
|
+
bravo = 3
|
96
|
+
charlie = 7
|
97
|
+
end
|
98
|
+
EOS
|
99
|
+
|
100
|
+
expect(src).to reek_of(:UncommunicativeVariableName,
|
101
|
+
lines: [2],
|
102
|
+
name: 'bravo')
|
103
|
+
expect(src).to reek_of(:UncommunicativeVariableName,
|
104
|
+
lines: [3],
|
105
|
+
name: 'charlie')
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
The following examples should then cover the detector specific features.
|
110
|
+
|
111
|
+
### Cucumber features
|
112
|
+
|
113
|
+
We are trying to write as few Cucumber features as possible.
|
114
|
+
Normally, there should be no need to write a new feature for a new smell detector.
|
115
|
+
If you feel like this is necessary in this case, please discuss this with us via
|
116
|
+
github issue or in your work-in-progress pull request before doing anything.
|
@@ -25,7 +25,7 @@
|
|
25
25
|
| |
|
26
26
|
| |
|
27
27
|
ReekCommand (cli/reek_command) |
|
28
|
-
* uses a reporter (report/report)
|
28
|
+
* uses a reporter (report/report) |
|
29
29
|
* uses a SourceLocator (source/source_locator) |
|
30
30
|
/ | \ |
|
31
31
|
/ | \ |
|
@@ -41,9 +41,8 @@
|
|
41
41
|
* generates the AST out of the given source
|
42
42
|
* adorns the generated AST via a TreeDresser (core/tree_dresser)
|
43
43
|
* initializes a SmellRepository with all relevant smells (smells/smell_repository)
|
44
|
-
* initializes a WarningCollector (cli/warning_collector)
|
45
44
|
* builds a tree of Contexts using ContextBuilder
|
46
|
-
*
|
45
|
+
* tells the SmellRepository above to run each of its smell detectors above on each of the contexts
|
47
46
|
/ | \
|
48
47
|
/ | \
|
49
48
|
/ | \
|
@@ -51,7 +50,7 @@
|
|
51
50
|
\ | /
|
52
51
|
\ | /
|
53
52
|
\ | /
|
54
|
-
|
53
|
+
SmellRepository
|
55
54
|
|
|
56
55
|
|
|
57
56
|
|
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# Instance Variable Assumption
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
Classes should not assume that instance variables are set or present outside of the current class definition.
|
6
|
+
|
7
|
+
Good:
|
8
|
+
|
9
|
+
```Ruby
|
10
|
+
class Foo
|
11
|
+
def initialize
|
12
|
+
@bar = :foo
|
13
|
+
end
|
14
|
+
|
15
|
+
def foo?
|
16
|
+
@bar == :foo
|
17
|
+
end
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Good as well:
|
22
|
+
|
23
|
+
```Ruby
|
24
|
+
class Foo
|
25
|
+
def foo?
|
26
|
+
bar == :foo
|
27
|
+
end
|
28
|
+
|
29
|
+
def bar
|
30
|
+
@bar ||= :foo
|
31
|
+
end
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Bad:
|
36
|
+
|
37
|
+
```Ruby
|
38
|
+
class Foo
|
39
|
+
def go_foo!
|
40
|
+
@bar = :foo
|
41
|
+
end
|
42
|
+
|
43
|
+
def foo?
|
44
|
+
@bar == :foo
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
## Example
|
50
|
+
|
51
|
+
Running Reek on:
|
52
|
+
|
53
|
+
```Ruby
|
54
|
+
class Dummy
|
55
|
+
def test
|
56
|
+
@ivar
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
would report:
|
62
|
+
|
63
|
+
```Bash
|
64
|
+
[1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar [https://github.com/troessner/reek/blob/master/docs/Instance-Variable-Assumption.md]
|
65
|
+
```
|
66
|
+
|
67
|
+
Note that this example would trigger this smell warning as well:
|
68
|
+
|
69
|
+
```Ruby
|
70
|
+
class Parent
|
71
|
+
def initialize(omg)
|
72
|
+
@omg = omg
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Child < Parent
|
77
|
+
def foo
|
78
|
+
@omg
|
79
|
+
end
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
The way to address the smell warning is that you should create an `attr_reader` to use `@omg` in the subclass and not access `@omg` directly like this:
|
84
|
+
|
85
|
+
```Ruby
|
86
|
+
class Parent
|
87
|
+
attr_reader :omg
|
88
|
+
|
89
|
+
def initialize(omg)
|
90
|
+
@omg = omg
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Child < Parent
|
95
|
+
def foo
|
96
|
+
omg
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
Directly accessing instance variables is considered a smell because it [breaks encapsulation](http://designisrefactoring.com/2015/03/29/organizing-data-self-encapsulation/) and makes it harder to reason about code.
|
102
|
+
|
103
|
+
If you don't want to expose those methods as public API just make them private like this:
|
104
|
+
|
105
|
+
```Ruby
|
106
|
+
class Parent
|
107
|
+
def initialize(omg)
|
108
|
+
@omg = omg
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
attr_reader :omg
|
113
|
+
end
|
114
|
+
|
115
|
+
class Child < Parent
|
116
|
+
def foo
|
117
|
+
omg
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
|
123
|
+
## Current Support in Reek
|
124
|
+
|
125
|
+
An instance variable must:
|
126
|
+
|
127
|
+
* be set in the constructor
|
128
|
+
* or be accessed through a method with lazy initialization / memoization.
|
129
|
+
|
130
|
+
If not, _Instance Variable Assumption_ will be reported.
|
131
|
+
|
132
|
+
## Configuration
|
133
|
+
|
134
|
+
_Instance Variable Assumption_ supports the [Basic Smell Options](Basic-Smell-Options.md).
|