Posts in english

Today we reach the end of a trip. Carlos Antonio, our first employee, is moving forward after 5 years at Plataformatec.

During this time, we have learned a lot, made some mistakes, grew together as people and as a company. In this blog post, we would like to share a bit of this story and what Carlos is leaving as legacy to us.

A story about Open Source

Carlos’ relationship with Plataformatec started with Open Source. When Carlos joined our team, back in August 2009, Plataformatec existed as a company only for 6 months and we were very excited to have him aboard. After all, he was the #1 employee.

At the time, the choice was really clear: Carlos had done many contributions to our only Open Source project at that point, Inherited Resources, and from his contributions we observed many of the traits that he exhibited throughout his stay at Plataformatec: tidy code, excellent communication skills and a great ability to evaluate trade-offs.

Being our first employee, Carlos helped us perpetuate those qualities as part of Plataformatec’s culture.

Focused

We often promote feedback between our team members and one word that was frequently used to describe Carlos is: focused.

Focus, on its own, can be a dangerous trait. Some people can focus and, as a consequence, lose the ability to understand how all components fit together. However, that was not Carlos’ case, as he aimed at having a holistic view of his environment and tasks, their causes and consequences. For example:

  • As the company grew, Carlos was always interested in understanding and participating in its diverse activities

  • At every project he worked, he was attentive to what makes the project important to the client. This often showed up when prioritizing features as Carlos would ask: “which one brings more value to the client?”

  • At the code level, Carlos sees how every piece of the application fits the whole design

Then, as a consequence of knowing how the involved components work, Carlos could always focus and reach a particular component to improve, fix or discuss it with precision.

Discussing trade-offs

My favorite quality in Carlos is his ability to understand and evaluate trade-offs.

When working together on a project, if I was unsure which solution would be the best to take, I could always call Carlos and have a quick discussion. I would expose the options I had evaluated so far, Carlos would help me expand them, maybe add some options of his own, and we would debate which one would suit best the current project.

In those discussions, I never had to worry about proposing something silly nor have I heard Carlos saying “we don’t do X”. If something was a bad fit, Carlos often guided me to understand why that was a bad option on my own.

Of course, this always worked both ways. When Carlos had to call someone to discuss a possible solution, he was always open to the team feedback, suggestions and so on.

Farewell?

Most of all, Carlos is a great Open Source partner.

After Carlos joined us, we started a great partnership towards Open Source. Carlos and I were the ones behind the conception of both Devise and Simple Form which would become the biggest Open Source projects from Plataformatec inside the Rails community.

Carlos is also a member of the Rails Core Team which means there are still plenty of opportunity for us to work together on Devise, Simple Form, and many other Open Source projects to come.

This is the end of a trip but definitely not the end of the journey.

We’ll see you around, Carlos!

Last month some amazing developers gave a sneak peek on how they write CSS in their companies – Mark Otto has written about CSS at GitHub, followed by Ian Feather’s post about Lonely Planet’s CSS and Chris Coyier write up about CodePen’s code – so I thought about sharing a bit of how we have been doing CSS in our projects here at Plataformatec over the last years.

After working on different projects with different styles of CSS, we wrote some Guidelines of what kind of code we would like to work with. These guidelines and some other practices have proven to be successful so far, and I want to tell you a bit about how we are doing this here.

Quick Facts

  • We use SCSS.
  • We usually just have Normalize.css (and sometimes Bootstrap) as third party dependencies.
  • Every developer in our team can jump through the codebase and work on our front end code.

Preprocessors and the Pipeline

We have always used Sass (with the SCSS syntax), using most of the Sass features wherever seemed fit and without making the code too complex to grasp so developers outside the project – or without a long experience with preprocessors – could get things done right after jumping in the code.

We do our best to use the most of the Rails Asset Pipeline. I know that it isn’t the most beloved Rails feature out there, but we are pretty happy with it. The Sprockets + Rails integration in Rails 4 is way better than it was before (you can read a bit about what was done on this post), thanks to the work of Guillermo, Rafael and Richard (the Sprocket heroes) and everybody else who contributed to sprockets-rails, and things will only get better on future releases. If you had a hard time with a Rails 3 app, I recommend that you try it out the latest releases and see what have improved.

Architecture

