Dynamic languages such as Ruby, Python, and JavaScript have many compelling benefits, but the lack of static types means subtle errors can remain latent in code for a long time. While many researchers have developed various systems to bring some of the benefits of static types to dynamic languages, prior approaches have trouble dealing with metaprogramming, which generates code as the program executes. In this paper, we propose Hummingbird, a new system that uses a novel technique, just-in-time static type checking, to type check Ruby code even in the presence of metaprogramming. In Hummingbird, method type signatures are gathered dynamically at run-time, as those methods are created. When a method is called, Hummingbird statically type checks the method body against current type signatures. Thus, Hummingbird provides thorough static checks on a per-method basis, while also allowing arbitrarily complex metaprogramming. For performance, Hummingbird memoizes the static type checking pass, invalidating cached checks only if necessary. We formalize Hummingbird using a core, Ruby-like language and prove it sound. To evaluate Hummingbird, we applied it to six apps, including three that use Ruby on Rails, a powerful framework that relies heavily on metaprogramming. We found that all apps typecheck successfully using Hummingbird, and that Hummingbird’s performance overhead is reasonable. We applied Hummingbird to earlier versions of one Rails app and found several type errors that had been introduced and then fixed. Lastly, we demonstrate using Hummingbird in Rails development mode to typecheck an app as live updates are applied to it.
We also developed DRails @cite_11 , which type checks Rails apps by applying DRuby to translated Rails code. For example, if DRails sees a call to belongs , it outputs Ruby code that explicitly contains the methods generated from the call, which DRuby can then analyze. While DRails was applied to a range of programs, its analysis is quite brittle. Supporting each additional Rails feature in DRails requires implementing, in OCaml, a source-to-source transformation that mimics that feature. This is a huge effort and is hard to sustain as Rails evolves. In contrast, types are generated in Ruby, which is far easier. DRails is also complex to use: The program is combined into one file, then run to gather profile information, then transformed and type checked. Using is far simpler. Finally, DRails is Rails-specific, whereas applies readily to other Ruby frameworks. Due to all these issues, we feel is much more lightweight, agile, scalable, and maintainable than DRails.
@cite_11
2081212007
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.