reek 6.0.1 → 6.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/ruby.yml +52 -0
  4. data/.rubocop.yml +2 -20
  5. data/.rubocop_todo.yml +27 -20
  6. data/CHANGELOG.md +22 -0
  7. data/CONTRIBUTING.md +3 -0
  8. data/Dockerfile +1 -1
  9. data/Gemfile +6 -6
  10. data/README.md +1 -1
  11. data/bin/code_climate_reek +2 -3
  12. data/lib/reek.rb +1 -0
  13. data/lib/reek/ast/ast_node_class_map.rb +1 -1
  14. data/lib/reek/ast/node.rb +1 -1
  15. data/lib/reek/cli/options.rb +1 -1
  16. data/lib/reek/configuration/app_configuration.rb +4 -3
  17. data/lib/reek/configuration/directory_directives.rb +2 -2
  18. data/lib/reek/configuration/excluded_paths.rb +2 -1
  19. data/lib/reek/context/code_context.rb +1 -1
  20. data/lib/reek/context/module_context.rb +3 -1
  21. data/lib/reek/context/refinement_context.rb +16 -0
  22. data/lib/reek/context_builder.rb +16 -2
  23. data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
  24. data/lib/reek/report/code_climate/code_climate_formatter.rb +1 -3
  25. data/lib/reek/smell_detectors/base_detector.rb +1 -1
  26. data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
  27. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
  28. data/lib/reek/smell_warning.rb +2 -3
  29. data/lib/reek/source/source_locator.rb +14 -13
  30. data/lib/reek/version.rb +1 -1
  31. data/reek.gemspec +14 -3
  32. metadata +29 -232
  33. data/.travis.yml +0 -36
  34. data/docs/API.md +0 -174
  35. data/docs/Attribute.md +0 -39
  36. data/docs/Basic-Smell-Options.md +0 -85
  37. data/docs/Boolean-Parameter.md +0 -54
  38. data/docs/Class-Variable.md +0 -40
  39. data/docs/Code-Smells.md +0 -39
  40. data/docs/Command-Line-Options.md +0 -119
  41. data/docs/Control-Couple.md +0 -26
  42. data/docs/Control-Parameter.md +0 -32
  43. data/docs/Data-Clump.md +0 -46
  44. data/docs/Duplicate-Method-Call.md +0 -264
  45. data/docs/Feature-Envy.md +0 -93
  46. data/docs/How-To-Write-New-Detectors.md +0 -132
  47. data/docs/How-reek-works-internally.md +0 -114
  48. data/docs/Instance-Variable-Assumption.md +0 -163
  49. data/docs/Irresponsible-Module.md +0 -47
  50. data/docs/Large-Class.md +0 -16
  51. data/docs/Long-Parameter-List.md +0 -39
  52. data/docs/Long-Yield-List.md +0 -37
  53. data/docs/Manual-Dispatch.md +0 -30
  54. data/docs/Missing-Safe-Method.md +0 -92
  55. data/docs/Module-Initialize.md +0 -62
  56. data/docs/Nested-Iterators.md +0 -59
  57. data/docs/Nil-Check.md +0 -47
  58. data/docs/RSpec-matchers.md +0 -129
  59. data/docs/Rake-Task.md +0 -66
  60. data/docs/Reek-4-to-Reek-5-migration.md +0 -188
  61. data/docs/Reek-Driven-Development.md +0 -46
  62. data/docs/Repeated-Conditional.md +0 -47
  63. data/docs/Simulated-Polymorphism.md +0 -16
  64. data/docs/Smell-Suppression.md +0 -96
  65. data/docs/Style-Guide.md +0 -19
  66. data/docs/Subclassed-From-Core-Class.md +0 -79
  67. data/docs/Too-Many-Constants.md +0 -37
  68. data/docs/Too-Many-Instance-Variables.md +0 -43
  69. data/docs/Too-Many-Methods.md +0 -56
  70. data/docs/Too-Many-Statements.md +0 -54
  71. data/docs/Uncommunicative-Method-Name.md +0 -94
  72. data/docs/Uncommunicative-Module-Name.md +0 -92
  73. data/docs/Uncommunicative-Name.md +0 -18
  74. data/docs/Uncommunicative-Parameter-Name.md +0 -90
  75. data/docs/Uncommunicative-Variable-Name.md +0 -96
  76. data/docs/Unused-Parameters.md +0 -28
  77. data/docs/Unused-Private-Method.md +0 -101
  78. data/docs/Utility-Function.md +0 -56
  79. data/docs/Versioning-Policy.md +0 -7
  80. data/docs/YAML-Reports.md +0 -93
  81. data/docs/defaults.reek.yml +0 -129
  82. data/docs/templates/default/docstring/html/public_api_marker.erb +0 -3
  83. data/docs/templates/default/docstring/setup.rb +0 -37
  84. data/docs/templates/default/fulldoc/html/css/common.css +0 -1
  85. data/docs/yard_plugin.rb +0 -17
  86. data/features/command_line_interface/basic_usage.feature +0 -15
  87. data/features/command_line_interface/options.feature +0 -123
  88. data/features/command_line_interface/show_progress.feature +0 -33
  89. data/features/command_line_interface/smell_selection.feature +0 -15
  90. data/features/command_line_interface/smells_count.feature +0 -38
  91. data/features/command_line_interface/stdin.feature +0 -65
  92. data/features/configuration_files/accept_setting.feature +0 -87
  93. data/features/configuration_files/directory_specific_directives.feature +0 -274
  94. data/features/configuration_files/exclude_directives.feature +0 -35
  95. data/features/configuration_files/exclude_paths_directives.feature +0 -42
  96. data/features/configuration_files/masking_smells.feature +0 -94
  97. data/features/configuration_files/mix_accept_reject_setting.feature +0 -84
  98. data/features/configuration_files/reject_setting.feature +0 -89
  99. data/features/configuration_files/schema_validation.feature +0 -59
  100. data/features/configuration_files/show_configuration_file.feature +0 -44
  101. data/features/configuration_files/unused_private_method.feature +0 -68
  102. data/features/configuration_loading.feature +0 -91
  103. data/features/configuration_via_source_comments/erroneous_source_comments.feature +0 -68
  104. data/features/configuration_via_source_comments/well_formed_source_comments.feature +0 -116
  105. data/features/locales.feature +0 -32
  106. data/features/programmatic_access.feature +0 -41
  107. data/features/rake_task/rake_task.feature +0 -138
  108. data/features/reports/codeclimate.feature +0 -59
  109. data/features/reports/json.feature +0 -59
  110. data/features/reports/reports.feature +0 -219
  111. data/features/reports/yaml.feature +0 -52
  112. data/features/rspec_matcher.feature +0 -41
  113. data/features/samples.feature +0 -305
  114. data/features/step_definitions/.rubocop.yml +0 -5
  115. data/features/step_definitions/reek_steps.rb +0 -102
  116. data/features/step_definitions/sample_file_steps.rb +0 -63
  117. data/features/support/env.rb +0 -33
  118. data/features/todo_list.feature +0 -108
  119. data/samples/checkstyle.xml +0 -7
  120. data/samples/clean_source/clean.rb +0 -6
  121. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +0 -29
  122. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +0 -30
  123. data/samples/configuration/corrupt.reek +0 -1
  124. data/samples/configuration/empty.reek +0 -0
  125. data/samples/configuration/full_configuration.reek +0 -13
  126. data/samples/configuration/full_mask.reek +0 -6
  127. data/samples/configuration/home/home.reek.yml +0 -4
  128. data/samples/configuration/partial_mask.reek +0 -4
  129. data/samples/configuration/regular_configuration/.reek.yml +0 -4
  130. data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
  131. data/samples/configuration/with_excluded_paths.reek +0 -5
  132. data/samples/no_config_file/.keep +0 -0
  133. data/samples/paths.rb +0 -5
  134. data/samples/smelly_source/inline.rb +0 -704
  135. data/samples/smelly_source/optparse.rb +0 -1788
  136. data/samples/smelly_source/redcloth.rb +0 -1130
  137. data/samples/smelly_source/ruby.rb +0 -368
  138. data/samples/smelly_source/smelly.rb +0 -7
  139. data/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -5
  140. data/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -2
  141. data/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -6
  142. data/samples/source_with_exclude_paths/nested/uncommunicative_variable_name.rb +0 -6
  143. data/samples/source_with_hidden_directories/.hidden/hidden.rb +0 -1
  144. data/samples/source_with_hidden_directories/not_hidden.rb +0 -1
  145. data/samples/source_with_non_ruby_files/gibberish +0 -1
  146. data/samples/source_with_non_ruby_files/python_source.py +0 -1
  147. data/samples/source_with_non_ruby_files/ruby.rb +0 -6
  148. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +0 -17
  149. data/spec/quality/documentation_spec.rb +0 -40
  150. data/spec/quality/reek_source_spec.rb +0 -11
  151. data/spec/reek/ast/node_spec.rb +0 -211
  152. data/spec/reek/ast/object_refs_spec.rb +0 -83
  153. data/spec/reek/ast/reference_collector_spec.rb +0 -47
  154. data/spec/reek/ast/sexp_extensions_spec.rb +0 -498
  155. data/spec/reek/cli/application_spec.rb +0 -168
  156. data/spec/reek/cli/command/report_command_spec.rb +0 -44
  157. data/spec/reek/cli/command/todo_list_command_spec.rb +0 -86
  158. data/spec/reek/cli/options_spec.rb +0 -51
  159. data/spec/reek/cli/silencer_spec.rb +0 -28
  160. data/spec/reek/code_comment_spec.rb +0 -184
  161. data/spec/reek/configuration/app_configuration_spec.rb +0 -195
  162. data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -230
  163. data/spec/reek/configuration/default_directive_spec.rb +0 -13
  164. data/spec/reek/configuration/directory_directives_spec.rb +0 -122
  165. data/spec/reek/configuration/excluded_paths_spec.rb +0 -16
  166. data/spec/reek/configuration/rake_task_converter_spec.rb +0 -33
  167. data/spec/reek/configuration/schema_validator_spec.rb +0 -165
  168. data/spec/reek/context/code_context_spec.rb +0 -192
  169. data/spec/reek/context/ghost_context_spec.rb +0 -60
  170. data/spec/reek/context/method_context_spec.rb +0 -72
  171. data/spec/reek/context/module_context_spec.rb +0 -55
  172. data/spec/reek/context/root_context_spec.rb +0 -12
  173. data/spec/reek/context/statement_counter_spec.rb +0 -24
  174. data/spec/reek/context_builder_spec.rb +0 -457
  175. data/spec/reek/detector_repository_spec.rb +0 -22
  176. data/spec/reek/documentation_link_spec.rb +0 -20
  177. data/spec/reek/errors/base_error_spec.rb +0 -13
  178. data/spec/reek/examiner_spec.rb +0 -309
  179. data/spec/reek/logging_error_handler_spec.rb +0 -24
  180. data/spec/reek/rake/task_spec.rb +0 -56
  181. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +0 -22
  182. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +0 -126
  183. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +0 -51
  184. data/spec/reek/report/code_climate/code_climate_report_spec.rb +0 -56
  185. data/spec/reek/report/html_report_spec.rb +0 -19
  186. data/spec/reek/report/json_report_spec.rb +0 -58
  187. data/spec/reek/report/location_formatter_spec.rb +0 -32
  188. data/spec/reek/report/progress_formatter_spec.rb +0 -68
  189. data/spec/reek/report/text_report_spec.rb +0 -89
  190. data/spec/reek/report/xml_report_spec.rb +0 -24
  191. data/spec/reek/report/yaml_report_spec.rb +0 -55
  192. data/spec/reek/report_spec.rb +0 -28
  193. data/spec/reek/smell_configuration_spec.rb +0 -56
  194. data/spec/reek/smell_detectors/attribute_spec.rb +0 -197
  195. data/spec/reek/smell_detectors/base_detector_spec.rb +0 -50
  196. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +0 -93
  197. data/spec/reek/smell_detectors/class_variable_spec.rb +0 -106
  198. data/spec/reek/smell_detectors/control_parameter_spec.rb +0 -300
  199. data/spec/reek/smell_detectors/data_clump_spec.rb +0 -134
  200. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +0 -211
  201. data/spec/reek/smell_detectors/feature_envy_spec.rb +0 -295
  202. data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +0 -96
  203. data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -226
  204. data/spec/reek/smell_detectors/long_parameter_list_spec.rb +0 -61
  205. data/spec/reek/smell_detectors/long_yield_list_spec.rb +0 -49
  206. data/spec/reek/smell_detectors/manual_dispatch_spec.rb +0 -75
  207. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +0 -68
  208. data/spec/reek/smell_detectors/module_initialize_spec.rb +0 -77
  209. data/spec/reek/smell_detectors/nested_iterators_spec.rb +0 -333
  210. data/spec/reek/smell_detectors/nil_check_spec.rb +0 -100
  211. data/spec/reek/smell_detectors/repeated_conditional_spec.rb +0 -100
  212. data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -77
  213. data/spec/reek/smell_detectors/too_many_constants_spec.rb +0 -144
  214. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +0 -132
  215. data/spec/reek/smell_detectors/too_many_methods_spec.rb +0 -54
  216. data/spec/reek/smell_detectors/too_many_statements_spec.rb +0 -90
  217. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +0 -78
  218. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +0 -78
  219. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +0 -147
  220. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +0 -201
  221. data/spec/reek/smell_detectors/unused_parameters_spec.rb +0 -114
  222. data/spec/reek/smell_detectors/unused_private_method_spec.rb +0 -205
  223. data/spec/reek/smell_detectors/utility_function_spec.rb +0 -293
  224. data/spec/reek/smell_warning_spec.rb +0 -137
  225. data/spec/reek/source/source_code_spec.rb +0 -79
  226. data/spec/reek/source/source_locator_spec.rb +0 -166
  227. data/spec/reek/spec/should_reek_of_spec.rb +0 -153
  228. data/spec/reek/spec/should_reek_only_of_spec.rb +0 -91
  229. data/spec/reek/spec/should_reek_spec.rb +0 -52
  230. data/spec/reek/spec/smell_matcher_spec.rb +0 -87
  231. data/spec/reek/tree_dresser_spec.rb +0 -46
  232. data/spec/spec_helper.rb +0 -110
  233. data/tasks/configuration.rake +0 -19
  234. data/tasks/console.rake +0 -5
  235. data/tasks/reek.rake +0 -6
  236. data/tasks/rubocop.rake +0 -11
  237. data/tasks/test.rake +0 -32
