In the Ruby world, we all strive for efficiency. After all, one of Rails’ main draws is its rapid development cycle. In this article, I’d like to share a couple of techniques that can help speed up this process even more and in the meantime, make you feel like a coding ninja.
Rails Console in Sandbox Mode
Sometimes, there comes a potentially scary time when you have to log in to the production server and boot up the old rails console to do some digging or, even worse, type some (potentially dangerous) commands. Not to worry though, sandbox mode will come to the rescue. When starting the console just do it with a flag and you will be greeted with this reassuring message.
$ rails console --sandbox
Loading production environment in sandbox (Rails 6.1.3.2)
Any modifications you make will be rolled back on exit
Semicolons Prevent Printing Return Values
Among the many things that I love about Ruby is that it returns the value of the last executed instruction in the method. Sometimes, however, especially when working in the console, it can be a nuisance as the console prints the return value of every expression and can effectively clog up the screen. We can prevent that with a semicolon.
pry(main)> users = User.all;
pry(main)> users.class
=> User::ActiveRecord_Relation
pry(main)> users.count
(2.8ms) SELECT COUNT(*) FROM "users"
=> 100
Tap
tap is an awesome method which when used on an object, passes it to a block and then returns the final object. Let’s say we have a piece of code like this:
user = User.new
user.name = 'John Doe'
user
User.new.tap do |user|
user.name = 'John Doe'
end
Notice the awkward last line returning user. Using tap, not only can we get rid of that line, but of the variable assignment as well!
Passing a block to a new array/hash
Creating and populating arrays and hashes is the bread and butter of any web engineer. You can define their default values by passing a block when creating them.
pry(main)> Array.new(5) { rand(10) }
=> [1, 6, 7, 9, 0]
With hashes we can define the default value of a new key.
pry(main)> hash = Hash.new { |k,v| k[v] = [] }
=> {}
[17] pry(main)> hash[:new_key]
=> []
each_with_object
Everyone learns early in their Ruby career that fors and whiles stink and each is the best way to iterate through a collection. Some then learn that each_with_index exists. My favorite, however, which I sadly rarely ever see is each_with_object. It takes an object such as an argument, gives you access to it within the block and then returns it’s final value.
pry(main)> %w(very important data).each_with_object([]) do
|str, passed_object|
passed_object << str.length
end
=> [4, 9, 4]
Combining methods to create fancy loops
While researching coding interview problems I found that the single most important skill to have is to create an array of strings and to successfully index each string present in that array. Naturally, we need to do it in the most efficient way therefore we throw a hashmap at it.
pry(main)> %w(foo foo bar foo bar)
.each.with_index
.with_object(
Hash.new{ |k,v| k[v] = [] }
) do |(value, index),passed_hash|
passed_hash[value] << index
end
=> {"foo"=>[0, 1, 3], "bar"=>[2, 4]}