We don’t have strict guidelines about how we should organize and architect our CSS code, but we have some general rules and conventions. We organize most of our code into isolated partial stylesheets under something like modules or components. And we also break functions, mixins and generic placeholders into specific files and @import everything on the application application.css.scss file.

We do our best to keep our selectors small and using only classes, somewhat based on Wealthfront post on Functional CSS and OOCSS-ish. With this setup we can avoid complex nested blocks and keep things quite readable for everybody.

Linting

We don’t have a specific guideline on linting, but I have been experimenting with SCSS Lint on the project that I’m current working on, and I want to evolve this into a default configuration for future projects.

Frameworks

We have some different setup across our projects, but we usually just have Normalize.css as our “reset” stylesheet and everything else is custom made – buttons, grids, typography rules, etc. And of all the existing CSS frameworks out there, we had some encounters with Bootstrap and Foundation once.

Documentation

We love documentation – not obvious code comments, but real documentation that makes easier to understand how to use a specific piece of code.

We started writing docs for our CSS to make more sense out of a SCSS partial, so through a single file we can understand how the application can use those styles. We have adopted some loose form of the KSS syntax, because we currently don’t care about generating pretty styleguides with live examples of the styles in use. But the KSS format is human-readable enough and does the job of explaining the purpose of a set of classes to someone.

Sprites

Last year I created a gem called Spriteful to help us manage the image sprites in some projects without having to bring Compass and compass-rails as dependencies to our pipeline. Spriteful has proven useful to me and my coworkers, and now we can generate sprites and SCSS partials out of icons and SVG images with just a single command.

Some close friends from outside the company have used it on their projects and it’s awesome that someone else has found our little tool handy for this task.

Who’s in charge?

One important aspect of how we work is that every developer in the team is capable to work with the front end code of the application and build new things or fix existing bugs, not just turn some static markup into ERB blocks. This provides a higher sense of collective ownership of the code, instead of enlisting one or two programmers who are in charge of half of the application while everybody else works elsewhere without caring about that layer.


The article below was originally written by Kasper Timm Hansen (@kaspth on github & twitter) about his work during the Google Summer of Code 2013.

Kasper and I worked a lot changing the underlying implementation of the sanitize helper to give Rails developers a more robust, faster and secure solution to sanitize user input.

This new implementation should be fully backward compatible, with no changes to the API, which should make the update easier.

You can see more information about the previous and the new implementation on this talk I presented in a Brazillian conference this year (the slides are in English).

Now, I’ll let Kasper share his words with you.

Scrubbing Rails Free of HTML-scanner

Everyone, at least one time, has already needed to use the sanitize method to scrub some pesky HTML away.

<%= sanitize @article.body %>

If you were to run this on Rails 4.1 (and before) this would take advantage of the html-scanner, a vendored library inside Rails, for the sanitization. Since the summer of 2013 I have been working to destroy that notion by wiping the traces of html-scanner throughout Rails. Before you become concerned of my mental health, I didn’t do this unwarranted. I’m one of the Google Summer of Code students working on Ruby on Rails. My project proposal was to kick html-scanner to the curb (technical term) and grab a hold of Loofah instead. Why did the old library need replacing, though?

The out washed HTML-scanner

html-scanner has been with us for a long time now. The copyright notice in the library clocks it in at 2006, when Assaf Arkin created it. This library relies on Regular Expressions to recognize HTML (and XML) elements. This made the code more brittle. It was easier to introduce errors via complex Regular Expressions, which also gave it a higher potential for security issues.

The Rails Team wanted something more robust and faster, so we picked Loofah. Loofah uses Nokogiri for parsing, which provides a Ruby interface to either a C or Java parser depending on the Ruby implementation you use. This means Loofah is fast. It’s up to 60 to 100% faster than html-scanner on larger documents and fragments.

I started by taking a look at the SanitizeHelper in Action View, which consists of four methods and some settings. The four methods of the are sanitize, sanitize_css, strip_tags and strip_links.

Let’s take a look at the sanitize method.

Comparing with the old implementation, sanitize still uses the WhiteListSanitizer class to do it’s HTML stripping. However, since Action View was pulled out of Action Pack and both needed to use this functionality, we’ve extracted this to it’s own gem.

Developers meet Rails::Html::WhiteListSanitizer

When you use sanitize, you’re really using WhiteListSanitizer‘s sanitize method. Let me show you the new version.

