Checkout the release notes to see a full scope of changes. Here we will go through the most important changes.
Globs and Excluded configuration options
Ameba now allows to globally configure the list of sources to run the inspection on. There are two new sections which can be added to .ameba.yml
:
1 | Globs: |
Globs
is used to define paths to include to the inspection. Defaults to%w(**/*.cr !lib)
Excluded
is used to exclude from the list defined byGlobs
Crystal 0.34 compatibility
Crystal 0.34
is not yet released, but thanks to @bcardiff Ameba is now ready to the upcoming release and is still compatible to the current Crystal version 0.33
.
New Rules
Style/RedundantNext
Crystal has next
keyword which can be used to go to the next iteration in a loop. However, it can also be used to exit from a block, for example:
1 | (1..3).each do |e| |
And in some places next
can be overused, especially when it combines in the last expression in the block. For example:
1 | block do |v| |
In all three places above the next
keyword is redundant and is reported by the new rule.
Lint/SharedVarInFiber
To achieve concurrency and parallelism Crystal uses Fibers and Channels. There is a tricky behavior which happens when a shared variable is used across multiple fibers and is mutated during iterations. For example:
1 | n = 0 |
You might expect the code above to print 1 2 3
, however it prints 3 3 3
. The problem is there is a shared variable n
and when channel.receive
is executed its value is 3
.
To solve it, the code above can be written to the following:
1 | n = 0 |
So instead of using a shared variable n
which is declared at the top and mutated in a while
loop, we reassign the value to variable m
and use it in our spawn. As the result, the code above prints the expected 1 2 3
. The new rule properly reports the issue on the first sample and passes on the second one.
There are also other technics to solve the problem above which are officially documented.
Lint/EmptyLoop
After some round of refactoring it can happen that the loop body becomes empty but for whatever reason such an empty loop is forgotten to be removed. A new rule is able to detect a few situations:
1 | while true |
And these samples are valid and not reported:
1 | a = 1 |
Lint/RedundantStringCoercion
This is typical situation when a value is being converted to string using Object.to_s
method in the interpolation.
1 | "Hello, #{name.to_s}" |
Since each value enclosed by { ... }
ends up invoking Object.to_s
explicit calls are redundant and are now reported by Ameba. The code above is forced to be changed to
1 | "Hello, #{name}" |
Support
A new Patreon page has been created recently to support Ameba. If you enjoy the project please consider becoming a patreon which will give more attention to the project from the development perspective and make it better.
Comments