ABOUT ME Bozhidar (Божидар) a.k.a. Bug Lives in Sofia, Bulgaria Works at Toptal (https://toptal.com) Devoted to Emacs Author/maintainer of many Emacs and Clojure libraries and tools (e.g. Projectile, CIDER, nREPL, Orchard) Author of RuboCop, editor of the community Ruby Style Guide (https://rubystyle.guide), blah, blah, blah @bbatsov @bozhidarb on Reddit (long story) metaredux.com emacsredux.com
RUBY NOUN 1. A PRECIOUS STONE CONSISTING OF CORUNDUM IN COLOUR VARIETIES VARYING FROM DEEP CRIMSON OR PURPLE TO PALE ROSE. 2. A PROGRAMMING LANGUAGE OPTIMISED FOR PROGRAMMER HAPPINESS
REDUX ADJECTIVE 1. BROUGHT BACK, REVIVED EMACS ERA REDUX 2. (USUALLY POSTPOSITIVE) (ESP OF AN ARTISTIC WORK) PRESENTED IN A NEW WAY APOCALYPSE NOW REDUX
RUBY 3.0, THE SHORT (BORING) VERSION Released on Christmas 2020 The first major Ruby release since Ruby 2.0 (released way back in 2013) Official release notes (https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/) Detailed release notes (https://rubyreferences.github.io/rubychanges/3.0.html)
THE LONG VERSION The programming landscape has changed a lot in the past 10 years Rails is no longer hip Ruby is facing some fierce competition from newer languages like Clojure, Elixir, Go, Java, etc Ruby 3 has the ambitious goal to save Ruby’s future Matz has been talking about Ruby 3 since 2015 He had a keynote about Ruby 3 at EuRuKo 2016 in Sofia A lot of ideas for Ruby 3 have floated around since then
„There has been, for instance, a consistent migratory pattern from Ruby to node.js to Go, Rust, and Elixir. At first, each community is defined by its potential. But as that potential is realized, the community begins to be defined by its compromises. That change is felt most keenly by the people who were there first, who remember what it was like when anything seemed possible. They feel fenced in and so they move on, in search of their golden city.“ -- Zack Telman
case temperature when ..-15 puts "Deep Freeze" when -15..8 puts "Refrigerator" when 8..15 puts "Cold" when 15..25 puts "Room Temperature" when (25..) # notice the brackets here puts "Hot" end
RUBY 2.X If the last argument of a method call is a Hash, Ruby < 2.7 will automatically convert to keyword arguments. # Those are more or less the same in Ruby 2.x def foo(name, options = {}) end def bar(name, **options) End foo('Bruce Wayne', age: 10) bar('Bruce Wayne’, { age: 10 })
RUBY 3.X The abovementioned automatic conversion will stop. Ruby 2.7 emits a warning, which is an error in Ruby 3. # Those are different in Ruby 3.x def foo(name, options = {}) end def bar(name, **options) End # Works, because you’re still passing a hash foo('Bruce Wayne', age: 10) # Doesn’t work anymore bar('Bruce Wayne’, { age: 10 }) # Magic fix bar('Bruce Wayne’, **{ age: 10 })
# Those are more or less the same in Ruby 2.x def foo(name, options = {}) end def bar(name, **options) end # Let's pass a hash parameter foo('Bruce Wayne', {age: 10}) # Ruby 2.6: works # Ruby 2.7: warns: Using the last argument as keyword parameters is deprecated; maybe ** should be added to th e call # Ruby 3.0: ArgumentError (wrong number of arguments (given 2, expected 1)) bar('Bruce Wayne', age: 10) # => works h = {age: 10} bar('Bruce Wayne', **h) # => works, ** is mandatory # The last hash argument still allowed to be passed without {}: foo('Bruce Wayne', age: 10) # => works
When I first declared “Ruby3x3” in the conference keynote, many including members of the core team felt “Matz is a boaster”. In fact, I felt so too. But we did. I am honored to see the core team actually accomplished to make Ruby 3.0 three times faster than Ruby 2.0 (in some benchmarks). – Matz
As of Ruby 3.0, JIT is supposed to give performance improvements in limited workloads, such as games (Optcarrot), AI (Rubykon), or whatever application that spends majority of time in calling a few methods many times. Although Ruby 3.0 significantly decreased a size of JIT-ed code, it is still not ready for optimizing workloads like Rails, which often spend time on so many methods and therefore suffer from i-cache misses exacerbated by JIT. Stay tuned for Ruby 3.1 for further improvements on this issue.
# good def the_answer = 42 def get_x = @x def square(x) = x * x # Not (so) good: has side effect def set_x(x) = (@x = x) def print_foo = puts("foo") # bad def fib(x) = if x < 2 x else fib(x - 1) + fib(x - 2) end
FUN (AND USEFUL) TRIVIA Started as April’s Fool joke Matz liked the idea and it became a real feature Endless definitions should ideally: Be single-line Be free of side-effects
2010s were an age of statically typed programming languages. Ruby seeks the future with static type checking, without type declaration, using abstract interpretation. RBS & TypeProf are the first step to the future. More steps to come. — Matz
UNION TYPES & METHOD OVERLOADING class Comment # A comment can be made by a User or a Bot def author: () -> (User | Bot) # Two overloads with/without blocks def each_reply: () -> Enumerator[Comment, void] | { (Comment) -> void } -> void ... end
TYPEPROF IN ACTION # test.rb def foo(x) if x > 10 x.to_s else nil end end foo(42) # $ typeprof test.rb # Classes class Object def foo : (Integer) -> String? end
ractor1, ractor2 = *(1..2).map do Ractor.new do number = Ractor.recv Math.sqrt(number) end end # send parameters ractor1.send 3**71 ractor2.send 4**51 p ractor1.take #=> 8.665717809264115e+16 p ractor2.take #=> 2.251799813685248e+15
MISC CHANGES $SAFE and $KCODE lost their special meaning Assignment to numbered parameters (e.g. _1) will now result in a syntax error (it’s a warning in Ruby 2.7) yield in a singleton class definitions, which was deprecated in 2.7, will now result in a syntax error Another batch of IRB improvements Continued efforts to gemify the Ruby standard library (https://stdgems.org/)
Ruby 3.0 is a (major) milestone. The language is evolved, keeping compatibility. But it’s not the end. Ruby will keep progressing, and become even greater. Stay tuned! — Matz
RUBOCOP NOW SUPPORTS RUBY 3 Support was introduced in RuboCop 1.7 The bulk of the work so far was related to endless method definitions The support for Ruby 3.0 will mature and evolve over the course of the next few months