def sanitize(html, options = {})
  return nil unless html
  return html if html.empty?

No surprises here.

  loofah_fragment = Loofah.fragment(html)

The first trace of Loofah. A fragment is a part of a document, but without a DOCTYPE declaration and html and body tags. A piece of a document essentially. Internally Nokogiri creates a document and pulls the parsed html out of the body tag, leaving us with a fragment.

  if scrubber = options[:scrubber]
    # No duck typing, Loofah ensures subclass of Loofah::Scrubber
    loofah_fragment.scrub!(scrubber)

You can pass your own Scrubber to sanitize! Giving you the power to choose if and how elements are sanitized. As the comment alludes, any scrubber has to be either a subclass of Loofah::Scrubber or it can wrap a block. I’ll show an example later.

  elsif allowed_tags(options) || allowed_attributes(options)
    @permit_scrubber.tags = allowed_tags(options)
    @permit_scrubber.attributes = allowed_attributes(options)
    loofah_fragment.scrub!(@permit_scrubber)

We have been very keen on maintaining backwards compatibility throughout this project, so you can still supply Enumerables of tags and attributes to sanitize. That’s what the PermitScrubber used here handles. It manages these options and makes them work independently. If you pass one it’ll use the standard behavior for the other. See the documentation on what the standard behavior is.
You can also set the allowed tags and attributes on the class level. Like this:

Rails::Html::Sanitizer.allowed_tags = Set.new %w(for your health)

That’s simply what allowed_tags and allowed_attributes methods are there for. They’ll return the tags or attributes from the options and fallback to the class level setting if any.

  else
    remove_xpaths(loofah_fragment, XPATHS_TO_REMOVE)
    loofah_fragment.scrub!(:strip)
  end

The StripScrubber built in to Loofah will strip the tags but leave the contents of elements. Which is usually what we want. We use remove_xpaths to remove elements along with their subtrees in the few instances where we don’t. If you have trouble with the syntax above, they’re XPath Selectors.

  loofah_fragment.to_s
end

Lastly we’ll take the elements and extract the remaining markup with to_s. Internally Nokogiri will call either to_xml or to_html depending on the kind of document or fragment you have.

Rub, buff or clean it off, however you like

So there you have it. I could go through how the other sanitizers work, but they’re not that complex. So go code spelunking in the source.

If this was the first time you’ve seen a Loofah::Scrubber, be sure to check out the source for PermitScrubber and see an example of how to implement one. You can also subclass PermitScrubber and get the sanitization you need without worrying about the implementation details of stripping elements and scrubbing attributes. Take a look at TargetScrubber – the weird PermitScrubber – and how it uses that to get scrubbing fast.

Before I scrub off though, I promised you an example of a custom scrubber. I’ll use the option that wraps a block here, but you could easily create a subclass of Loofah::Scrubber (in a helper maybe?) and override scrub(node). So here goes:

<%= sanitize @article.body,
  scrubber: Loofah::Scrubber.new { |node| node.name = "script" } %>

The code above changes all the HTML tags included in the article body to be a tag <script>.

<sarcasm>
If you’re going to introduce bugs, why not make everything a potential risk of running arbitrary code?
</sarcasm>


Rails 4 supports arrays fields for PostgreSQL in a nice way, although it is not a very known feature. In order to demonstrate its usage it’s useful to explain the context where this was used.

PostgreSQL Arrays and Rails Migrations

Suppose we have a Product model with the following fields: name, category_id and tags. The name field will be a simple string, category_id will be the foreign key of a record in the Category model and tags will be created by inputting a string of comma-separated words, so: “one, two, forty two” will become the tags: “one”, “two” and “forty two” respectively.

Creating these tables via migrations is nothing new, except for the column tags which will have the Array type in this case. To create this kind of column we use the following syntax in our migration:

create_table :categories do |t|
  t.string :name, null: false
end
 
create_table :products do |t|
  t.string :name, null: false
  t.references :category, null: false
  t.text :tags, array: true, default: []
end

Let’s explore what we can do with this kind of field using the postgres console:

$ rails db
> INSERT INTO products(name, category_id, tags) VALUES('T-Shirt', 3, '{clothing, summer}');
> INSERT INTO products(name, category_id, tags) VALUES('Sweater', 3, ARRAY['clothing', 'winter']);
> SELECT * FROM products;
1  |  T-Shirt  |  3  | {clothing, summer}
2  |  Sweater  |  3  | {clothing, winter}

