Plataformatec Blog http://blog.plataformatec.com.br Plataformatec's place to talk about Ruby, Ruby on Rails and software engineering Tue, 30 Sep 2014 14:14:48 +0000 en-US hourly 1 http://wordpress.org/?v=4.0 The brand new Plataformatec blog http://blog.plataformatec.com.br/2014/09/the-brand-new-plataformatec-blog/ http://blog.plataformatec.com.br/2014/09/the-brand-new-plataformatec-blog/#comments Tue, 30 Sep 2014 12:00:35 +0000 http://blog.plataformatec.com.br/?p=4235 »]]> Today we are shipping a whole new design to improve your navigation and reading experience on our blog!

The brand new Plataformatec blog

Back in 2012 we rolled out our new visual identity and website, but we didn’t change our blog much at the time. So we decided that it was time to give some love to our blog and work on a full redesign over the last couple of months. We are really excited to release this work for everybody who reads our posts.

Fonts are bigger, colors are brighter and everything looks much better on your smartphone than it used to. We focused on improving the reading experience and on a more up to date look for our blog.

The whole development process was a great experience, from design to code, and I want to share some of the story of how we got there:

The (re)design process

At first we started sketching everything with HTML and CSS trying to put together our new look with some elements of our existing layout. As things started coming into shape, the next step was to put together a Jekyll website with all of our blog posts (thanks to jekyll-import) so we could easily test the new design against our existing content, rather than against a bunch of “Lorem ipsum” posts. This was really useful when reviewing the code snippets in our posts and visualizing how we could improve the syntax highlight using something else than the previous WordPress plugin we were using.

As we designed and prototyped each piece of our new layout, people outside the redesign project jumped in and participated through the Pull Requests that we used for building those blocks. A good part of our team was part of the whole process helping out with design/code/copy feedback.

One of the Pull Requests in our new theme

The Journey into WordPress

One of the first decisions was to keep using WordPress as our blog engine. Over the last years a lot of alternatives have surfaced (like Ghost), but WordPress still feels the most complete blogging solution for us, so we’re still using it for the time being.

Given that, one of our challenges was to learn how to work with WordPress and convert our design (built on top of a Jekyll site) into a WordPress theme that we could install in our blog. This task ended up being much easier than expected.

After finishing the first complete iteration of the layout, I spent a few days watching some of the WordPress courses on Treehouse to learn how to work with WordPress themes and the whole PHP API behind it. I’ve mixed together some Bash scripts, a proxy server built with rack-legacy and some Gulp tasks to automate a local WordPress environment and migrated our Jekyll templates into PHP ones and we were set!

This might sound a bit too complicated, but the idea of starting with Jekyll to focus on the design process and quick iterations to later worry about the theme “infrastructure” was a well payed bet so I didn’t have to juggle both problems at the same time.

The best is yet to come

The idea is to not stop here. There are still a lot of improvements we want to do on our blog and all the tooling we have put together makes it easy to jump back and iterate over the design and the code.

Let us know if you find anything broken around here and we will jump on it to fix it. We hope you enjoy this new look and feel while reading through our blog posts :heart:!


]]>
http://blog.plataformatec.com.br/2014/09/the-brand-new-plataformatec-blog/feed/ 3
Writing assertive code with Elixir http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/ http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/#comments Wed, 24 Sep 2014 12:00:01 +0000 http://blog.plataformatec.com.br/?p=4228 »]]> Functional languages are typically great languages for writing assertive code and Elixir is no exception. In this blog post, I would like to discuss some anti-patterns I have seen in Elixir code and how to rewrite them in a way to make the best of Elixir.

Pattern matching

Imagine you have a string with format foo=bar&token=value&bar=baz where you want to extract the value for the key token which may appear anywhere or not at all in the string.

Here is one solution a developer not very-acquainted with pattern matching would try:

def get_token(string) do
  parts = String.split(string, "&")
  Enum.find_value(parts, fn pair ->
    key_value = String.split(pair, "=")
    Enum.at(key_value, 0) == "token" && Enum.at(key_value, 1)
  end)
end

At first the code seems to work fine but once we go deeper we can see it makes many assumptions we have not really planned for!

For example, what happens if someone passes "foo=bar&token=some=value&bar=baz" as argument? The code will work and will return the string "some". But is that what we really want? Maybe we wanted "some=value" instead? Or maybe we wanted to reject it all together?

