Bindings, Platforms, and Innovation
This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.
Tracking change and innovation in the enterprise software development community
Posted by Werner Schuster on Nov 07, 2008 05:15 PM
Static analysis tools allow to keep code quality up and warn of potential bugs. Compilers in statically compiled languages often run static analysis checks and report potential problems as warnings. Popular stand-alone tools are C's lint or Smalltalk Lint, many modern IDEs also perform static analysis on code, often incrementally as code is edited.
Static analysis tools for Ruby for a long time suffered from the lack of a standard way of accessing the Abstract Syntax Tree (AST) of Ruby source. One solution was the ParseTree gem, which uses a native extension to access the parse tree of parsed Ruby code. One problem of ParseTree include the dependency on native code to run. ParseTree is also only available on Ruby 1.8, but is unlikely to be supported on 1.9 (Ruby 1.9 comes with Ripper, a library that allows to parse source files but not access the parse trees at runtime). The ParseTree support across new Ruby implementations is inconsistent at the moment.
The introduction of ruby_parser, a Ruby parser written in Ruby promises to fix these problems. The project was recently released in 2.0 version, which improved performance and, importantly, added line numbers as metadata to the ASTs. The latter information is crucial for static analysis tools as they need to report the location of a discovered problem.
An important point, considering that all current Ruby IDEs written either in Java (Eclipse based IDEs such as Aptana or 3rdRail, Netbeans' Ruby support, JetBrains' RubyMine) or .NET (Ruby In Steel, based on VS). All of these IDEs also feature static analysis code of Ruby code, but none of it is written in Ruby. Static analysis code based on a Java or .NET based Ruby parser and AST obviously doesn't run on MRI or other Ruby implementations. UnifiedRuby is a cleaned up version of ParseTree's output, and in combination with ruby_parser, it's now possible to parse Ruby source code and analyze in pure Ruby.
A growing list of static analysis tools has become available in the past few months.
Flay, written by Ryan Davis, checks codebases for duplicates. By using an AST, instead of the source code, it's possible to compare the code structurally. Copy/pasted code can so be detected even if, say, literal values were modified. Ryan has previously released another static analysis tool flog, which calculates a score for a codebase which depends on various patterns considered bad, eg. large numbers of dependencies. Both flay and flog can be used from the command line to check code bases. Flay uses ruby_parser to parse Ruby code.
Reek by Kevin Rutherford is a "a code smells detector for ruby". It comes with a list of checks which detect long method bodies, large classes, bad names, etc. The checks are written as SexpProcessor subclasses, which works as a visitor over the AST. Reek's code is hosted at Github.
Roodi is similar to reek in that it allows to run a list of checks over a codebase. Roodi comes with checks that ensure methods or modules comply with a naming convention, max parameter count, etc. Other checks include advice such as avoiding for loops, etc. The shipped checks can also be easily configured with a YAML file. New checks can be easily written as well. A checker class registers the types of AST nodes it's interested in and can then handle the matched subtrees.
Rufus by John Mettraux allows to check Ruby for unwanted or unsafe code. The Rufus library allows to check some Ruby source code before loading it. Eg. loading a Ruby file that consists of a single line like exit is probably a bad idea. The library can be configured with custom patterns of code to be excluded.
Do you plan to add one or more of these tools to your continuous integration setup? What checks would you like to see or write?
Ensuring Code Quality in Multi-threaded Applications
Effective Management of Static Analysis Vulnerabilities and Defects
Agile Development: A Manager's Roadmap for Success
You might also want to check out RubyDiff as another static analysis tool. It doesn't check code style, but does a syntactic diff on ruby code. There is a rubyforge project, and the source is available on github.
Hi Werner, thanks for the link to "rufus-treechecker". "rufus" is in fact a set of ruby gems derived from ruote. The less obscure of these gems is rufus-scheduler, for scheduling pieces of ruby code in an 'at' or 'cron' fashion. Best regards.
This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.
This article explores the use of JBoss and jBPM to implement design solutions that effectively address the issue of orchestrating long running activities.
This presentation covers the use of graph databases as an optimal solution for data that is difficult to fit in static tables, rapidly evolving data or data that has a lot of optional attributes.
This session introduces Real Options and shows how it can help in running your project. Real Options is a decision-making process that can be used to manage risk.
This article discusses the use of bindings on services and references (including the instance of non-configured bindings) as the means to implement SCA communications in a Web and SOA environment.
After a short introduction to DSLs, Scott Davis plays with the keyboard showing how to approach the creation of a DSL by typing working snippets of Groovy code that get executed.
IBM Rational and InfoQ present, Scaling Agile with C/ALM, an eBook showing organizations how to become “finely tuned software delivery machines” by enabling team integration and scaling.
Amanda Laucher presents a real life enterprise application written in F#. She shows actual code snippets, explaining design decisions and suggesting how to use some of the F# constructs.
2 comments
Watch Thread Reply