As we can see we need to specify each tag following this syntax:

‘{ val1, val2, … }’ or ARRAY['val1', 'val2', ...]

Let’s play a little more to understand how this column behaves when queried:

> SELECT * FROM products WHERE tags = '{clothing, summer}';
1  |  T-Shirt  |  3  | {clothing, summer}
 
> SELECT * FROM products WHERE tags = '{summer, clothing}';
(0 rows)
 
> SELECT * FROM products WHERE 'winter' = ANY(tags);
2  |  Sweater  |  3  |  {clothing, winter}

As this example demonstrates, searching for records by an array with its values in the order they were inserted works, but with the same values in a different order does not. We were also able to find a record searching for a specific tag using the ANY function.

There’s a lot more to talk about arrays in PostgreSQL, but for our example this is enough. You can find more information at the PostgreSQL official documentation about arrays and its functions.

How Rails treats PostgreSQL arrays

It’s also valuable to see how to use the array field within Rails, let’s try:

$ rails c
 
Product.create(name: 'Shoes', category: Category.first, tags: ['a', 'b', 'c'])
#> 
 
Product.find(26).tags
#> ["a", "b", "c"]

So Rails treats an array column in PostgreSQL as an Array in Ruby, pretty reasonable!

Validations

We want each product to be unique, let’s see some examples to clarify this concept.

Given we have the following product:

Product.create(name: 'Shoes', category: Category.first, tags: ['a', 'b', 'c'])

We can easily create another one if we change the name attribute:

Product.create(name: 'Slippers', category: Category.first, tags: ['a', 'b', 'c'])

We can also create another product with different tags:

Product.create(name: 'Shoes', category: Category.first, tags: ['a', 'b'])

But we don’t want to create a product with the same attributes, even if the tags are in a different order:

Product.create(name: 'Shoes', category: Category.first, tags: ['a', 'c', 'b'])
#> false

As PostgreSQL only finds records by tags given the exact order in which they were inserted, then how can we ensure the uniqueness of a product with tags in an order-independent way?

After much thought we decided that a good approach would involve creating an unique index with all the columns in the products table but with tags sorted when a row is inserted in the database. Something like:

CREATE UNIQUE INDEX index_products_on_category_id_and_name_and_tags
ON products USING btree (category_id, name, sort_array(tags));

And sort_array is our custom function responsible for sorting the array, since PostgreSQL does not have a built in function like this.

Creating a custom function in PostgreSQL using PL/pgSQL

To create a custom function we used the PL/pgSQL language, and since we are adding database specific code like this we can’t use the default schema.rb anymore. Let’s change this in config/application.rb:

# Use SQL instead of AR schema dumper when creating the database
config.active_record.schema_format = :sql

With this configuration set, our schema.rb file will be replaced by a structure.sql file without side effects, our current migrations don’t need to be changed at all. Now we can create a migration with our sort_array code:

def up
  execute <<-SQL
    CREATE FUNCTION sort_array(unsorted_array anyarray) RETURNS anyarray AS $$
      BEGIN
        RETURN (SELECT ARRAY_AGG(val) AS sorted_array
        FROM (SELECT UNNEST(unsorted_array) AS val ORDER BY val) AS sorted_vals);
      END;
    $$ LANGUAGE plpgsql IMMUTABLE STRICT;
 
    CREATE UNIQUE INDEX index_products_on_category_id_and_name_and_tags ON products USING btree (category_id, name, sort_array(tags));
  SQL
end
 
def down
  execute <<-SQL
    DROP INDEX IF EXISTS index_products_on_category_id_and_name_and_tags;
    DROP FUNCTION IF EXISTS sort_array(unsorted_array anyarray);
  SQL
end

Now, let’s take it slow and understand step by step

CREATE FUNCTION sort_array(unsorted_array anyarray) RETURNS anyarray

The line above tells that we are creating a function named sort_array and that it receives a parameter named unsorted_array of type anyarray and returns something of this same type. This anyarray, in fact, is a pseudo-type that indicates that a function accepts any array data type.

RETURN (SELECT ARRAY_AGG(val) AS sorted_array
FROM (SELECT UNNEST(unsorted_array) AS val ORDER BY val) AS sorted_vals);

