After returning to Ruby from a long stint coding in another language, I regularly assume that foo.sort
, foo.map {...}
, foo.sub /bar/, 'zip'
will change foo. Of course I meant foo.sort!
, etc. But that usually takes 3 or 4 debugging potshots before I notice. Meanwhile, the sort is calculated, but then isn't assigned to anything. Can I make ruby warn about that missing lvalue, like a C compiler warns of a function's ignored return value?
Here's a very basic parser :
@forgetful_methods = %w(sort map sub)
Dir['*.rb'].each do |script|
File.readlines(script).each.with_index(1) do |line, i|
@forgetful_methods.each do |method|
if line =~ /\.#{method}(?!!)/ && $` !~ /(=|\b(puts|print|return)\b|^#)/
puts format('%-25s (%3d) : %s', script, i, line.strip)
end
end
end
end
# =>
# brace_globbing.rb ( 13) : subpatterns.map{|subpattern| explode_extglob(match.pre_match+subpattern+match.post_match)}.flatten
# delegate.rb ( 11) : @targets.map { |t| t.send(m, *args) }
It checks every ruby script in the current directory for sort
, map
or sub
without !
that aren't preceded by =
, puts
, print
or return
.
It's just a start, but maybe it could help you find some of the low hanging fruits. There are many false positives, though.
A more complex version could use abstract syntax trees, for example with Ripper.