---
title: Crystal 0.29.0 released!
version: 0.29.0
summary: Crystal has a new development release.
thumbnail: +
author: bcardiff
---

[Crystal 0.29.0](https://github.com/crystal-lang/crystal/releases/tag/0.29.0) has been released!

This release comes with many fixes in the compiler and some polishing in the std-lib. There is some work-in-progress related to multi-threading in other branches and whiteboards still.

There were [116 commits since 0.28.0](https://github.com/crystal-lang/crystal/compare/0.28.0...0.29.0) by 24 contributors.

Let’s review some of the most relevant changes in this release. But don't miss the rest of the [release changelog](https://github.com/crystal-lang/crystal/releases/tag/0.29.0) which has a lot of valuable information.

# Compiler

In [#7758](https://github.com/crystal-lang/crystal/pull/7758) a bug in the `require` file path algorithm was fixed. If your shard of application stops compiling it’s maybe due to an extra pair of `../` or a requirement missing. Keep calm and fix the paths.

Since [#7582](https://github.com/crystal-lang/crystal/pull/7582) the compiler is a bit pickier (as it always should’ve been) with respect name of variables. Shouting and asking is no longer allowed, so `!` and `?` are disallowed at the end of variables. They are allowed only in methods name (and in the special `$?`).

Deprecation warnings were introduced in 0.28.0, and there were a couple of undetected cases. Since [#7724](https://github.com/crystal-lang/crystal/pull/7724) the analysis covers initialize methods and methods with named args. Remember to build and spec with `--warnings=all --error-on-warnings` options since this feature is opt-in for now.

Effective error reporting depends heavily on tracking back an AST node to the original location. More cases are now handled since [#7827](https://github.com/crystal-lang/crystal/pull/7827).

During the last couple of releases, we’ve been introducing a couple of feature toggles to introduce new semantics. We were missing a way to run the existing compiler specs against these toggles when they affect low-level phases of the compiler. Maybe [#7837](https://github.com/crystal-lang/crystal/pull/7837) will only be relevant to the ones that want to dig into the compiler itself.

## Language semantics

Since [#7818](https://github.com/crystal-lang/crystal/pull/7818) the compiler is a bit more strict regarding how new/initialize methods are defined when they’ve been included from a `module`. All in all it aims for consistency with `initialize` methods defined in a hierarchy of types.

In [#7801](https://github.com/crystal-lang/crystal/pull/7801) the behaviour of `sizeof` and `instance_sizeof` is improved for abstract structs and modules. In some cases it used to compile when it shouldn’t, and there could be some wrong sizes returned.

When declaring an `enum` flag type its members are `Int32` by default, and you are allowed to change the base type to other numeric types like `Int8`, `UInt16`, etc. Since [#7776](https://github.com/crystal-lang/crystal/pull/7776) 64-bits numeric types can be used also without chances of blowing up if there were more than 32 members. #Internals

## Tools

The crystal implementation tool got a really useful feature. Since [#7742](https://github.com/crystal-lang/crystal/pull/7742) the tool can be used to lookup class and module implementations. Although its usage depends on the editor, let’s see a command line example.

In a `minion.cr` with the following content:

```crystal
class Minion
  def initialize(@name : String)
  end
end

m = Minion.new("Stuart")
```

If the cursor is located at line 6 column 8, it will be in the middle of `Minion` of the `Minion.new`. We can ask the tool to locate all the places where the constant `Minion` is defined.

```shell
$ crystal tool implementations --cursor minion.cr:6:8 minion.cr
1 implementation found
/path/to/minion.cr:1:1
```

This search is semantic. If there is a `Minion` constant in another namespace it will not be shown as an implementation. And it works across all files included from the main file after the cursor location.

# Standard library

The docs are filled with examples, from time to time there is a major update to keep them consistent. Check how an external tool built by the community was used one more time in [#7718](https://github.com/crystal-lang/crystal/pull/7718). #LovelyNewTraditions

## Text

There are a couple of refinements in the `String` API. In [#7633](https://github.com/crystal-lang/crystal/pull/7633), `String#at` is deprecated in favor of `#char_at`. A `String` is able to contain binary data so it’s better to have no doubts if you are intending to access a `char` or a `byte`. #UTF8FTW

In case your code parses octals using `String#to_i`, they will need to be prefixed with `0o` and not only `0`. So `0777` is `777` (dec) and `0o777` is `511` (dec). Read more at [#0o17013](https://github.com/crystal-lang/crystal/pull/7691). #0o0

`String#camelcase` got a new `downcase` option in [#7717](https://github.com/crystal-lang/crystal/pull/7717) and some `String#to_i` arguments were restricted to `Bool` in [#7436](https://github.com/crystal-lang/crystal/pull/7436).

## Collections

`Slice` got sorting methods in [#7597](https://github.com/crystal-lang/crystal/pull/7597) and the `#pointer` was removed in [#7581](https://github.com/crystal-lang/crystal/pull/7581).

## Serialization

YAML mappings are now a bit more comfortable for `String`. If the mapping states that a `String` is expected, and if the YAML source provides a scalar, the value is interpreted as a string. No need to quote it in the YAML, or add `#to_s` methods on the code. Read more at [#7809](https://github.com/crystal-lang/crystal/pull/7809)

## Files

This breaking change can probably be sent to `/dev/null`. In [#7778](https://github.com/crystal-lang/crystal/pull/7778) `File::DEVNULL` was renamed to `File::NULL`.

## Networking

Extra! Extra! [#7423](https://github.com/crystal-lang/crystal/pull/7423) added multicast for UDP. Broadcast the news! Extra! Extra!

In case your code needed to handle big files via `IO` there was one stopper issue. `IO#copy` used to return a 32 bits number, since [#7660](https://github.com/crystal-lang/crystal/pull/7660) that is changed to a `UInt64`. We still encourage 32 bits by default, but some use cases demand a bit more, like... 32 more bits.

## Crypto

Names are hard, vol. 23425. In `Crypto::Bcrypt::Password` the `#==` method was deprecated in favor of `#verify` in [#7790](https://github.com/crystal-lang/crystal/pull/7790) to better reflect the semantic of the operation.

# Next steps

Please update your Crystal and report any issues. We will keep moving forward and start the development focusing on 0.30.

Once again, check your code with `--warnings=all`. This will help in the migration of your codebase and will probably push some feedback about that tool. Many of the breaking changes in this release are actually deprecations, so you probably want to check for warnings in order to do a full upgrade to Crystal 0.29.0.

Don't miss the rest of the [release changelog](https://github.com/crystal-lang/crystal/releases/tag/0.29.0) which has a lot of valuable information.

> **THANKS:**
> The development is possible thanks to the community's effort, [84codes](https://www.84codes.com/)' support, and every [supporter](https://crystal-lang.org/sponsors).