@@ -1,119 +0,0 @@
1
- # Command Line Options
2
-
3
- ## Introduction
4
-
5
- Reek follows standard Unix convention for passing arguments.
6
-
7
- Check out
8
-
9
- ```Bash
10
- reek -h
11
- ```
12
-
13
- for details.
14
-
15
- ## Telling Reek to use a specific configuration file
16
-
17
- In case your configuration file is not in the standard location (that would be your project directory or
18
- whatever directory you're running Reek from) you can specify a configuration file with the `-c` option
19
- like this:
20
-
21
- ```Bash
22
- reek -c /somewhere/on/your/filesystem/reek_config.yml lib/
23
- ```
24
-
25
- ## Telling Reek Which Code to Check
26
-
27
- Probably the most standard use case would be to check all Ruby files in the lib directory:
28
-
29
- ```Bash
30
- reek lib/*.rb
31
- ```
32
-
33
- In general, if any command-line argument is a directory, Reek searches that directory and all sub-directories for Ruby source files. Thus
34
-
35
- ```Bash
36
- reek lib
37
- ```
38
-
39
- would be equivalent to
40
-
41
- ```Bash
42
- reek lib/**/*.rb
43
- ```
44
-
45
- Occasionally you may want to quickly check a code snippet without going to the trouble of creating a file to hold it. You can pass the snippet directly to Reek's standard input:
46
-
47
- ```Bash
48
- echo "def x() true end" | reek
49
- ```
50
-
51
- To just check all Ruby files in the current directory, you can simply run it
52
- with no parameters:
53
-
54
- ```Bash
55
- reek
56
- ```
57
-
58
- ## Telling Reek Which Smells to Detect
59
-
60
- You can tell Reek to only check particular smells by using the `--smell`
61
- option and passing in the smell name.
62
-
63
- For example, to only check for [Utility Function](Utility-Function.md), you
64
- would use:
65
-
66
- ```Bash
67
- reek --smell UtilityFunction
68
- ```
69
-
70
- You can select several smells by repeating the `--smell` option like so:
71
-
72
- ```Bash
73
- reek --smell UtilityFunction --smell UncommunicativeMethodName
74
- ```
75
-
76
- ## Output options
77
-
78
- ### Output smell's line number
79
-
80
- By passing in a "-n" flag to the _reek_ command, the output will suppress the line numbers:
81
-
82
- ```Bash
83
- $ reek -n mess.rb
84
- ```
85
-
86
- ```
87
- mess.rb -- 2 warnings:
88
- x doesn't depend on instance state (UtilityFunction)
89
- x has the name 'x' (UncommunicativeMethodName)
90
- ```
91
-
92
- Otherwise line numbers will be shown as default at the beginning of each warning in square brackets:
93
-
94
- ```Bash
95
- $ reek mess.rb
96
- ```
97
-
98
- ```
99
- mess.rb -- 2 warnings:
100
- [2]:x doesn't depend on instance state (UtilityFunction)
101
- [2]:x has the name 'x' (UncommunicativeMethodName)
102
- ```
103
-
104
- ### Enable the verbose mode
105
-
106
- _reek_ has a verbose mode which you might find helpful as a beginner. "verbose" just means that behind each warning a helpful link will be displayed which leads directly to the corresponding _reek_ documentation page.
107
- This mode can be enabled via the "-U" or "--documentation" flag.
108
-
109
- So for instance, if your test file would smell of _ClassVariable_, this is what the _reek_ output would look like:
110
-
111
- ```Bash
112
- reek -U test.rb
113
- ```
114
- ```
115
- test.rb -- 1 warning:
116
- [2]:Dummy declares the class variable @@class_variable (ClassVariable) [https://github.com/troessner/reek/blob/master/docs/Class-Variable.md]
117
- ```
118
-
119
- Note the link at the end.
@@ -1,26 +0,0 @@
1
- # Control Couple
2
-
3
- ## Introduction
4
-
5
- Control coupling occurs when a method or block checks the value of a parameter
6
- in order to decide which execution path to take. The offending parameter is
7
- often called a _Control Couple_.
8
-
9
- Control Coupling is a kind of duplication, because the calling method already knows which path should be taken.
10
-
11
- Control Coupling reduces the code's flexibility by creating a dependency
12
- between the caller and callee: any change to the possible values of the
13
- controlling parameter must be reflected on both sides of the call. A _Control
14
- Couple_ also reveals a loss of simplicity: the called method probably has more
15
- than one responsibility, because it includes at least two different code paths.
16
-
17
- You can find a good write-up regarding this problem [here](https://solnic.codes/2012/04/11/get-rid-of-that-code-smell-control-couple/).
18
-
19
- ## Current Support in Reek
20
-
21
- Reek performs the following checks that fall in this category:
22
-
23
- * [Control-Parameter](Control-Parameter.md) - a method parameter or block
24
- parameter is the tested value in a conditional statement
25
- * [Boolean-Parameter](Boolean-Parameter.md) - a method parameter is defaulted
26
- to `true` or `false`.
@@ -1,32 +0,0 @@
1
- # Control Parameter
2
-
3
- ## Introduction
4
-
5
- _Control Parameter_ is a case of [Control Couple](Control-Couple.md).
6
-
7
- ## Example
8
-
9
- A simple example would be the `quoted` parameter in the following method:
10
-
11
- ```Ruby
12
- def write(quoted)
13
- if quoted
14
- write_quoted @value
15
- else
16
- write_unquoted @value
17
- end
18
- end
19
- ```
20
-
21
- Fixing those problems is out of the scope of this document but an easy solution
22
- could be to remove the `write` method altogether and to move the calls to
23
- `write_quoted` and `write_unquoted` to the caller of `write`.
24
-
25
- ## Current Support in Reek
26
-
27
- Reek warns about _Control Parameter_ when a method parameter or block parameter is
28
- the tested value in a conditional statement.
29
-
30
- ## Configuration
31
-
32
- _Control Parameter_ supports the [Basic Smell Options](Basic-Smell-Options.md).
data/docs/Data-Clump.md DELETED
@@ -1,46 +0,0 @@
1
- # Data Clump
2
-
3
- ## Introduction
4
-
5
- In general, a _Data Clump_ occurs when the same two or three items frequently
6
- appear together in classes and parameter lists, or when a group of instance
7
- variable names start or end with similar substrings.
8
-
9
- The recurrence of the items often means there is duplicate code spread around to handle them. There may be an abstraction missing from the code, making the system harder to understand.
10
-
11
- ## Example
12
-
13
- Given
14
-
15
- ```Ruby
16
- class Dummy
17
- def x(y1,y2); end
18
- def y(y1,y2); end
19
- def z(y1,y2); end
20
- end
21
- ```
22
-
23
- Reek would emit the following warning:
24
-
25
- ```
26
- test.rb -- 1 warning:
27
- [2, 3, 4]:Dummy takes parameters [y1, y2] to 3 methods (DataClump)
28
- ```
29
-
30
- A possible way to fix this problem (quoting from [Martin Fowler](http://martinfowler.com/bliki/DataClump.html)):
31
-
32
- > The first step is to replace data clumps with objects and use the objects whenever you see them. An immediate benefit is that you'll shrink some parameter lists. The interesting stuff happens as you begin to look for behavior to move into the new objects.
33
-
34
- ## Current Support in Reek
35
-
36
- Reek looks for a group of two or more parameters with the same names that are expected by three or more methods of a class.
37
-
38
- ## Configuration
39
-
40
- Reek's _Data Clump_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
41
-
42
- | Option | Value | Effect |
43
- | -----------------|-------------|---------|
44
- | `max_copies` | integer | The maximum number of methods that are permitted to take the same group of parameters. Defaults to 2. |
45
- | `min_clump_size` | integer | The smallest number of parameters that can be reported as a clump. Defaults to 2. |
46
-
@@ -1,264 +0,0 @@
1
- # Duplicate Method Call
2
-
3
- ## Introduction
4
-
5
- Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.
6
-
7
- Let's look at an example that is quite common in the Rails world:
8
-
9
- ```Ruby
10
- def not_production?
11
- Rails.env.development? || Rails.env.test?
12
- end
13
- ```
14
-
15
- While this duplicate usage of `Rails.env` might seem innocuous there are 2 problems with it:
16
-
17
- 1.) Efficiency
18
-
19
- ```Ruby
20
- Rails.env.development? || Rails.env.test?
21
- ```
22
-
23
- is not as efficient as it could be. If the call to `env` is not memoized your basically paying twice in terms of computation for something that you should only pay once.
24
-
25
- Here
26
-
27
- ```Ruby
28
- Rails.env.development? || Rails.env.test?
29
- ```
30
-
31
- you have 4 method calls while here:
32
-
33
- ```Ruby
34
- env = Rails.env
35
- env.development? || env.test?
36
- ```
37
-
38
- you have one assignment (which is very cheap in terms of computation) and 3 method calls.
39
- The difference might not be much here but just imagine you're writing a high performance app or you doing some expensive database calls in each method call.
40
-
41
- It doesn't really matter though if the efficiency difference is significant. This is a matter of principle - we believe that being efficient is one of the vital traits of good software.
42
-
43
- 2.) Maintainability
44
-
45
- The second point is a bit more subtle. This
46
-
47
- ```Ruby
48
- env = Rails.env
49
- env.development? || env.test?
50
- ```
51
-
52
- is a lot more intention revealing than
53
-
54
- ```Ruby
55
- Rails.env.development? || Rails.env.test?
56
- ```
57
-
58
- Here
59
-
60
- ```Ruby
61
- env = Rails.env
62
- env.development? || env.test?
63
- ```
64
-
65
- I'm very clear on what I do: I get the environment and then I run some checks on it.
66
-
67
- Here
68
-
69
- ```Ruby
70
- Rails.env.development? || Rails.env.test?
71
- ```
72
-
73
- I'm not very clear on what I do and it requires quite more mental effort: Ok, so I'm talking to Rails, getting the environment and then running a check on it ...or .....oh, I get the same Rails constant again, get the same environment and run another check on it.
74
-
75
- ## Example
76
-
77
- Here's a very much simplified and contrived example. The following method will report a warning:
78
-
79
- ```Ruby
80
- def double_thing
81
- @other.thing + @other.thing
82
- end
83
- ```
84
-
85
- One quick approach to silence Reek would be to refactor the code thus:
86
-
87
- ```Ruby
88
- def double_thing
89
- thing = @other.thing
90
- thing + thing
91
- end
92
- ```
93
-
94
- A slightly different approach would be to replace all calls in `double_thing` by calls to `thing`:
95
-
96
- ```Ruby
97
- class Other
98
- def double_thing
99
- thing + thing
100
- end
101
-
102
- def thing
103
- @other.thing
104
- end
105
- end
106
- ```
107
-
108
- The approach you take will depend on balancing other factors in your code.
109
-
110
- ## Current support in Reek
111
-
112
- Reek's Duplicate Method Call detector checks for repeated identical method calls within
113
- any one method definition. This is intended to complement the checks performed by tools
114
- such as [Flay](http://ruby.sadi.st/Flay.html) and [Simian](http://www.redhillconsulting.com.au/products/simian/).
115
-
116
- ## Edge cases
117
-
118
- Be aware that there are some edge cases like this code:
119
-
120
- ```Ruby
121
- class Foo
122
- def bar(switch)
123
- case switch
124
- when :a
125
- ->(arg) { arg.call_me(:maybe); do_something }
126
- when :b
127
- ->(arg) { arg.call_me(:maybe); do_something_else }
128
- when :c
129
- ->(arg) { arg.call_me(:maybe); do_something_different }
130
- end
131
- end
132
- end
133
- ```
134
-
135
- Reek cannot reliably detect that each call's receiver is a different arg and will report:
136
-
137
- ```
138
- [5, 7, 9]:DuplicateMethodCall: Foo#bar calls 'arg.call_me(:maybe)' 3 times
139
- ```
140
-
141
- If you're running into this problem you can disable this smell detector for this method either via
142
- configuration:
143
-
144
- ```Yaml
145
- ---
146
- DuplicateMethodCall:
147
- exclude:
148
- - 'Foo#bar'
149
- ```
150
-
151
- or via source code comment:
152
-
153
- ```Ruby
154
- class Foo
155
- # :reek:DuplicateMethodCall
156
- def bar(switch)
157
- # ....
158
- end
159
- end
160
- ```
161
-
162
- ## Configuration
163
-
164
- Reek's Duplicate Method Call detector currently offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
165
-
166
- Option | Value | Effect
167
- -------|-------|-------
168
- `max_calls` | integer | The maximum number of duplicate calls allowed within a method. Defaults to 1.
169
- `allow_calls` | an array of strings or regular expressions | Ignores any context who matches it |
170
-
171
- ## Example configuration
172
-
173
- ### Adjusting `max_calls`
174
-
175
- Imagine code like this:
176
-
177
- ```Ruby
178
- class Alfa
179
- def bravo
180
- charlie.delta
181
- charlie.delta
182
- end
183
- end
184
- ```
185
-
186
- This would report:
187
-
188
- >>
189
- src.rb -- 1 warning:
190
- [4, 5]:DuplicateMethodCall: Alfa#bravo calls 'charlie.delta' 2 times
191
-
192
- If you want to allow those double calls here you can disable it in 2 different ways:
193
-
194
- 1.) Via source code comment:
195
-
196
- ```Ruby
197
- class Alfa
198
- # :reek:DuplicateMethodCall { max_calls: 2 }
199
- def bravo
200
- charlie.delta
201
- charlie.delta
202
- end
203
- end
204
- ```
205
-
206
- 2.) Via configuration file:
207
-
208
- ```Yaml
209
- DuplicateMethodCall:
210
- max_calls: 2
211
- ```
212
-
213
- Note though that the latter way will set `max_calls` to 2 for all instances
214
- of the smell detector which might not be what you want - in this case
215
- you'll have to use source code comments.
216
-
217
- ### Adjusting `allow_calls`
218
-
219
- Imagine code like this:
220
-
221
- ```Ruby
222
- class Alfa
223
- def bravo
224
- charlie.delta
225
- charlie.delta
226
- echo.foxtrot
227
- echo.foxtrot
228
- end
229
- end
230
- ```
231
-
232
- This would report:
233
-
234
- >>
235
- src.rb -- 2 warnings:
236
- [4, 5]:DuplicateMethodCall: Alfa#bravo calls charlie.delta 2 times
237
- [6, 7]:DuplicateMethodCall: Alfa#bravo calls echo.foxtrot 2 times
238
-
239
- So let's say you're ok with the `echo.foxtrot` calls you can stop reporting them like this:
240
-
241
- 1.) Via source code comment:
242
-
243
- ```Ruby
244
- class Alfa
245
- # :reek:DuplicateMethodCall { allow_calls: ['echo.foxtrot'] }
246
- def bravo
247
- charlie.delta
248
- charlie.delta
249
- echo.foxtrot
250
- echo.foxtrot
251
- end
252
- end
253
- ```
254
-
255
- 2.) Via configuration file:
256
-
257
- ```Yaml
258
- DuplicateMethodCall:
259
- allow_calls:
260
- - 'echo.foxtrot'
261
- ```
262
-
263
- Note though that the latter way will allow those calls across your source code which might not be what you want.
264
- In this case you'll have to use source code comments.