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.
Here are the top five most liked Ruby posts, in order, from the first year of Today I Learned.
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.
# frozen_string_literal: true
And it is done, all literal string are frozen now :)
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
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
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
Call a method on every items with
[:foo, :bar].each do |item| item.to_s end
Can be reduced to:
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
[:foo, :bar].each do |item| puts(item) end
Can be reduced to:
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
format options for readable, hierarchical documentation in a small amount of time.
$ rspec -fdoc --dry-run specs/my_massive_test_file_spec.rb
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:
Keep instantiating those objects, and learning every day.