There are other examples where the code above would work by accident, possibly adding complexity to the codebase as other users may start to rely on such behaviour.

The most idiomatic way of writing the code above in Elixir is by using pattern matching:

def get_token(string) do
  parts = String.split(string, "&")
  Enum.find_value(parts, fn pair ->
    [key, value] = String.split(pair, "=")
    key == "token" && value
  end)
end

With pattern matching, we are asserting that String.split/2 is going to return a list with two elements. If someone passes "foo=bar&token&bar=baz", it will crash as the list will have only one element. If someone passes "token=some=value", it will crash too as it contains 3 items.

Our new code does not contain any of the accidental complexity of the previous one and it will also be faster. Any input that does not match the given pattern will lead to a crash, giving us the perfect opportunity to discuss and decide how to handle those corner cases.

Polymorphism is opt-in

Elixir provides protocols as a mechanism for polymorphism. A protocol allows developers to express they are willing to work with any data type, as long as it implements the protocols X, Y and Z.

I have previously compared Elixir protocols to alternatives in languages like Swift and Ruby. One nice aspect of Elixir protocols is that they are explicit, you need to explicitly outline and define a protocol for data structures to implement.

For example, one protocol in Elixir is the String.Chars protocol, which converts any data type to a string, if that data type can be converted to a human-readable string. The to_string function uses such protocol for conversions:

iex> to_string("hello")
"hello"
iex> to_string(1)
"1"
iex> to_string URI.parse("http://blog.plataformatec.com.br")
"http://blog.plataformatec.com.br"
iex> to_string %{hello: :world}
** (Protocol.UndefinedError) protocol String.Chars not implemented for %{hello: :world}

Imagine you have a function that converts underscores to dashes in a string:

def dasherize(string), do: String.replace(string, "_", "-")

Now imagine that at some point you decide to call to_string/1 before calling replace/3:

def dasherize(data), do: String.replace(to_string(data), "_", "-")

Albeit small, this is a drastic change to our code. Our dasherize function went from supporting only strings as argument to support a large number of data types. In other words, our code became less assertive and more generic.

That said, before adding protocols to our code, we should ask if we really intend to open our function to all types. Maybe we want dasherize to support only atoms and strings? If so, we should rather write:

def dasherize(data) when is_atom(data), do: dasherize(Atom.to_string(data))
def dasherize(data), do: String.replace(data, "_", "-")

However, if we are confident we want a protocol, then we should indeed use the protocol and write a test case that guarantees our function works for at least a couple types that implement such protocol. Such tests are extremely important to guarantee we don’t make a different assumption somewhere in the same function.

Note this trade-off does not only happen in protocols, but in any polymorphic API, like the Dict module. In practice, one should rather use specific dict implementations, like the Keyword and Map modules, and rely on the Dict module only when polymorphism is desired.

Map/struct access

Elixir provides maps, known as dictionaries in other languages, as a key-value data structure. Maps are created as follows:

map = %{name: "john", age: 42}

Maps allow two types of access. A strict access, that requires the field name to exist in the map, and a dynamic access, that returns nil if the field does not exist in the map:

# Strict access
iex> map.name
"john"
iex> map.address
** (KeyError) key :address not found in: %{age: 42, name: "john"}

# Dynamic access
iex> map[:name]
"john"
iex> map[:address]
nil

Both syntaxes have their use cases but we should prefer the strict syntax when possible as it helps us find bugs early on. The same applies to structs, which are named maps:

defmodule User do
  defstruct [:first_name, :last_name, :age]

  def name(user) do
    "#{user.first_name} #{user.last_name}"
  end
end

User.name %User{first_name: "John", last_name: "Doe"}
#=> "John Doe"

In the example above, we have defined a User struct and a name/1 function that receives the struct and returns its name. Since we are using user.first_name, if we accidentally pass a struct that does not contain such a field, it will crash immediately, with a nice error message!

In fact, the strict aspect of the user.first_name syntax is one of the reasons why structs do not support the dynamic syntax out of the box:

user = %User{first_name: "John", last_name: "Doe"}
user[:first_name]
** (Protocol.UndefinedError) protocol Access not implemented for %User{...}

In case you want to use the dynamic syntax, you need to derive the Access protocol for the User struct:

defmodule User do
  @derive [Access]
  defstruct [:first_name, :last_name, :age]

  def name(user) do
    "#{user.first_name} #{user.last_name}"
  end
end

However, only derive Access when you truly need to do so, as it is much better to push yourself to rely more on the strict syntax. I would even say relying on Access for structured data is an anti-pattern itself!

Wrapping up

The most interesting aspect of all examples above is that writing in the assertive style leads to faster, more concise and maintainable code. Even more, it allows us to focus on specific scenarios, postponing any complexity (incidental or accidental) to only when we need them, if we need them.


]]>
http://blog.plataformatec.com.br/2014/09/writing-assertive-code-with-elixir/feed/ 0
Splitting long CSS files to overcome IE9 4095 rules limit http://blog.plataformatec.com.br/2014/09/splitting-long-css-files-to-overcome-ie9-4095-rules-limit/ http://blog.plataformatec.com.br/2014/09/splitting-long-css-files-to-overcome-ie9-4095-rules-limit/#comments Wed, 17 Sep 2014 12:00:37 +0000 http://blog.plataformatec.com.br/?p=4197 »]]> CSS preprocessors like SASS and LESS improved the way we write CSS nowadays. It provides better ways to organize styles into files, that can represent a component or page, and then compile into a single file, following the idea of reducing HTTP requests. Also there are other features like variables, mixins and placeholders that help with code reuse and maintenance.

However, it is possible that with the growth of your application code base the number of CSS styles will surpass the limit rules supported by IE9 or above. The current limit is up to 4095 rules per file.

But it is good to note that only the overflowed styles will be ignored. So, considering this detail, you might take some time to figure out that your layout is broken unless you are aware of this issue, since other browsers like Chrome, Safari and Firefox does not have such limit.

The simplest way to fix that is to split your main stylesheet into multiple files. Using a pre-processor makes the job easy, just create another manifest and move some imports to the newest one and problem solved.

Easy, huh? Well, if you have a well organized CSS the job might be straightforward, but if you don’t, you may struggle with some difficulties.

Here are some experiences that we got when addressing this issue.

Prefer to use placeholders instead of classes

We had some CSS styles that used @extend .some-class and it caused some problems as the .some-class definition is written to the CSS file, even if it is never used. One options is to convert classes into placeholders so they can be reused without being generated.

To make matters worse, .some-class was often defined in another file, which led to the file being imported, duplicating its rules over different files. This takes us to our next tip.

Organize variables and mixins into separated files

As your codebase grows, it is possible that variables, mixins or placeholders get spread in different files. So, if you have to split a CSS file, or even reorganize it, you will have to carefully ensure that all variables, mixins and placeholders are ported over. Keeping them in their proper files like _variables.scss and _mixins.scss cleans up the code and makes future refactoring much easier.

Use tools to break the compiled CSS file

There are projects that try to address the problem of long CSS files using a CSS parser to count the number of styles and generating multiple files when necessary. It is another solution to be aware of, but if you have a well organized CSS structure and guidelines to keep them clean, you can achieve the same result without adding another dependency or step in your asset pipeline.

Ways to detect the number of styles

From the command line

$ curl --silent  | grep -o '{' | wc -l

or if dealing with a compressed asset

$ curl --silent -H 'Accept-encoding: gzip'  | \
> gunzip - | grep -o '{' | wc -l

For example:

$ curl --silent http://plataformatec.com.br/stylesheets/all.css | \
> grep -o '{' | wc -l
339

Another easy way is just opening the CSS file in your browser and search for {.

Note that if you want to check the resulting CSS file in development you need to enable assets concatenation. One options is to set config.assets.debug to false in your development.rb file.

Summary

Preprocessors help a lot but it also requires discipline like any other code that you write. If you need inspiration to organize your files, you can take a look on Bourbon and even the well known Bootstrap project.

Do you know any other cases where a well structured CSS saved you?


]]>
http://blog.plataformatec.com.br/2014/09/splitting-long-css-files-to-overcome-ie9-4095-rules-limit/feed/ 0
Floating Point and currency http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/ http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/#comments Wed, 10 Sep 2014 12:00:05 +0000 http://blog.plataformatec.com.br/?p=4168 »]]>

“Do not use floating point for currency”

This simple statement is useful for both novice and experienced developers alike. It avoids problems that might otherwise compromise the correctness of the software you’re building.

