rapa
rapa copied to clipboard
Ragel-based implementation of Ruby's Array#pack and String#unpack.
- Overview
The Array#pack and String#unpack methods are essentially maps from one data representation to another where the transform is controlled by a simple regular language. These methods are used extensively in Ruby code to implement marshalling and encoding.
All Ruby implementations have ad hoc, hand coded versions of these methods. In contrast, this project uses Ragel to describe the language of directives that controls how the transformations are performed. The transformations are then coded in small snippits (Ragel actions). The grammar of directives is language agnostic while the actions are coded in the implementation's target language. In this way, the logic of the directives is shared across all implementations.
- Organization
The implementation-independent specifications of the directives languages are in the "machines" directory. The implementation-specific code for the methods and the actions are in subdirectories of the "actions" directory. To add code for a specific implementation, follow the example of the implementation for Rubinius. The following diagrams illustrate the necessary files:
machines/ pack.rl # description of Array#pack directives unpack.rl # description of String#unpack directives
actions/rubinius/ pack_actions.rl # code for each Array#pack operation pack_code.rl # code for Array#pack method definition unpack_actions.rl # code for each String#unpack operation unpack_code.rl # code for String#unpack method definition
- Generating Files
The Rakefile contains tasks to generate the final source code from the directives languages and the actions. The task for a particular implementation sets the include path for Ragel to use so that implementation-specific actions are used by the implementation-independent directives definitions. For example, to generate the files for Rubinius, run:
rake build:rbx
This will generate pack.cpp and unpack.cpp in the root directory. To generate the files in a specific directory, use the DIR environment variable:
rake build:rbx DIR=/path/to/rubinius/machine/class
- Specs
The specs for Array#pack and String#unpack are contained in the RubySpec project. Each Ruby implementation has its own method for running the RubySpecs. This project is not independent of some Ruby implementation. To run the specs, generate the code for a particular implementation and run the specs under that implementation.