The trick here is the use of the function unnest that expands an Array to a set of rows. Now we can order these rows and after that we use another function called array_agg that concatenates the input into a new Array.

$$ LANGUAGE plpgsql IMMUTABLE STRICT;

The last trick is the use of the keywords IMMUTABLE  and STRICT. With the first one we guarantee that our function will always return the same output given the same input, we can’t use it in our index if we don’t specify so. The other one tells that our function will always return null if some of the parameters are not specified.

And that’s it! With this we can check for uniqueness in a performant way with some method like:

def duplicate_product_exists?
  relation = self.class.
    where(category_id: category_id).
    where('lower(name) = lower(?)', name).
    where('sort_array(tags) = sort_array(ARRAY[?])', tags)
 
  relation = relation.where.not(id: id) if persisted?
 
  relation.exists?
end

Case insensitive arrays

There is still a problem with our code though, the index is not case insensitive!  What if a user inserts a product with tags ['a', 'b'] and another one inserts the same product but with tags ['A', 'b']? Now we have duplication in our database! We have to deal with this, but unfortunately this will increase the complexity of our sort_array function a little bit. To fix this problem we only need to change one single line:

From this:

FROM (SELECT UNNEST(unsorted_array) AS val ORDER BY val) AS sorted_vals);

To:

FROM
(SELECT
  UNNEST(string_to_array(LOWER(array_to_string(unsorted_array, ',')), ','))
  AS val ORDER BY val)
AS sorted_vals);

The difference is that instead of passing unsorted_array directly to the function unnest we are transforming it in an String, calling lower on it and transforming it back to an Array before passing it on. With this change it doesn’t matter if the user inserts ['a'] or ['A'], every tag will be saved in lowercase in the index. Problem solved!

As we can see, it’s not an easy task to deal with uniqueness and arrays in the database, but the overall result was great.

Would you solve this problem in a different way? Share with us!

When we start programming with Ruby, one of the first niceties we learn about are the Ruby blocks. In the beginning it’s easy to get tricked by the two existing forms of blocks and when to use each:

%w(a b c).each { |char| puts char }
%w(a b c).each do |char| puts char end

The Ruby Community has sort of created a “guideline” for when to use one versus another: for short or inline blocks, use curly brackets {..}, for longer or multiline blocks, use the do..end format. But did you know there is actually a slight difference between them? So sit tight, we’ll cover it now.

Operators Precedence

Languages contain operators, and these operators must obey a precedence rule so that the interpreter knows the order of execution, which means one operator will be executed first if it has higher precedence than others in a piece of code. Consider the following example:

a || b && c

What operation gets executed first, a || b, or b && c? This is where operator precedence takes action. In this case, the code is the same as this:

a || (b && c)

Which means && has higher precedence than || in Ruby. However, if you want the condition a || b to be evaluated first, you can enforce it with the use of ():

(a || b) && c

This way you are explicitly telling the interpreter that the condition inside the () should be executed first.

What about blocks?

It turns out blocks have precedence too! Lets see an example that mimics the Rails router with the redirect method:

def get(path, options = {}, &block)
  puts "get received block? #{block_given?}"
end
 
def redirect(&block)
  puts "redirect received block? #{block_given?}"
end
 
puts '=> brackets { }'
get 'eggs', to: redirect { 'eggs and bacon' }
 
puts
 
puts '=> do..end'
get 'eggs', to: redirect do 'eggs and bacon' end

This example shows a rather common code in Rails apps: a get route that redirects to some other route in the app (some arguments from the real redirect block were omitted for clarity). And all these methods do is outputting whether they received a block or not.

At a glance these two calls to get + redirect could be considered exact the same, however they behave differently because of the blocks precedence. Can you guess what’s the output? Take a look:

=> brackets {..}
redirect received block? true
get received block? false
 
=> do..end
redirect received block? false
get received block? true

The curly brackets have higher precedence than the do..end, which means the block with {..} will attach to the inner method, in this example redirect, whereas the do..end will attach to the outer method, get.

Wrapping up

This blog post originated from a real Rails issue, where you can read a little bit more about the subject and see that even Rails got it wrong in its documentation (which is now fixed). The precedence is a subtle but important difference between {..} and do..end blocks, so be careful not to be caught off guard by it.