But behind every piece of wisdom, every history of success, there is hard work from lots of people. Exploring this background is an enriching experience, the kind of thing that elevates the level of knowledge and makes you more confident about what you are doing.

Do not expect to find here a complete guide to floating point or currency handling. There are enough references on each matter separately out there already. The idea is to provide a brief exploration in a top-down fashion, gradually digging each layer of the stack, from the perspective of someone that do not master floating point.

Let’s start with a simple example in irb (Ruby’s Interactive Shell), which happens to be a common source of questions:

0.1 + 0.02 == 0.12

# => false

(0.1 + 0.02) + 0.3 == 0.1 + (0.02 + 0.3)
# => false

Wasn’t it supposed to return true? What’s going on behind the scenes?

Debugging the results from each side of the first expression.

0.1 + 0.02

# => 0.12000000000000001



0.12

# => 0.12

It looks like there is something wrong with the operation 0.1 + 0.02. Lets take a closer look, using a more accurate format.

sprintf("%0.50f", 0.12)

# => "0.11999999999999999555910790149937383830547332763672"



sprintf("%0.50f", 0.10 + 0.02)

# => "0.12000000000000000943689570931383059360086917877197"



sprintf("%0.50f", 0.02)

# => "0.02000000000000000041633363423443370265886187553406"



sprintf("%0.50f", 0.10)

# => "0.10000000000000000555111512312578270211815834045410"

So the error happens even before the arithmetic operations. It’s time to dive deeper into the stack.

Conversions

Once the interpreter parses the decimal string 0.1, for example, it converts that to an internal representation, which we’ll review briefly. This is achieved with the help of C strtod function, in MRI.

Curiously, this conversion step had already lead to security issues before.

Another conversion takes place when printing a float back to the decimal string. These transformations are not as trivial as one might think. There had been many studies in the development of the algorithms used in order to make it accurately and efficiently.

Since all of this happens transparently, some might expect that all languages work this way by default. It does, but not always for free. For example, in the infant days of the Elixir language, a developer had the following question after typing a decimal string into IEx (Elixir’s Interactive Shell). This had been solved by borrowing functionality already present in Erlang.

A counter intuitive fact is that even if a decimal number is not exactly representable as float, say 0.12, we are able to convert it back and forth without ever seeing the rounding error due to such carefully designed algorithms.

This automatic rounding behavior hides complexity but may encourage some to operate on floats expecting that the final conversion is going to provide a desired decimal result. But that is not always true due to rounding errors accumulation.

But what’s this internal representation and why does it impose such limitations?

Thinking in terms of binaries

We are not going to dive into the details of the IEEE754 nor explain how to do such conversions. That’s an interesting topic but it has been covered before and would end up being too extensive to fit in this post.

Instead we are going to show some examples that provides a glimpse of the real problem.

For instance, take the decimal number 0.625. This number represents the sum of fractions 6/10^1 + 2/10^2 + 5/10^3. The same reasoning can be used to find the binary representation replacing the denominator by powers of two 1/2^1 + 0/2^2 + 1/2^3 = 0.5 + 0.125 = 0.625, which leads to the binary 0.101 when we place the numerators in a row.

But if we had chosen another number, let’s say the decimal 0.1, we would find that it’s not possible to write it as a finite sum of fractions whose denominator is a power of 2. E.g. it does not have a finite binary representation.

Since the space to store a double precision float is limited to 64 bits, some sort of rounding would be required. And here we have one of the causes of precision loss.

What type should I use for representing currency?

The two most frequent answers include Integers or BigDecimals as the way to go. I’ve personally used both and it worked fine, but it would be too pretentious to say that one or another is the best for your problem.

Most Rails applications use databases. If that’s your case, it’s important to understand the limitations offered by the types available and the conversions done by the adapter during information storage and retrieval.

For example, Postgres recommends using its numeric type for currency, which Rails maps to BigDecimals. This type also supports the aggregation functions we are used to.

Other databases may require other approaches, like mongodb that does not have a type compatible with BigDecimal. But it doesn’t mean that it’s impossible to use BigDecimals with mongodb either.

Currency in cents, like $19.90 could be represented as the integer 1990. It avoids precision problems and works well with most databases too. One inconvenience is formatting numbers as currency, but there are gems to make this task easier and coding your own helper methods is also an alternative.

