Crystal 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 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 which has a lot of valuable information.
Compiler
In #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 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 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.
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 will only be relevant to the ones that want to dig into the compiler itself.
Language semantics
Since #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 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 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 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:
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.
$ 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. #LovelyNewTraditions
Text
There are a couple of refinements in the String
API. In #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. #0o0
String#camelcase
got a new downcase
option in #7717 and some String#to_i
arguments were restricted to Bool
in #7436.
Collections
Slice
got sorting methods in #7597 and the #pointer
was removed in #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
Files
This breaking change can probably be sent to /dev/null
. In #7778 File::DEVNULL
was renamed to File::NULL
.
Networking
Extra! Extra! #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 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 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 which has a lot of valuable information.
The development is possible thanks to the community’s effort, 84codes’ support, and every supporter.