Static Typing for Ruby on Rails
Jong-hoon (David) An, Avik Chaudhuri, and Jeffrey S. Foster
In Proceedings of the 24th IEEE/ACM International Conference on Automated Software Engineering. Auckland, New Zealand. November 2009
[ Abstract |
pdf ]
Ruby on Rails (or just ``Rails’’) is a popular web application
framework built on top of Ruby, an object-oriented scripting
language. While Ruby’s powerful features such as dynamic typing help make
Rails development extremely lightweight, this comes at a cost.
Dynamic typing in particular means that type errors in Rails applications
remain latent until run time, making debugging and maintenance harder.
In this paper, we describe DRails, a novel tool that brings
static typing to Rails applications to detect a range of run
time errors. DRails works by translating Rails programs into pure
Ruby code in which Rails’s numerous implicit conventions are made
explicit. We then discover type errors by applying DRuby, a
previously developed static type inference system, to the translated
program. We ran DRails on a suite of applications and found that it
was able to detect several previously unknown errors.
Profile-Guided Static Typing for Dynamic Scripting Languages
Michael Furr, Jong-hoon (David) An, and Jeffrey S. Foster
University of Maryland, Computer Science Department
Technical Report
CS-TR-4935
April 2009
[ Abstract |
pdf ]
Many popular scripting languages such as Ruby, Python, and Perl
include highly dynamic language constructs, such as an eval method
that evaluates a string as program text. While these constructs allow
terse and expressive code, they have traditionally obstructed static
analysis. In this paper we present PRuby, an extension to Diamondback
Ruby (DRuby), a static type inference system for Ruby. PRuby augments
DRuby with a novel dynamic analysis and transformation that allows us
to precisely type uses of highly dynamic constructs. PRuby’s analysis
proceeds in three steps. First, we use run-time instrumentation to
gather per-application profiles of dynamic feature usage. Next, we
replace dynamic features with statically analyzable alternatives based
on the profile. We also add instrumentation to safely handle cases
when subsequent runs do not match the profile. Finally, we run DRuby’s
static type inference on the transformed code to enforce type
safety. We used PRuby to gather profiles for a benchmark suite of
sample Ruby programs. We found that dynamic features are pervasive
throughout the benchmarks and the libraries they include, but that
most uses of these features are highly constrained and hence can be
effectively profiled. Using the profiles to guide type inference, we
found that DRuby can generally statically type our benchmarks modulo
some refactoring, and we discovered several previously unknown type
errors. These results suggest that profiling and transformation is a
lightweight but highly effective approach to bring static typing to
highly dynamic languages.