Do you know any other interesting fact about Ruby blocks that people may not be aware of? Or maybe you learned something tricky about Ruby recently? Please share it on the comments section, we would love to hear.


This post is part of a collection of posts we’re publishing on the subjects of low internal software quality, refactoring and rewrite.

Not only physical matter deteriorates, software does too

It’s known that physical matter deteriorates. People accept that and have always dealt with it. What people don’t accept so easily is that software “deteriorates” too. Unlike physical matter, it doesn’t happen due to some physical or chemical phenomenon. It usually happens because of some business change or people change. Let me give you an example.

Imagine you’re leading the tech or product team of a startup; you’re the CTO. You already launched your product’s first version, and it was a success. Your business model was validated, and now you’re in a growth stage. That’s awesome! But it has its costs, and it brings a new set of challenges.

The first version of your product is working, but the codebase is not in the shape you’ll need from now on. Maybe your team’s velocity is not as good as it used be. Your team keeps complaining about the code quality. The CEO and the product director want new features, and your current projections will not meet the business needs.

It’s not uncommon that one of the main sources of all these problems is the poor quality of your product’s codebase. You may need a refactor1 or a rewrite.

When the codebase is not in good shape, everyone can get frustrated

If the internal quality of your product is not good, everyone becomes frustrated.

Your whole team, including developers, will get frustrated because they would like to ship features faster, but the current code quality and architecture are not helping.

The IT, product, and software departments suffer because they’re not able to meet the expectations of the other departments.

The customer also suffers because of frequent bugs, how long it takes for them to be resolved, and how long it takes new features to be launched.

You get the picture.

Identifying the symptoms

It’s the leader’s job (let’s say the CTO) to identify when a refactor or a rewrite is needed. In order to do that, he or she can look around for some symptoms, like the ones below:

  • Everything is hard: Almost every feature or bug fix your team needs to do is hard. It was not always like that. You remember the good old days when your team was fast and everything ran smoothly.
  • Slow velocity: Your team’s velocity decreased or is decreasing. When you were building the first version of your product, it was fast to develop a new feature, and your team used to build lots of them every iteration. Now it’s different.
  • Slow test suite: Your test suite takes 10x, 20x, 30x more time to run than before.
  • Bugs that don’t go away: Your team fixes a bug, then in a week or so it appears again. Every now and then your team is fixing a regression bug.
  • Your team is demotivated: Your team keeps complaining that working in the project is not as productive as it was in the past. A single person can’t build one feature alone; there are too many moving parts.
  • Knowledge silos: There are some parts of the software that only a single developer knows well enough to maintain. It’s difficult for the rest of the team to work with that specific code.
  • New developer ramp-up time is taking too long: When new developers join the team, it takes too much time for them to be fully productive.

The reason you got into one of these situations is probably not a technical one. Maybe you needed to deliver too much, too fast while you were building the first version of your product. Maybe your team didn’t have the maturity and experience in the past they have now. Analyzing the root cause is important too, but you need to do something else. You need to solve your problem.

If you’re experiencing the symptoms above, you probably have a low internal software quality problem. Recognizing the symptoms is already a big step. The next step is to think of solutions. Some solutions you may take include refactoring or a rewrite process.

Refactor or rewrite?

There’s no definitive guide about when you should do a big refactor or a rewrite, because it depends a lot on your context. That said, there are some rules of thumb that you should consider when evaluating which solution to go with:

When to rewrite

  • The technology you use is outdated, and it’s not maintained anymore.
  • Your software is really slow, and changing the architecture is not enough or is not viable.
  • The supply of software developers that know the technology you use is low and decreasing.
  • There are new technologies that offer a significant advantage compared to what you’re using.

When to refactor

  • The technology you use is still maintained and relevant.
  • It’s viable to improve your application in an incremental fashion.
  • The problem you’re solving is just technical and not a business one.

Choosing one of these options is not an easy decision, and once you go with one of them, there will be an entire new set of concerns you’ll encounter. Stay tuned, in our next blog posts we’ll talk about what to consider when doing a big refactor or a rewrite.

Now I would like to know about your experiences. Have you ever been in a similar situation? How did you identify that your problem was low internal software quality? Please share with us!


  1. I prefer the term “code refurbishment”, but people aren’t generally used to it. So I’ll use refactoring in this blog post for the sake of clarity.