Ruby Under a Microscope: An Illustrated Guide to Ruby Internals
Format: PDF / Kindle (mobi) / ePub
Ruby is a powerful programming language with a focus on simplicity, but beneath its elegant syntax it performs countless unseen tasks.
Ruby Under a Microscope gives you a hands-on look at Ruby's core, using extensive diagrams and thorough explanations to show you how Ruby is implemented (no C skills required). Author Pat Shaughnessy takes a scientific approach, laying out a series of experiments with Ruby code to take you behind the scenes of how programming languages work. You'll even find information on JRuby and Rubinius (two alternative implementations of Ruby), as well as in-depth explorations of Ruby's garbage collection algorithm.
Ruby Under a Microscope will teach you:
- How a few computer science concepts underpin Ruby's complex implementation
- How Ruby executes your code using a virtual machine
- How classes and modules are the same inside Ruby
- How Ruby employs algorithms originally developed for Lisp
- How Ruby uses grammar rules to parse and understand your code
- How your Ruby code is translated into a different language by a compiler
No programming language needs to be a black box. Whether you're already intrigued by language implementation or just want to dig deeper into Ruby, you'll find Ruby Under a Microscope a fascinating way to become a better programmer.
Covers Ruby 2.x, 1.9 and 1.8
puts n params identifier "n" Here you can see Ruby now understands that “do |n| … end” is a block, with a single block parameter called n. The puts n box on the right represents the other part of the AST I showed above, the parsed version of the puts call. And finally here’s the entire AST for my sample Ruby code: 38 Chapter 1: Tokenization, Parsing and Compilation 10.times do |n| puts n end program method add block call integer 10 period …do |n| puts n end identifier "times" Here
pattern. Sometimes it takes Ruby longer to add a new instance variable, and sometimes Ruby is able to save one faster. What’s going on here? The reason for this behavior has to do with that array I showed above where Ruby stores the instance variables: RObject ivptr Leonhard Euler In Ruby 1.8 this array is actually a hash table containing both the variable names (the hash keys) and the actual values, which will automatically expand to accommodate any number of elements. Stay tuned for Chapter
classes. Whenever you create a module, Ruby actually creates another RClass — rb_classext_struct structure pair, just like it would for a new class. For example, when I define a new module like this: module Professor end …internally Ruby will create a class, not a module! Here are the class structures again: 149 Ruby Under a Microscope RClass RBasic flags klass Class Pointer m_tbl Method Table VALUE iv_index_tbl Instance Level Attribute Names ptr rb_classext_struct super Superclass
value for :key2 by repeating the same hash calculation: internal_hash_function(:key2) % 11 = 5 Believe it or not, the C library used by Ruby to implement hash tables was originally written back in the 1980’s by Peter Moore from the University of California at Berkeley, and later modified by the Ruby core team. You can find Peter Moore’s hash table code in the C code files st.c and include/ruby/st.h. All of the function and structure names use the naming convention st_ in Peter’s hash table code.
table->bins = new_bins; } The new_size method call here returns the new bin count, for example 19. Once Ruby has the new bin count, it allocates the new bins and then iterates over all the existing st_table_entry structures (all the key/value pairs in the hash). For each st_table_entry Ruby recalculates the bin position using the same modulus formula: hash_val = ptr->hash % new_num_bins. Then it saves each entry in the linked list for that new bin. Finally Ruby updates the st_table structure and