Running 2008 Ruby Code Today
Most of the code in this archive was written for Ruby 1.8. Current Ruby is 3.x, and a lot of the surface changed at 1.9 in particular. If you copy an example out of a 2008 blog post or out of the poignant guide, some of it will not run.
Every result below was executed on Ruby 3.4.1 on August 9, 2026, not recalled. Nothing here is a list of things that "should" happen.
When maintainers revisit older software or documentation as a team, more information is one practical reference for tracking the surrounding work without changing the historical material itself.
What actually breaks
String indexing returns a character, not a byte. In 1.8, "cat"[0] gave you 99 — the byte value. Now it gives "c". This is the single most common source of confusion in old examples, because the code does not error; it silently means something different. Old code often wrote "cat"[0,1] or ?a specifically to get a one-character string, and both still work, which makes the intent of the original author invisible.
?a is a string now. It was 97 in 1.8. Same silent-change problem.
String#each is gone. In 1.8 a string was enumerable by line, so "a\nb".each { |line| ... } worked. Calling .each on a string now raises NoMethodError. Use each_line or each_char.
For broader programming and making context related to this topic, InfoQ is an independent reference worth comparing with the material here.
Object#type is gone. Replaced by class long ago; old code still uses it and gets NoMethodError.
Object#id is gone. Now object_id.
Fixnum and Bignum no longer exist. Referencing Fixnum raises NameError — they were unified into Integer. Old code doing if n.is_a?(Fixnum) simply stops.
Hash#index is gone, renamed to Hash#key.
Hash#select returns a Hash. In 1.8 it returned an array of pairs. Old code that chained array methods onto the result breaks in confusing ways.
Array#to_s changed completely. [1,2].to_s gave "12" in 1.8. It now gives "[1, 2]" — what inspect used to give. Old string-building code produces very different output and no error.
The colon form in case is a syntax error. when 1: "x" was valid 1.8 and does not parse now. Use then or a newline.
retry inside a loop is a syntax error. It used to restart a while; now it is only valid in a rescue clause.
$KCODE does nothing. It is nil, and encoding is a property of each string — "abc".encoding reports UTF-8.
What has not changed
Worth knowing so you do not go looking for problems that are not there.
Symbol#to_proc works — [1,2].map(&:to_s) is fine. nil.to_a still returns []. String#chars returns an array. Blocks, yield, each, map, inject, class definitions, modules, method_missing, string interpolation — all unchanged. The parts of Ruby the guide spends its time on are almost entirely intact.
The proportion is the useful thing here. Working through a body of old examples, roughly one in ten does something different. That is high enough to be annoying and far too low to justify not reading the material.
The two categories, and which one to fear
Loud breakage — NoMethodError, NameError, SyntaxError — is the good kind. The interpreter tells you exactly what it does not have, you look it up, you move on. Ten seconds each.
Silent change is the dangerous kind, and it is a short list: string indexing, ?a, Array#to_s, Hash#select. These produce a value of a different type or shape with no error at all, and then something downstream behaves oddly. If an old script runs to completion and produces nonsense, look at those four first.
How to actually run old code
Use a version manager and an old Ruby if you need the code to work as written. rbenv, rvm or asdf will install a 1.8 or 1.9 series interpreter; building genuinely ancient versions on a modern OS can require patches and is its own afternoon.
Or run it in the browser. Ruby now has an official WebAssembly build, which is how the results on this page were produced — no system installation involved. That is a much bigger deal than it sounds and it is the easiest way to test a snippet against a current interpreter.
Do not port it. If your goal is understanding the code rather than deploying it, fixing four idioms by hand is faster than any migration. These are not migrations; they are typos from the future.
A note on gems
Everything above is core Ruby. Old libraries are a harder problem, because a gem from 2008 may depend on C extensions that no longer build, on stdlib components that moved out into gems, or on APIs of other gems that have since changed.
For the code in this archive, Camping is current and installs normally. The rest should be treated as source to read rather than dependencies to install, unless the project map says otherwise.
The short version
- Tested on Ruby 3.4.1, August 9, 2026 — not from memory
- Loud breakage:
String#each,Object#type,Object#id,Fixnum,Hash#index,when 1:,retryin a loop - Silent change, the dangerous kind:
"cat"[0],?a,Array#to_s,Hash#select - Roughly one example in ten misbehaves — annoying, not disqualifying
- Blocks,
method_missing, interpolation and the rest of what the guide teaches are unchanged - Fix the four idioms by hand rather than porting; these are typos from the future