Hashrocket Projects Ruby
Best of TIL Year One: Ruby
Here are some of the top Ruby posts from Today I Learned.
My goal with this series is to pause and highlight some of the top posts from the first year of Today I Learned. Today we'll look at Ruby, our third-most active channel.
Hashrocket invested early in Ruby, and it remains the lingua franca of our company. Though many of us enjoy hacking on JavaScript, Elixir, Go, Clojure, and other languages, Ruby is still a well-worn and trusty tool. We travel to Rails Conf and Ruby Conf each year, and host our own annual Ruby conference in St. Augustine. There's a cache at Hashrocket to an elegant line of Ruby, because it's a language we all know well.
Here are the top five most liked Ruby posts, in order, from the first year of Today I Learned.
Enjoy!
Ruby String Mutability (Vinicius Negrisolo)
Until Ruby 3 we need to explicitly call the method freeze
on literal strings, so they become immutable. And, if you have a lot of literal strings in a file, this will be very repetitive and verbose. In order to let our code cleaner there is a magic comment that can be added in the top of each file.
the magic:
# frozen_string_literal: true
And it is done, all literal string are frozen now :)
example:
class Unfrozen
def foo
'bar'
end
end
class StringFrozen
def foo
'bar'.freeze
end
end
# frozen_string_literal: true
class ClassFrozen
def foo
'bar'
end
end
To test that:
require 'spec_helper'
describe 'Ruby String Mutability' do
it 'validates string mutability' do
expect(Unfrozen.new.foo.frozen?). to be false
expect(StringFrozen.new.foo.frozen?). to be true
expect(ClassFrozen.new.foo.frozen?). to be true
end
end
Randomized with seed 51265
.
Finished in 0.00179 seconds (files took 0.45396 seconds to load)
1 example, 0 failures
\o/
Ruby Retry- Where you been? (Micah Cooper)
For some reason, I never knew about ruby's retry
keyword. The more you know...
def api_request
TwitterWrapper.make_request # Throws a ServiceUnavailabe(506)- Server overloaded
rescue ServiceUnavailable => error
retries = retries.to_i + 1 # Increment a retry counter
retries < 5 ? retry : raise(error) # run the method again until "retries is exceeded"
# notice the local variable "retries" is persisted through retries
end
You could put a sleep in there if you wanted to wait a certain amount of time before retrying.
h/t Vinicius Negrisolo
Percent Notation (Josh Branchaud)
Ruby has many uses for the %
character. One of the more obscure uses is as
a notion for custom delimited strings. Use the percent notation with a
non-alphanumeric character to surround a string.
> %=Jurassic Park=
=> "Jurassic Park"
> % Ghostbusters
=> "Ghostbusters"
It even works with balanced characters
> %(The Goonies)
=> "The Goonies"
This is useful for defining a string that has both types of quotes
> %[That'll be the "day"]
=> "That'll be the \"day\""
It's also useful for creating horribly obfuscated code
> %=what===%?what?
=> true
h/t Josh Davey
Ruby array shortcuts - "&:" and "&method" (Vinicius Negrisolo)
Call a method on every items with &:
So this:
[:foo, :bar].each do |item|
item.to_s
end
Can be reduced to:
[:foo, :bar].each(&:to_s)
But, what if you want to call a method for each item in an array, and this item should be a parameter for this method?
Call a method with every items as a parameter with &method
So this:
[:foo, :bar].each do |item|
puts(item)
end
Can be reduced to:
[:foo, :bar].each(&method(:puts))
A high level view of RSpec tests (Chris Erin)
Test files in ruby/rspec can grow to gigantic soul crushing sizes, which makes it hard to really get a sense of what tests are in the file and where. This is troublesome when trying to determine a sensible place to add a new test to the already gigantic file.
To get a better sense of the structure of the file you can combine the dry-run
and format
options for readable, hierarchical documentation in a small amount of time.
$ rspec -fdoc --dry-run specs/my_massive_test_file_spec.rb
Conclusion
Thanks to Vinicius, Micah, Josh, and Chris for these posts.
Today I Learned had a spike in traffic near the beginning of the year, and these posts are mostly from that time. But there's a lot of great Ruby tips from earlier. See them all here:
https://til.hashrocket.com/ruby
Keep instantiating those objects, and learning every day.
This blog post is part three of a series; here's part one and two. Next, we will look at the top command line posts from year one.