Hashrocket.com / blog

Large best of til

Best of TIL Year One: Ruby

posted on and written by in

Image 100x100 jake worth

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.

&gt; %=Jurassic Park=
=&gt; "Jurassic Park"
&gt; % Ghostbusters 
=&gt; "Ghostbusters"

It even works with balanced characters

&gt; %(The Goonies)
=&gt; "The Goonies"

This is useful for defining a string that has both types of quotes

&gt; %[That'll be the "day"]
=&gt; "That'll be the \"day\""

It's also useful for creating horribly obfuscated code

&gt; %=what===%?what?
=&gt; 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.

Posted in Development