Crystal 0.18.0 has been released (a while ago).
Updates:
UnionsThese were always available, but they were not able to be accessed since they did not have a type name. Most noticeably you would have used them when declaring an hash or other type that could house many types.
Now being able to access unions directly, we can do thinks such as extract json, which usually has many data types throughout the struct, into other containers such as arrays. In this example we parse a json string and map them to a Result class which uses the unions of Point and Circle as the type definition of the variable shape. As the json is deconstructed and the mapping is done the union figures out which type the json string satisfies and automatically returns that type.
Code
require "json"
struct Point
JSON.mapping x: Int32, y: Int32
end
struct Circle
JSON.mapping center: Int32, radius: Int32
end
class Result
JSON.mapping shape: Point | Circle
end
result = Result.from_json(%({"shape": {"x": 1, "y": 2}}))
result # => Result(@shape=Point(@x=1, @y=2))
result = Result.from_json(%({"shape": {"radius": 1, "center": 2}}))
result # => Result(@shape=Circle(@center=2, @radius=1))
shapes = Array(Point | Circle).from_json(%([{"x": 1, "y": 2},
{"radius": 1, "center": 2}]))
shapes # => [Point(@x=1, @y=2), Circle(@center=2, @radius=1)]
Hashes, Enumerables, and block unpackingCrystal now has an Enumerable class which adds many methods which allow you to iterate an object on an object by object manner. This is similar to a "for each" loop in other languages, but instead exposes the map, and different flavors of the each method like ruby.
For example we can now enumerate a hash retrieving the key, value pairs in separate local scope variables:
Code
hash = {1 => "a", 2 => "b"}
hash.each do |key, value|
# Prints "1: a", then "2: b"
puts "#{key}: #{value}"
end
hash.map { |key, value| "#{key}: #{value}" } # => ["1: a", "2: b"]
Splats in yield and block argumentsWe can now give splat arguments to blocks and yields allowing us to easily pass on block arguments to other methods. This allows you to forward blocks of code to other methods which can in turn yield results. I am not sure if I would ever try using this.
Named tuples and arguments creation with string literalsI am not actually to fond of this change since I think it looks weird, but it is useful none the less. One particular example is the ability to create json objects with keys that have spaces (before I don't think it was possible unless you used a hash which is slower than turples for reasons outlined in previous updates).
Code
require "json"
{"hello world": 1}.to_json # => "{\"hello world\":1}"
Class variables are now inheritedI welcome this change as it brings classes a little bit closer to being more ruby like. Now Class variables (denoted with @@, rather than instance variables denoted as @) are inherited into subclasses, but each subclass can keep independent values.
In this example we have a class foo with a class variable. Bar inherits from foo also getting an exact copy of the variable. Although they share exact copies now, each class variable are able to work independent of each other:
Code
class Foo
@@value = 1
def self.value
@@value
end
def self.value=(@@value)
end
end
class Bar < Foo
end
p Foo.value # => 1
p Bar.value # => 1
Foo.value = 2
p Foo.value # => 2
p Bar.value # => 1
Bar.value = 3
p Foo.value # => 2
p Bar.value # => 3
Notable mentions- OpenSSL and TLS improvments
- Functional language generics for user defined classes
- Other fixes to the standard library and error messages
This post was edited by AbDuCt on Jun 19 2016 10:20pm