Ruby Symbol GC Misconception

Its Sunday, but I just finished interviewing a Ruby developer to join my team. He will not be joining the team, but not for reasons posted here.

I showed him a piece of code from that was like…

def hire
  data = JSON.parse(params[:data], symbolize_name: true )
  # more stuff wich included N+1 Query
end

He was quick to point out that the I am creating symbols from a user input. I was curious why he thought it was a problem and he described that Symbols in Ruby don’t get garbage collected. Knowing it was a little higher than what I expected I asked “which interview question website did you pick it from” and I figured out it was Toptal.

That is not entirely true if you are on Ruby 2.2 or higher.

There are two kinds of Symbols in Ruby. Some are mortal while others are immortal. Most symbols you make dynamically get cleared.

A good article on that matter

Ruby API Testing With VCR

The days of isolated websites and apps are over. Applications interact with one another through APIs to access each others specialization. You should write a Ruby GEM for the task. But how are you going to mock API calls. Answer is vcr will and you don’t!

A simple example would be as follows. The API is written using HTTParty but should work with any thing…

it "fetches price trends" do
  VCR.use_cassette "zumper/san-frasisco-ca/lower-haight" do
    price_trends = Zumper::API.get_price_trends(
      city: "san-frasisco",
      neighborhood: "lower-haight",
    )
    # do some thing with price_trends
  end
end

Here, on your first call, the response will be recorded by you VCR in to a file. This file will be used to replay the API call making it fast and deterministic.

If you are wondering why…

  • Tests should run fast and HTTP is a notoriously slow protocol
  • Tests need to be deterministic - running on http you might come up with internet errors

I was asked what if the API changes…

Firstly and most importantly, APIs shouldn’t implement breaking changes. End points need to be thoroughly tested and changes shouldn’t break tests. Breaking changes can come from a new version ex: v1 -> v2. But it is not under your control.

Secondly, vcr is for you when developing, so the tests run faster. I normally have a VPS that momentarily deletes vcr cassettes and run tests again.

I am out! Happy & snappy testing!

Back to teaching

I loved sharing my knowledge. In the past I used videos and hosted them on YouTube. I am hoping to make a come back in the next few months. The focus of the first series of video tutorials would be Ruby.

The Ruby tutorial will comprise a starter edition and a pro edition.

The starter edition is targeting newbies to coding. This will mostly be video tutorials and be verbose, so that users can visually follow and understand. This is expected to be named Ruby Lite. I will be using a blog post with details and a slide-show with summary which both will be made available through my website.

The pro edition would be for existing software developers. As an existing software developer learning Scala, I believe video tutorials are a waste of time and test is the best way to go forward.

I am actually writing them for my customers/designers/developers who join my teams so that they get to know the language and eventually the stack (Rails, Sinatra, Padrino, Grape).

So yes, once Ruby is complete, I am intending to make tutorials on Rails, Sinatra, Padrino and Grape. But it will take time.

Split Padrino Controllers

Some things are bigger the better. But some, when they are big, are truly ugly! Code makes the top of that list. I recently opened a Padrino class with 2900+ lines of pure spaghetti. It was traumatic to touch that file that had countless number of actions in it.

Making an admin section? Wondering how to avoid writing every thing in app/controllers/admin.rb? Well you are of luck and the approach is really simple.

Xygen is not its real name.

# file: app/controllers/admin/products.rb
class Xygen::App.controllers :admin do
  layout :admin

  get '/products' do
    @products = Product.all
    render 'admin/products/index'
  end

  # get '/products/:id' do
  # end
  # and so on...
end

Now that you are splitting code in to files, you might wonder where to add common code.

There are few places you can add them to.

  1. Helpers (my preferred)
  2. app.rb (lets keep that slim too, shall we?)
# file: app/helpers/admin.rb
class Xygen::App.helpers do
  def authenticate
    # your foo doo
  end
end

And finally use it in your code…

# file app/controllers/admin/products.rb
class Xygen::App.controllers :admin do
  before { authenticate }
  # rest of the code ...
end

TextbookValet Gets Highrise Integration

Highrise is a CRM ideal for small businesses. While we at TextbookValet are not entirely small, and have built required CRM features to our app, we used Highrise integrations to reach out to multiple services used in the hiring processes.

We worked with 5 services (possibly more that I am not aware) that integrated with Highrise. They will make contacts with necessary information set as custom fields. Then our web app will connect to Highrise through the API and synchronize with it.

This way we only need to integrate one service, saving us time, and money.

Link: Highrise API Gem