Written by James BrittTechnically reviewed by Jim Freeze · Reviewed
A brief history of Ruby programming language development starts with a distinction: the idea came before the public release. Yukihiro Matsumoto, usually called Matz, began designing Ruby in 1993. Ruby 0.95 reached Japanese newsgroups in December 1995. Those dates describe different milestones, so accounts that use either year need not disagree.
This guide follows three well documented moments: Ruby’s conception, its early public release, and Ruby 2.0. It then connects that history to a small program you can read today. The aim is to explain the language’s character without turning a short history into a list of every release.

A brief history of Ruby programming language milestones
Ruby’s official introductory FAQ records 24 February 1993 as its birthday. Matsumoto describes discussing an object-oriented scripting language with a colleague. He wanted features such as objects, iterators, exceptions and automatic garbage collection together in a language he enjoyed using.
The same account places the posting of Ruby 0.95 in December 1995. Think of 1993 as the start of the project and 1995 as an early public-release milestone. Neither date means that Ruby arrived with its present libraries, tooling or community already assembled.
The distinction matters when you read older articles. “Created,” “announced” and “released” are not interchangeable labels. A language can spend years in development, and its first public users may have a very different experience from the people who learn it later.
What the original design helps explain
Ruby encourages you to work with objects by sending them messages, usually through method calls. An array can transform its contents with map; a string can produce an uppercase version with upcase. A block supplies the operation to perform for each element.
That arrangement is useful to notice before studying individual punctuation marks. You can read a line as a request to an object, followed by the work it should do. The program still has strict rules, but related operations can fit together in a compact expression.
Automatic memory management also changes a beginner’s workload. You normally do not write a matching manual deallocation for each ordinary Ruby object. You still need to manage resources such as open files and network connections; garbage collection does not make resource ownership disappear.
These observations are a way to read modern Ruby, not evidence that every present-day feature existed in the first release. Historical explanations become misleading when they project today’s syntax backwards.
Ruby 2.0: a useful point on the timeline
The Ruby 2.0 release announcement is dated 24 February 2013, the project’s twentieth birthday. It lists keyword arguments, lazy enumeration and Module#prepend among the additions. It also announces UTF-8 as the default script encoding.
This is a helpful milestone because the announcement names concrete changes. Rather than saying that Ruby simply became “more powerful,” you can ask what a developer could express differently. Keyword arguments can give a call meaningful parameter names. Lazy enumeration can postpone work until a result is needed.
A release announcement is a document from its own time. Read it to understand what changed in that release. When maintaining a program today, use the documentation for the Ruby version running it. Historical feature descriptions do not guarantee compatibility with every later version.
Read the design in a short modern program
This example is modern Ruby for learning purposes. Its output and four behaviour checks passed with Ruby 3.2.3. It does not attempt to recreate Ruby 0.95. Save it as greetings.rb, then run ruby greetings.rb in a terminal with Ruby installed.
def greeting(name, prefix: "Hello")
"#{prefix}, #{name}!"
end
names = ["Ada", "Matz"]
messages = names.map { |name| greeting(name, prefix: "Welcome") }
puts messages
The output is two lines: Welcome, Ada! and Welcome, Matz!. The array receives map, and the block calls the method for each name. The method returns its last expression, a string. Its keyword argument lets the caller choose a greeting prefix.
Change the array to an empty array and run the file again. No greeting lines print. You changed the input without adding a loop counter or checking an index. Next, remove the supplied prefix from the method call to try the default greeting.
For more practice with this style, read our guide to Ruby functional programming. It explains collection transformations and the places where changes to shared objects can surprise you.
Explore the history: choose a question
Open a question to check your understanding. Each answer links a date or design idea to a practical reading habit.
Was Ruby created in 1993 or released in 1995?
Both statements can be accurate. The official FAQ gives 24 February 1993 as Ruby’s birthday and places the public posting of Ruby 0.95 in December 1995. Check which event an author is describing before comparing dates.
Does the example show the original Ruby syntax?
No. It is a modern teaching example. The keyword-argument milestone discussed here comes from the Ruby 2.0 announcement, so this snippet should not be presented as code from the first public release.
Did Ruby and Rails begin as the same project?
Ruby is a programming language; Rails is a web framework built with it. Learning Ruby does not require creating a Rails application. Keep the language’s history separate from the history of a framework that uses it.
Keep the language and its ecosystem separate
Many tutorials move quickly from Ruby to Rails, gems, testing tools and deployment commands. That can make several layers seem like one product. They are distinct parts of a working environment, each with its own versions and responsibilities.
Our Ruby versus Ruby on Rails explanation untangles the language and framework. For a history reader, that distinction prevents a common error: treating the growth of a prominent Ruby tool as the beginning of Ruby itself.
When you encounter an old code sample, note its publication date, identify its Ruby version if possible, and run it in an appropriate test environment. Those small steps turn history into something useful: a way to understand the assumptions behind a program, rather than a set of dates to memorise.