Some may experience performance issues when using BigDecimals, but I’ve never faced such issues personally. One thing to be aware of is that BigDecimals are not as simple as Integers and I like to keep things as simple as possible.

Even floating point may be required under some contexts if numerical methods get involved. The most important thing is to be aware of the limitations and make informed decisions.

So have you ever had problems with currency handling? I’m really willing to hear about how you solve this problem. If you have an experience to share, please, leave a comment below or find me on twitter @rcillo.

References


]]>
http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/feed/ 3
What Guardians of the Galaxy teach us about agile teams http://blog.plataformatec.com.br/2014/09/what-guardians-of-the-galaxy-teach-us-about-agile-teams/ http://blog.plataformatec.com.br/2014/09/what-guardians-of-the-galaxy-teach-us-about-agile-teams/#comments Wed, 03 Sep 2014 12:00:56 +0000 http://blog.plataformatec.com.br/?p=4181 »]]> Yeah, it might seem a little bit lame at first, but the whole idea is to talk about agile teams, so do not nitpick about the metaphors and examples using the movie. This post has spoilers, so if you have not watched Guardians of the Galaxy yet, go there and watch it, but come back to read the post =).

It’s been some time since I started writing down some ideas about agile teams, culture and how these things reflect in actions. After watching the Guardians of the Galaxy movie, my ideas and thoughts became this blog post. Each section is about skills and practices that agile teams should master. To better understand them, examples from the Guardians of the Galaxy will be used.

The sense of team

The main character of the movie, Quill – also known as Star-Lord -, acts as a scrum master. During the first minutes of the movie he managed to group different people with different purposes and abilities to work together in a very efficient way. He did it in the same way agile teams work: making everyone to have a common goal.

Quill wanted to sell the Orb for money; Rocket and Groot were hunting Quill for money; Gamora wanted to sell the Orb too, not for the money, but because she did not want it fall into the wrong hands; Drax wanted revenge, and hurt Ronan the way Ronan hurted him. Quill managed to set their goals to save the galaxy. Now, everyone works for the same purpose. All the personal problems were vanished, the goal of the team was now bigger than the personal goals.

Selfishness hurts

Have you ever not called for help just because you wanted to show to someone (or even to yourself) that you could accomplish it by yourself? Well, Drax did it. And It was selfish. He called Ronan to Knowhere saying the Orb was there and so he could kill Ronan. He thought of it as an opportunity. But he lost the fight and the Orb as well.

In software development, trying to decide a software architecture, pushing code to master without code review or ignoring known bugs are some selfish acts that someone could perform.

Although it should be avoided, sometimes we still see things like these happening in agile teams. When it happens, we should reinforce that it’s a team. And a team works like a team, there is no space for solo stars. Drax realized he made a mistake doing that. He asked for apologies and the team understood and moved on.

Solving conflicts among members

Drax joined the team, firstly, because of Gamora. He wanted to kill her in order to hurt Ronan. But when he figured out it wouldn’t help, he kept in the team, for some reason. It could be a problem and may put the goal in risk if not managed well. But Star-Lord argued well and made people collaborate with each other.

Solving conflicts in the team comes from listening both sides. Drax explained why he wanted to kill her. She said she was against Ronan as well. Star-Lord helped both to get in a deal, since it probably was a communication issue. On a daily basis, we can face ourselves criticizing someone, not happy with something or two members that do not go along. Having an health environment where everyone is able to tell their issues is half the way. How to conduce the conflict resolution is the second one.

That’s a leader role, but it does not require only the scrum master to perform it. When things goes chaotic, the team must figure out a way to cool down and make things go well again. In an agile team, we can think in chaotic moments to be, for instance, when pressure from the external world come into to the team, for instance. Rushing the development, cutting edges, letting quality goes down, everything could be taken as the “chaotic” moment. Someone must notice it and figure out a way to solve it.

Behaving like a team member

Star-Lord never said “I am the leader”. This role came to him naturally when everyone trusted him enough. That’s the final scene where he was asked where to go to, and so Gamora says: “You lead, Star-Lord”. No roles are set, they must come naturally. When a member is comfortable performing some role, he must naturally say “let me handle this”.

As a leader, he is not supposed to solve all the problems. He needs the team to be part of the solution, so they would be more engaged and committed with the results. You can see it while they plan how to escape from the prison. It was not Star-Lord who came up with a plan. Rocket made it up and everyone was part of its execution, which, by the way, was one of the funniest parts.

