Fork me on GitHub

Project Notes

#398 Ruby 4.0

About Ruby 4.0 including installation on Apple Silicon.

Notes

Ruby 4.0 was released on 2025-12-25. As of 2026-01-02, 4.0.0 is current stable.

Highlights

  • Logical binary operators (||, &&, and and or) at the beginning of a line continue the previous line, like fluent dot.
  • More efficient Array find methods Array#rfind, Array#find
  • Net::HTTP no longer auto-sets Content-Type.
  • Set is now a core class and no longer needs to be autoloaded on use.
  • Pathname has been promoted from a default gem to a core class of Ruby
  • ZJIT is a new prototype JIT compiler. Isn’t considered production ready yet, so it’s behind a --zjit flag if you want to test it out.
  • Ruby Box is an experimental isolation feature for separating definitions (monkey patches, globals, class definitions). It’s akin to what you might call namespaces elsewhere
  • Backtraces are cleaner, with internal frames hidden meaning C-implemented methods now show the Ruby source location.

macOS (Apple Silicon) Install

Already available via rvm:

$ rvm get head
...
$ rvm install ruby-4.0.0
...
ruby-4.0.0 - #generating default wrappers........
ruby-4.0.0 - #adjusting #shebangs for (gem irb erb ri rdoc testrb rake).
Install of ruby-4.0.0 - #complete
Ruby was built without documentation, to build it run: rvm docs generate-ri

Checking version installed:

$ ruby -v
ruby 4.0.0 (2025-12-25 revision 553f1675f3) +PRISM [arm64-darwin24]

Testing Some of the Changes

See examples.rb for a quick test of some of the changes. Running the example:

$ ruby examples.rb
## Demo: Logical binary operators
In Ruby 4.0, Logical binary operators (`||`, `&&`, `and` and `or`) at the beginning of a line continue the previous line, like fluent dot.
  Example:
    if condition1
      && condition2
      puts "OK!"
    end
OK!
## Demo: Infinite enumerator
In Ruby 4.0, `Enumerator.produce` now accepts an optional size keyword argument to specify the size of the enumerator
  Example:
    Enumerator.produce(1, size: Float::INFINITY, &:succ).size == Float::INFINITY
Infinity
## Demo: Finite enumerator with known/computable size
Example:
    required_items = 4
    traverser = Enumerator.produce(0, size: required_items) do |it|
      raise StopIteration if it == required_items - 1
      it + 1
    end
    traverser.each { |n| puts n }
traverser.size: 4
0
1
2
3
## Demo: Pathname
In Ruby 4.0, `Pathname` has been promoted from a default gem to a core class of Ruby
  Example:
    puts Pathname.new("../ruby40").basename
ruby40

Credits and References

About LCK#398 RubymacOS

This page is a web-friendly rendering of my project notes shared in the LittleCodingKata GitHub repository.

Project Source on GitHub Return to the LittleCodingKata Catalog
About LittleCodingKata

LittleCodingKata is my collection of programming exercises, research and code toys broadly spanning things that relate to programming and software development (languages, frameworks and tools).

These range from the trivial to the complex and serious. Many are inspired by existing work and I'll note credits and references where applicable. The focus is quite scattered, as I variously work on things new and important in the moment, or go back to revisit things from the past.

This is primarily a personal collection for my own edification and learning, but anyone who stumbles by is welcome to borrow, steal or reference the work here. And if you spot errors or issues I'd really appreciate some feedback - create an issue, send me an email or even send a pull-request.

Follow the Blog follow projects and notes as they are published in your favourite feed reader