We are releasing the first post-1.0 release, making efforts to keep our promise of making regular releases each 3 months, a bit delayed because of the conference, and with special focus on keeping the language stability. Below we list the most important or interesting changes, without mentioning the several bugfixes. For details visit the release’s notes.
Stats
In this release we included 166 PRs since the 1.0.0 release by 28 contributors. We thank all the effort put into improving the language and its stdlib! ❤️
Language changes
Splats can now be embedded in enumerable literals and in type definitions (#10429). A few examples:
t1 = {1, 'a'}
t2 = {true, *t1} # => {true, 1, 'a'}
typeof(t2) # => Tuple(Bool, Int32, Char)
def f1(x : {Bool, *{Int32, Char}}); end # Works in type annotations too
def f2(x : Tuple(Bool, *{Int32, Char})); end
ae = 'a'..'e'
ccae = ['<', *ae, '>'] # => ['<', 'a', 'b', 'c', 'd', 'e', '>']
a = 1..10
b = 5..15
Set{*a, *b} # => Set{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
The type of a while expression is now the union of all break expressions within the body, plus Nil
if the condition isn’t exactly the true
literal; the while expression returns nil
if the condition fails. The type of a break expression is computed similarly to a break inside a block or a return (Nil
if empty, Tuple
if multiple values) (#10566).
# First the first non-blank line in STDIN
first_non_blank_line =
while line = gets
break line unless line.blank?
end
puts first_non_blank_line
Macros
It is now possible to access the top level module with the special instance variable @top_level
(#10682):
FOO = 1
class Foo
def bar
{{@top_level.has_constant?("FOO")}} # true
end
end
NumberLiteral
now includes a to_number
method to obtain the pure number, without any stringification #10802:
{{ p 10_u8.id }} # => 10_u8
{{ p 10_u8.to_number }} # => 10
We included a small breaking change, as there was a mismatch between the documentation and the code regarding Path#global?
. The former Path#global
is now deprecated in favor of Path#global?
, whose name better represents it (#10812).
There is a new macro method ASTNode#nil?
for querying if an object is the NilLiteral
or Nop
(#10850, #10616).
Stdlib
There were several changes that are not supposed to have a direct impact on the users. The most important one to note is that to help get better error messages and documentation, several methods were annotated with expected types. Adding typing annotations might break existing code in specific scenarios so, if this happens to you, please let us now. Also, we are growing the native Windows support, requiring several refactors.
Numeric
It is now possible to create numbers from different representations using new
, as in Float32.new("1.1", whitespace:false)
((#10422).
We added #positive?
and #negative?
methods for Number
and Time::Span
(#10601).
BigFloat
and BigDecimal
got rounding modes (#10618, #10798).
Collections
Likewise to Set
, the Hash
class includes now sub/superset checking methods (#7500):
Hash#subset_of?(other : Hash)
Hash#proper_subset_of?(other : Hash)
Hash#superset_of?(other : Hash)
Hash#proper_superset_of?(other : Hash)
Also, we generalized Number#step
with a new Steppable
module, that is included in Char
, Number
, Time
and Time::Span
(#10279).
Finally, it is now possible to #truncate
and Array
, to efficiently remove elements from both ends (#10712).
Crypto
New methods for getting peer certificates and signatures in OpenSSL
(#8005).
Files
Now it is possible to use a Path
for the methods in FileUtils
(#10747).
Networking
OAuth2::Client
supports the customization of its HTTP::Client
node (10452).
Runtime
The segfault handler is now implemented in Crystal, in practice meaning that the compilation process of Crystal is simpler: it does not require the former external libcrystal
. For package maintainers, this means building libcrystal.a
(which was part of the make deps
recipe) is obsolete now. The C code for this library has been removed and packaging instructions need to be updated. make deps
is no longer necessary for building arbitrary Crystal programs; now it only builds llvm_ext.a
, only required for linking against LLVM (for example when building the compiler itself).
Serialization
The Yaml parser now supports UUID
(#10715).
We have been able to do all of this thanks to the continued support of 84codes, Nikola Motor Company and every other sponsor. To maintain and increase the development pace, donations and sponsorships are essential. OpenCollective is available for that. Reach out to crystal@manas.tech if you’d like to become a direct sponsor or find other ways to support Crystal. We thank you in advance!