Crystal 0.13.0 has been released!
This release includes some compiler and standard library fixes, as well as a bunch of additions. Let’s see some of them.
Special handling of case with tuple literals
There’s now special language support for matching multiple values. For example, FizzBuzz
can now be written like this, using an underscore (_
) to match any value:
(1..100).each do |i|
case {i % 3, i % 5}
when {0, 0}
puts "FizzBuzz"
when {0, _}
puts "Fizz"
when {_, 0}
puts "Buzz"
else
puts i
end
end
With this new syntax you can also match types, and variables inside a when
body are known
by the compiler to have those types:
a = rand < 0.5 ? 1 : "hello"
b = rand < 0.5 ? 2 : "bye"
case {a, b}
when {Int32, Int32}
puts "Both ints: #{a + 1}, #{b + 1}"
when {String, String}
puts "Both strings: #{a.upcase}, #{b.upcase}"
else
puts "Other: #{a}, #{b}"
end
Backreferences in sub and gsub
String#sub
and String#gsub
now feature a syntax for backreferences, similar to Ruby’s.
For example:
puts "hello world".gsub(/([aeiou])/, "*\\1*") # => "h*e*ll*o* w*o*rld"
To implement this, gsub
does a quick check to see if the string has any backlash in it. If so,
for every match it will scan the string for backreferences. The quick check would make existing
code slower. However, most of the cases the replacement string is known at compile-time, so that
check disappears in release mode, thanks to LLVM.
Custom separator and quote for CSV
The separator and quote field for parsing CSV can now be specified at construction time, thanks to jreinert:
require "csv"
string = <<-CSV
name;value
foo;bar
CSV
CSV.parse(string, separator: ';') # => [["name", "value"], ["foo", "bar"]]
Random float
Now you can generate a random float between 0 and max
, or between a given float range,
thanks to AlexWayfer:
puts rand(1.5) # => 0.0369659
puts rand(1.5..2.5) # => 1.68439
Other changes
Be sure to read the full changelog, as there are more additions, small changes, bug fixes and optimizations.