
Small reference in the Ruby documentation for goruby: ruby-doc.org/3.3.6/extension…
squadracer.com/en/weeklytips…
goruby
Ruby not concise enough? In the source code, you’ll find a file called golf_prelude.rb. Include it in the compilation and you get goruby where each method has its own abbreviation, the String class behaves like an Array, … to be as concise as possible!
Links to Ruby documentation for
||= (ruby-doc.org/3.3.6/syntax/as…)
defined? (ruby-doc.org/3.3.6/syntax/mi…)
squadracer.com/en/weeklytips…
||= vs defined?
Cache false/nil
||= is the most common way of caching. Except that it doesn’t handle false and nil! defined? can be a solution by checking whether the variable is defined. ⚠️ Be sure to take into account when the parser defines the variable!
Link to Ruby documentation for local variables: ruby-doc.org/3.3.6/syntax/as…
squadracer.com/en/weeklytips…
A more interesting example highlighting the parser step. In the 1st if, the parser sees and creates the a variable after the condition, which will therefore be false at runtime. In the 2nd case, it sees and creates b before! (A if inline is therefore not equivalent!)
local variable, a detail on how they work
They are created when the parser encounters them, not dynamically at runtime! Furthermore, a if does not create a new scope, making variables accessible after the scope has ended. This is also the case for unless, while, until and for.
Link to Ruby documentation for tap: ruby-doc.org/3.3.5/Kernel.ht…
squadracer.com/en/weeklytips…
The main benefit is to be able to alter the object in the method chain. Another use case is to be able to inspect an intermediate state without having to rewrite everything.
tap
For method chaining
The tap method, defined in Kernel, returns self which is passed as a block argument. To be distinguished from then, which returns the result of the block.
Link to Ruby documentation for double splat operator: ruby-doc.org/3.3.5/syntax/ca…
squadracer.com/en/weeklytips…
⚠️ There is a subtle difference with the splat operator. It doesn’t handle nil. Well, not yet, because after more than 10 years, it will in Ruby 3.4.0 (see Issue 20064: bugs.ruby-lang.org/issues/20…).
**{double splat operator}
The double splat operator (or keyword splat) has been around since Ruby 2.0. It’s the equivalent of the splat operator but for Hash.
fast-ruby presents some interesting comparisons, like while vs loop, which do you think is faster? github.com/fastruby/fast-rub…
Link to Ruby documentation for Benchmark: ruby-doc.org/3.3.5/stdlibs/b…
squadracer.com/en/weeklytips…
Comparing implementations is generally more interesting, and can be done with bm or bmbm. The bmbm is run twice to « warm up » the code for a more accurate result. For example, compare flat_map and map { ... }.flatten and check that flat_map is indeed faster.
![require 'benchmark'
result = Benchmark.bmbm do |bm|
list = (0..1_000).to_a
bm.report "flat_map" do
list.flat_map { |x| [x, x * x] }
end
bm.report "map.flatten" do
list.map { |x| [x, x * x] }.flatten
end
end
puts result
# Rehearsal -----------------------------------------------
# flat_map 0.000085 0.000000 0.000085 ( 0.000085)
# map.flatten 0.000230 0.000001 0.000231 ( 0.000231)
# -------------------------------------- total: 0.000316sec
#
# user system total real
# flat_map 0.000080 0.000000 0.000080 ( 0.000078)
# map.flatten 0.000215 0.000001 0.000216 ( 0.000214)](https://pbs.twimg.com/media/GYT_xcAWMAASumH.jpg?name=small&format=webp)
ALT require 'benchmark' result = Benchmark.bmbm do |bm| list = (0..1_000).to_a bm.report "flat_map" do list.flat_map { |x| [x, x * x] } end bm.report "map.flatten" do list.map { |x| [x, x * x] }.flatten end end puts result # Rehearsal ----------------------------------------------- # flat_map 0.000085 0.000000 0.000085 ( 0.000085) # map.flatten 0.000230 0.000001 0.000231 ( 0.000231) # -------------------------------------- total: 0.000316sec # # user system total real # flat_map 0.000080 0.000000 0.000080 ( 0.000078) # map.flatten 0.000215 0.000001 0.000216 ( 0.000214)
Need to speed up?
Benchmark allows you to measure the execution time of a block with measure. You’ll find user and system CPU times, as well as the sum of the two. In brackets, the actual time. The unit is seconds. In this example, it’s long but not CPU-intensive.
Link to Ruby documentation for exception handling: ruby-doc.org/3.3.5/syntax/ex…
squadracer.com/en/weeklytips…
The else is only allowed if there are rescue and can therefore be used wherever rescue can be used: block, method and even class!
What’s the point, given that the code could have been placed in the begin? Well, the code in the else is no longer protected by the rescue. This means you don’t have to deal with an unexpected exception as a side-effect.




![3.times.to_a.tap { _1[1] = 5 } # [0, 5, 2]
# vs
a = 3.times.to_a
a[1] = 5
a # [0, 5, 2]
3.times .tap { p _1 } # #<Enumerator: 3:times>
.map { _1 * 2 } .tap { p _1 } # [0, 2, 4]
.filter(&:positive?) # [2, 4]](https://pbs.twimg.com/media/GabJw57XsAASvOm.jpg?name=small&format=webp)

![[*nil] # []
{**nil} # TypeError (< 3.4.0)
{**nil} # {} (>= 3.4.0)](https://pbs.twimg.com/media/GZgpdUAXsAMCUK5.jpg?name=small&format=webp)




