Refactory scenario: removing conditional blocks and extracting code to a private method

This is a simple but very useful refactory strategy.

It allows you to easily make the code more readable and clear by having a method name that explains what’s going on and also avoiding blocks of conditionals by turning them into guard clauses.

Let’s use real code from a Rails action as an example, but this can be applied in any programming language:

# users/registrations#new
def new
  email = params[:email].strip.downcase
  @lead = Lead.find_or_initialize_by(email: email)

  unless @lead.persisted?
    valid_email_format = @lead.email.match(URI::MailTo::EMAIL_REGEXP).present?

    if valid_email_format && EmailVerificationService.new.valid?(email)
      @lead.valid = true
    end

    if @lead.valid
      clearbit_data = Clearbit.new.email_lookup(email)
      name_hash = clearbit_data.fetch('person', {}).fetch('name', {})

      if name_hash.present?
        first_name = name_hash.fetch('givenName', nil)
        if first_name.present? && first_name != 'Name'
          @lead.first_name = first_name
        end

        last_name = name_hash.fetch('familyName', nil)
        if last_name.present? && last_name != 'Name'
          @lead.last_name = last_name
        end
      end
    end

    @lead.save! if @lead.changed?
  end
end

Whaaaat?! Why is this action so long? What’s going on here!?

Yup that would also be my reaction seeing that amount of code in an action 😆

Even though it’s on a Users::RegistrationController, it’s doing many things with the Lead model. Yup, that’s how it is on real-life projects. 😉

However, should the programmer have to read every single line of code to grasp what’s going on there? Nope!

Extracting related logic to a private method

So the first thing I like to do is extract all the code that’s related to the same thing to a private method:

def new
  email = params[:email].strip.downcase
  @lead = Lead.find_or_initialize_by(email: email)

  personalize_the_signup_view
end

private

def personalize_the_signup_view
  unless @lead.persisted?
    valid_email_format = @lead.email.match(URI::MailTo::EMAIL_REGEXP).present?

    if valid_email_format && EmailVerificationService.new.valid?(email)
      @lead.valid = true
    end

    if @lead.valid
      clearbit_data = Clearbit.new.email_lookup(email)
      name_hash = clearbit_data.fetch('person', {}).fetch('name', {})

      if name_hash.present?
        first_name = name_hash.fetch('givenName', nil)
        if first_name.present? && first_name != 'Name'
          @lead.first_name = first_name
        end

        last_name = name_hash.fetch('familyName', nil)
        if last_name.present? && last_name != 'Name'
          @lead.last_name = last_name
        end
      end
    end

    @lead.save! if @lead.changed?
  end
end

Ok I already see a significant improvement, if the developer reading this code isn’t interested in code related to personalization of the view for the Lead, he can stop there 👍

Removing conditional blocks

So now we can get rid of some conditional blocks by turning them into guard clauses:

def personalize_the_signup_view
  return if @lead.persisted?

  valid_email_format = @lead.email.match(URI::MailTo::EMAIL_REGEXP).present?

  if valid_email_format && EmailVerificationService.new.valid?(email)
    @lead.valid = true
  end

  return unless @lead.valid

  clearbit_data = Clearbit.new.email_lookup(email)
  name_hash = clearbit_data.fetch('person', {}).fetch('name', {})

  return if name_hash.blank?
  
  first_name = name_hash.fetch('givenName', nil)
  if first_name.present? && first_name != 'Name'
    @lead.first_name = first_name
  end

  last_name = name_hash.fetch('familyName', nil)
  if last_name.present? && last_name != 'Name'
    @lead.last_name = last_name
  end

  @lead.save! if @lead.changed?
end

I find it easier to understand what’s going on. You can see that if the Lead is already in the database, we stop there. If the email has an invalid format, we won’t even bother calling Clearbit API, and we also return early if Clearbit doesn’t return the kind of data we are expecting.

Yeah, I know there are other ways to optimize this code even more, but the goal of this post is to show only “one thing”. One example, so it’s easier to understand.

How to open mac localhost on iPhone or iPad

A quick tip that not many people know to access your development server on your Apple gadgets easily.

If they are on the same network, it’s as easy as accessing YourMacName.local on your iPhone or iPad browser. For example http://wall-e.local.

It makes it easier to test responsive layouts or any other thing on your gadgets.

If you don’t know your computer’s name, go to “System Preferences” and then into “Sharing. It should be the first thing here.

Have your terminal troll you when you make a typo

Sometimes when we are programming, we are typing one thing but thinking about another as our fingers can’t type as fast as we think, right? So if we are not careful, we get typos.

The most frequent typo is changing the order of a couple of letters like “gti” instead of “git or “sl” instead of “ls”.

So what about turning these small mistakes into something funny? Allow your terminal to troll you when you make those mistakes 😁

When you type “gti” you will see:

reproduction of the gti typo

And when you type “ls” you’ll see a Steam Locomotive:

demo of the sl typo

