Ripper CHANGELOG 3.1.0

The Ripper module ships with the Ruby standard library and gets updated (implicitly or explicitly) every time the Ruby parser changes. Unfortunately, Ripper itself never changes version (it’s been stuck at 0.1.0 since it was first shipped with Ruby in 2004). As such, there isn’t really a dedicated CHANGELOG, and it’s somewhat difficult to determine what changed inside the Ripper module without digging into the source.

Because I maintain a couple of things that depend on Ripper’s interface, I have some insight into what goes down when Ripper updates. Because of this, I’m putting out this blog post with a list of the changes in the hope that it helps anyone else out there that may be using Ripper for their own purposes.

First of all, if you’re unfamiliar with how Ripper works, I recommend checking out my documentation project. It’s there to help explain a lot of the terminology I’m going to use to describe the changes here. If you’re interested in skipping past my description of the changes are want to just see the code that has to change, feel free to take a look at this pull request that I had to make to kddnewton/syntax_tree to support Ruby 3.1.0.

Without further ado, the changes are listed below.

Blocks without names

Because blocks can now be forwarded without a name, both on_args_add_block and on_blockarg have changed somewhat.

def decorated(&block)
  # ... do something with the block here ...

def decorator(&)"About to perform the action")
  decorated(&)"Performed the action")

Hash keys without values

You can now create hash keys without values, somewhat similar to how it’s done in JavaScript. Because of this, on_assoc_new changed.

x = 1
y = 2

{ x:, y: }
# => { x: 1, y: 2 }

Endless methods without parentheses

You can now create endless methods without using parentheses around the arguments to method calls, which changes on_bodystmt, on_def, and on_defs.

def double(value) = value * 2
def double3 = double 3

double3 # => 6

Argument forwarding

When you forward arguments using the ... operator, it has changed position in its event handler. This changes the on_params event handler.

def request(type, arg, &block)
  # ...

def get(...)
  request(:GET, ...)

Pinned expressions

You can now pin expressions and not just identifiers within pattern matching. This changes the on_begin event handler.

case 1
in ^(0 + 1)
  puts "matched"

Wrapping up

For a comprehensive list of the changes that went into Ruby 3.1.0, I recommend this blog post. If you think I’ve missed anything, feel free to reach out on twitter @kddnewton.

← Back to home