Everyone had a task to perform and the plan’s success was depending on their execution. Rocket let everyone perform it without monitoring or over controlling. He just trusted people would do their best to succeed. And they did. Rocket did his part as well. Everyone was part of it.

Backing the team up

When Gamora was in the vacuum, after her ship explosion, Star-Lord put himself in risk in order to save her. Ok, it might have been for love. But, in real life, members of a good agile team will always do small sacrifices for other members. For love? Maybe not. I don’t think there is a word to describe the feeling of being united and friend with the whole team to the point of doing small sacrifices.

Have you ever exchanged your chair because someone else’s was not comfortable or kind of broken? Have you worked on someone’s user story in order to finish it because the owner had personal issues to deal during the sprint? If you had answered yes for any of these questions or you can think of a similar experiences, so you’ve done small sacrifices.

Do you remember the “We are Groot” scene? That was a sacrifice. A very nice scene indeed. Very touchy. Well, you might think you will not save someone’s life at this point. But you can totally save someone’s day. On daily basis, these small acts count a lot. They are an important detail that makes the team united and raises the trust sense.

Also, it is very interesting how those sacrifices are taken by examples and encourage other members to sacrifice themselves too. It is very nice when it happens because you feel safe. You feel safe to fail, to expose your ideas and to perform better.

Communication

The members should always be communicating with each other. It can be through Campfire, Skype, HipChat, IRC or even in person. But the communication must happen, its lack can cause huge problems like when Groot, Rocket and Drax were going to save Gamora and Quill from Yondu.

Rocket tells to Yondu’s ship crew that he would blow the ship away in case they do not set Gamora and Quill free. Actually, they already had an agreement, but it was not informed. The situation went weird. Sometimes, specially in consulting, communication fails and either we feel or the customer feels threatened like Yondu felt. If people take it personally, you will have a situation.

A lot of software projects fail due to the lack of communication. People do not clearly understand what’s going on, expectations are not met and fights among members can happen. It might be a change in the requirements that nobody knew except for the guy developing the feature or it could be a phrase without any context, it does not matter what it is, the lack of communication will lead to low trust sense, lower collaboration and also contributes to a bad work environment.

Having fun together

There is another moment that I need to talk about. While Gamora and Star-Lord were talking with the Collector, the rest of the guys were in the bar drinking and having fun. That’s important for agile teams. The more they spend time outside the work hours, the more they know each other and the sense of trust raises.

The sense of trust is the primary factor that unite people. They become happy to work with each other, they trust in the work and that they will cover them back. They will know each other as better as Rocket knows Groot! Yeah, they know each other pretty well. When Groot says “I am Groot”, Rocket knows exactly what he meant, just like when you see a disapproval look from your team member and knows he is shy enough to not say anything at first, so you gently say “I am not sure about this, does someone have any thoughts?” and then he answers.

The final scene is what best describes the journey of agile teams. They finally reached their purpose. And how it happened? Well, Star-Lord starts this very interesting dancing act for Ronan. In the mean time, Rocket was able to build the weapon again and they could strike Ronan with it. That’s teamwork. Unfortunately, it was not enough to defeat Ronan. Drax and Rocket shoot the hammer and the Infinity Stone broke apart. Star-Lord grabs the Stone and then everyone helps him. Everyone was needed, otherwise Star-Lord would blow up!

When everyone is holding each other and Star-Lord is capable of controlling it, everyone – the whole team – feels part of their victory. Groot in pieces was as important as the others.

The same logic is applied for project teams. When one fail, the team fails, the team learns, and the team improves itself. No guilty, no finger pointing. It is about not making the same mistakes again. So, who wins when the project succeeds? The team. The team that in that moment can feel like they have saved the Galaxy.


]]>
http://blog.plataformatec.com.br/2014/09/what-guardians-of-the-galaxy-teach-us-about-agile-teams/feed/ 0
Thank you, Carlos Antonio! http://blog.plataformatec.com.br/2014/08/thank-you-carlos-antonio/ http://blog.plataformatec.com.br/2014/08/thank-you-carlos-antonio/#comments Fri, 15 Aug 2014 12:40:00 +0000 http://blog.plataformatec.com.br/?p=4159 ]]> 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!

]]>
http://blog.plataformatec.com.br/2014/08/thank-you-carlos-antonio/feed/ 1