You can easily install them with brew:

brew install gti
brew install sl

Or check their repos (gti and sl) to see how to install on other platforms.

Do you know any other package like that? Let me know in the comments below 👍

Programming isn’t for me, programming is too hard… true and true but here’s how to make it easier and why it’s worth it

In the beginning, you were like:

Wow, I love playing video games! It would be awesome if I created my own… I’m gonna start learning how to program! 😎

Or maybe…

Wow, this site is beautiful! That’s it! I’m gonna learn how to create websites as beautiful as this! It shouldn’t be hard…

And then you start doing some PHP tutorials, read a bunch of blog posts, articles about frameworks, databases, gems that are awesome, do Rails for Zombies, sign up for Code Academy

But a few weeks or a couple months later…

Fuck it! I’m tired of reading a hundred tutorials, searching for the best plugins, learning the framework that’s trending this week, controllers, models, mailers, IDEs, terminal errors, git branches, SSL, DNS, debugging errors…

Programming isn’t for me!
(╯°□°)╯︵ ┻━┻)

Is it your problem? Hell NO!

Programming isn’t something fun!

Yes, I said it!

But do you know what’s really fun? Building stuff! And it comes with that fulfilling sense of accomplishment when you finally finish building something.

And this was the reason why I endured the rest of my digital design undergrad but decided to be a programmer: being able to turn my ideas into reality!

A programmer is one of the few professions that enables you to create something that other people can use, from basically nothing. And what you create can even make people’s life somehow better, easier or happier! How awesome is that!?!?

How should I start then?

With a small personal project. Maybe a static website that helps people relax or that will blow people’s mind with your creativity (turn your sound on), maybe something useless or something exciting like helping people watch grass grow in real-time.

The most important thing is that it needs to be a small project, something you can build in a couple weeks or maybe in 1 weekend. The main goal is enduring the process but finally creating something from nothing for the first time!

Build something you think its funny, something you can show to your friends and family, something they can use!

Start right now!

Until you build your first personal project, momentum is key. Right after finishing this blog post, take 15 minutes to follow these simple steps (yup, you can spare 15 minutes):

  1. remember some ideas you already had or that you wrote down somewhere;
  2. choose the smallest one that you feel like building it right now;
  3. check your calendar and reserve times, nights and days on it that you will dedicate to building this project!
  4. JUST DO IT!

Have no idea how to even begin?

Ok, I understand it. But I’m gonna take that excuse from you too: just leave a comment with your questions and I’ll give you some directions 😁

Must-have gem for rails projects: zero downtime migrations

This is one of the most useful Ruby gems I’ve discovered in a while: zero_downtime_migrations, it catches problematic migrations at development time.

Problems such as:

  • Adding a column with a default in a single migration;
  • Adding a non-concurrent index;
  • Mixing data changes with index or schema migrations;
  • Performing data or schema migrations with the DDL transaction disabled;
  • Using each instead of find_each to loop thru ActiveRecord objects when doing data changes;

And it doesn’t only catch the problem but it also teaches what you should do to avoid it 👏👏

Example from their README:

Solution of problem and solution

Seriously, share this gem with every Rails developer you know and make everybody’s life a bit easier 😁

Beholddy, easily monitor youtube for new videos of specific subjects

On this last weekend, me and a couple friends hacked together a beautiful UI for a tool that I built to scratch my own itch: monitor youtube for new videos on specific subjects. Meet Beholddy:

This cute beholder, with its unique features, will monitor youtube for every new video uploaded and let you know as soon as a new that meets your criterias comes out!

I currently use it to find out:

  • videos of huge channels of a topic that I could take advantage on (by getting into their “similar videos”, for example);
  • discover smaller channels talking about subjects similar to mine and maybe propose a partnership;
  • monitor competitors;
  • new tips about videogames I enjoy 😜

But hey, this is me! Try it and maybe you will find other uses for it and don’t worry cause it has a free plan!

And please, give me some feedback on how you are using it and I will even add a couple more alerts to your free plan 😉

Someone coding

How to delete local git branches after the merge

From time to time we all get annoyed by the git branch autocomplete, which used to be so useful, but now makes us practically write the whole branch name! 😡

Why it keeps happening? Because we are awesome developers who use feature branch flow and now, after working so hard, we have dozens of branches on our local machine.

Yogo, can you tell me an easy way to clear these branches? I don’t wanna delete each one manually! 😩

I sure can, my friend! Here is an alias that I use to delete all my merged branches:

alias clear_merged_branches="git branch --merged | egrep -v '(^\*|master|production)' | xargs git branch -d"

It will only leave the “master” and “production” branches, which you can easily change on that code. Besides the branches that haven’t been merged into master, of course.

Remember to use this alias while you are on the “master” branch 😉

Update

As lpmusix pointed out, you can also use it as a git alias. Add to the alias section of your ~/.gitconfig:

cb = "!git branch --merged | egrep -v '(^\\*|master|production)' | xargs git branch -d"