The Crystal Programming Language Forum

Crystal 0.31.0 has been released!

We’ve written a blog post summarizing the changes in this release:

The full changelog is here:

All the usual installation methods still apply:

Docker images and 64 bits Linux packages are available as usual.

The brew formula PR is in


This is such a baller move:


“Multithreading … period” :joy:



There is also a breaking-change required to avoid an ambiguity for drivers that support columns with Array values. db.query("SELECT ...", [1,2]) now means a single argument: [1, 2] , and db.query("SELECT ...", args: [1, 2]) means that two arguments are passed to the query.

Hmm. So something like this would now be a breaking-change? If I am reading it right

result = db.exec "UPDATE rpg_user_items set equipped = 0, slot_position = ? where user_id = ? and rpg_character_id = ? and itemid = ?", "#{x}x#{y}", client.user_id, client.selected_characterid, incoming_itemid

I would need to use args: now?

Recompiled a working project and got this error

➜ Crystal Projects crystal build --release
Showing last frame. Use --error-trace for full trace.


 519 | x = 1.to_big_i << (bits - 1) / 2 | num >> (bits / 2 + 1)
Error: no overload matches 'BigInt#<<' with type Float64

Overloads are:
 - BigInt#<<(other : Int)
 - Int#<<(count : Int)

Oh man…

Got to change all the integer divides from / to //, and other operations that now create floats into integers operations.

Lots of breaking changes to track down and fix.

Very nice post!

I just don’t understand this part:

Also, if a line that ended someplace outside the it but inside a describe is specified, the whole describe will run.

Can you give an example, or rephrase it? (or explain here?) ty

1 Like

Congratulations!! Hope Crystal lang becomes a big success.

1 Like

Check the PR in the Better line matching section.

Aaah it’s when you run the spec using a line number! I see now.

Might be worth to rephrase as:
Also when running a spec using a line number, if a line that ended someplace outside the it but inside a describe is specified, the whole describe will run.

The change from using / to // for doing integer division really caused havoc in my code.

The last subtlety was tracking down change from: a /= b to a = a // b, but found a //= b also works. Doing a /= b returns a float when it used to return an integer when both a and b were integers.

At least the compiler gave very helpful messages using: crystal --error-trace

Because I knew my code, once I knew what to look for it was straightforward to correct.
It might not be the case for people trying to use other people’s code.

This change really needs to be well documented with examples.

I have only found a few errors in my code which is a pain. But I love the idea behind the change.

The fact that this was caught at compile time is actually amazing. If Ruby made this change you might overlook several cases of it until they make it to production.


Sweet, only required a single change to “//”

1 Like

To be completely accurate, I had to do a few more changes besides / to //,
like to Time.local, but the most serious ones involved operations
that used to create integer results that became floats.