The latest and greatest additions to Reek

2015 has been an awesome year for Reek. With the release of Reek 3 we reached a level where I’d call Reek a stable, mature and – if used right – an incredibly useful library.

We have been quite busy since the Reek 3 release – here are my favourite features we have added to Reek since then:

Unused private methods

Reek now detects unused private methods and warns you.
Code like this:

class Car
  def start
    drive
  end

  private

  def hyper_drive; end
end

would cause Reek to emit:

1 warning:
  [8]:UnusedPrivateMethod: Car has the unused private instance method `hyper_drive` [https://github.com/troessner/reek/blob/master/docs/Unused-Private-Method.md]

Right now this smell detector can only recognise unused private instance methods – we plan to expand it to class methods as well in the future.

Deactivate UtilityFunction for private methods

Quite some users complained about the UtilityFunction detector and I believe they rightfully did so.

In its old version it would warn on every method in question which was conflicting with a lot of users writing small, private methods for readability reasons. We added a configuration option so that you can now disable this smell detector for private methods like this:

---
UtilityFunction:
  public_methods_only: true

Making NestedIterators smell smarter

Conceptually, every method in Ruby that takes a block is called an iterator.
However it’s idiomatic Ruby to use blocks for a lot of different things and most of them have nothing to with “iterating” over anything.

For instance it’s quite common to have before and after hooks in the test framework of your choice like this:

before do
  my_collection.each do |item|
    # do something with `item``
  end
end

As a consequence, Reek would warn you about NestedIterators which really makes no sense whatsoever in this case.

We improved NestedIterators sensitivity so that it won’t count iterators without block arguments.

Improved error messages

Unfortunately Reek never was the user friendliest library when it came to error messages.

Especially the warnings for complex smells like FeatureEnvy were not really helpful:

FeatureEnvy: "refers to `foobar` more than self"

After quite some back and forth we finally converged on far more helpful error message. For instance, the new and improved error message for FeatureEnvy is now:

FeatureEnvy: RedCloth#blocks refers to blk more than self (maybe move it to another class?)
[https://github.com/troessner/reek/blob/master/docs/Feature-Envy.md]

Far more expressive and it includes a helpful link by default you just have to click to read up on what FeatureEnvy means and how you might be able to fix it.

What’s next?

  • We’re working hard on our upcoming CodeClimate integration
  • We’ll streamline and clean up our API which we’ll then release in Reek 4
  • With the EOL of Ruby 2.0 approaching fast we’ll drop its support in Reek 4 as well which will clean up our code base quite a bit.
  • We have so many cool features on our todo list that I don’t even know where to start

Reek 3 has been released!

My beloved reek gem has come quite a long way. During the last months we refactored so much of the source code that it almost feels like a new and shiny gem.

Right after the release of reek 2  we started to work on reek 3 which we released a couple of days ago.

A stable API

The changes that I’m most exited about is that we agreed on a public API  and implemented it as well. For this API to use you’ll basically just do something like this:


require 'reek'

reporter = Reek::Report::TextReport.new
examiner = Reek::Examiner.new("class Klazz; def m(a,b,c); end; end")
reporter.add_examiner examiner
reporter.show

which would give you this

5 warnings:
Klazz has no descriptive comment (IrresponsibleModule)
Klazz#m has the name 'm' (UncommunicativeMethodName)
Klazz#m has unused parameter 'a' (UnusedParameters)
Klazz#m has unused parameter 'b' (UnusedParameters)
Klazz#m has unused parameter 'c' (UnusedParameters)

Getting a stable API out is something that hopefully means a lot for projects who make use of reek programmatically like rubycritic.

The API is still rather small so you can quickly read up on everything you need to know in 5 minutes here.

Excludable directories

We made directories excludable via configuration, a feature that was requested quite some times.

The way this works is that you just add a paragraph like this

exclude_paths:
  - app/views
  - app/controllers

 

to your reek config and that’s it – reek will ignore those directories when scanning.

Singleton methods

We fixed one of the most annoying bugs that has been around for years. Until now, reek would not recognize singleton methods if they were defined with the class << self syntax, meaning that this:

class C
  class << self
    def m(a)
      a.to_s
    end
  end
end

would incorrectly report UtilityFunction.
Now it will correctly recognize those methods as singleton methods.

Compatibitility

We dropped support ruby 1.9. Time to move on.

What’s next?

How to recruit great developers

I believe there are 3 ways of recruiting when it comes to technology and startups (ignoring agencies and freelancers):

1.) The HR way: Non-organic recruiting through cold calls and direct search

The “standard” way to do recruiting which probably never works out well for anybody.
Unless you are looking for interns, juniors or freelancers (no offense intended, that’s just the way it is).

There are many reasons why this approach does not work:

  • Developers prefer to be approached by technical guys and not by somebody who thinks that a “javascript” developer easily fits into a “java enterprise” environment.
    I mean, why wouldn’t he, both positions have the word “java” in it!
  • Good developers normally don’t respond to contact requests from xing and linkedin since their inboxes are already flooded with messages
  • It’s hard for a non-technical person to assess the quality of a developer since the CV is useless in most cases. Or rather all cases.
    I have seen great developers with shitty CVs and lame developers with great CVs. The only thing that should matter for a developer is code.
    Oh, and team culture and stuff. But I’ll get to that later

 

2.) Organic recruiting through team culture

The best way to recruit – it means that your team culture is so great that great developers apply proactively. Great developers rarely have to apply for a job, so this means a lot already (quite a few of them don’t even have a CV because they never had to apply anywhere).

This also means that your team culture is so strong, that your team members proactively start looking for other great team players because they are so convinced of what you’re doing.

Please note that this is not the same thing like “I’m looking in my network because my employer has a ‘refer a friend’ program”, this is something much stronger, since people are not motivated by money, but by passion.

Ok, sounds great, so how do we get there?

* Be polyglot

A lot of companies are focused on one language only. E.g. you started out with ruby and now you are doomed to write ruby forever. This deters good developers. Nobody wants to be locked in the golden ruby cage forever (trust me, I’m the biggest ruby fanboy out there, and even I am convinced of that).
You should drop the “we are doing ruby and you have to know ruby” restriction completely and embrace all modern, sexy languages.
Not to mention that you then can tap into the huge reservoir of great developers out there who haven’t written a single line of ruby in their life.
But in order to do that, you need the appropriate technical architecture. Having a microservice architecture allows you to be polyglot since every microservice is completely independent from each other. Having one monolithic app would probably not work.
Of course this still needs to be at least loosely monitored since certain technologies probably don’t make sense for you (e.g. Java Enterprise when you’re a start-up) or are outdated in the sense that most good developers moved to a different eco system years ago like PHP or Perl (I love Perl, but let’s face it, Perl 6 put the final nail in the coffin).
And of course the teams must commit to maintain and operate it.

* Organize user groups

User groups are a very informal developer meetup.

Normally all you need is:

  • a room with a beamer (easy)
  • couple of beers (easy)
  • people who have a topic they are passionate about (hard to find)
  • a network of great people to invite (see above)

You can either create a user group that hasn’t existed before in your area. Depending on where you are, this might be pretty hard. E.g. in Berlin there are a gazillion of user groups already with all kind of technical topics.
If that doesn’t work, go to existing user groups. Immerse yourself. At one point, people will know and trust you and they might be open to host the next user group at your place.

* Organize internal tech talks

Kind of self-explanatory – your developers get together and talk about tech.
Those talks have more great side effects than I could enumerate here. You increase team spirit. You increase “world knowledge” since those tech talk of revolve around work related problems. You create synergies between teams you hadn’t even thought about before. I could go on and on, but I’ll stop here.

* Watch conference videos together

Establish a culture where it is considered “normal” to sit together for lunch and watch talks from literally any conference. Can be tech-oriented, but can also be about yoga, sleeping better or how to ride a unicorn on a rainbow.

* Create a world class office

Sleeping pods, showers, gym and most important: an up-to-date library (Zappos style. Check it out). That includes encouraging people to read as well.
Ask your team what they want to have in the office.
Some ideas are more of a joke but there will be a lot of good ideas as well ranging from very cheap (“order a new book shelf”) to rather expensive (“A gaming room would be cool”).

* Have open source days

That would be days were people can hack on open source software. This is kind of a difficult thing to get right and warrants a separate blog post later.

* Attend to conferences

Developers want to go to conferences. That’s just something they expect. You should not only grant those requests, but rather encourage people to go there.
Yes, it’s probably not cheap and yes, it might be during working days.

What you get out of this:

  • Motivated developers
  • New ideas how to solve existing problems
  • New impulses
  • A bigger network of talented people

* Establish a mentor program

Seniors mentor juniors. Veterans mentor newbies so that they don’t feel lost and can get productive as fast as possible. This doesn’t mean that juniors can just abuse seniors to get the job done. It’s more of a “ok, when I am totally stuck with something i can at least ask my mentor for an idea” thing. In most cases they don’t even ask anything, but just to know that they can already has an incredible positive effect on them.

* Make recruiting a top priority for every team member

How google works has some great thoughts on how to do that. And more important, how to not do that.

One thing that I love to do is a trial day or two for candidates. After that, both sides know if this will work.
Don’t invite everybody but only people that passed an initial screening. Reject developers who can’t show source code with their application right away, which already weeds out the bad ones.
Include the teams in the decision process. After all, a hire would be good for nothing if you think he / she is a good addition but the team he’d work with rejected him.

 

3.) Recruiting on steroids through active participation in the tech scene

Even better but requires a lot more of effort.

* Speak at conferences

First of all, its important to understand that those conferences are very different from what a lot people would expect: They are very informal, the agenda is sometimes unclear even days before or changed ad hoc and they often feel more like a meeting with friends. They are mostly non-commercial (in the sense that they only have fees to pay their expenses) and you can’t just buy a speaker slot. You sometimes can buy a slot for a 5 minute lightning talk , but never for a full talk (you have to submit a proposal and this proposal gets reviewed by the organizers if it is interesting enough for the attendees).
Talks must be authentic so you can’t just have a talk about something that somebody else did since most people will notice right away.

* Organize workshops that are free for non-employees

This is basically how a company here in Berlin recruited rare Erlang programmers (Erlang is very popular in northern Europe): They invited Erlang icons, paid them to do workshops and invited every Erlang dev in Berlin to take part. For free (or almost for free).
There are so many idols out there that travel the world and can be booked for workshops. Corey Haines, Eric Ries, Sandi Metz, Yehuda Katz….the list is long.

* Organize Hackathons

Organize a hackathon, give participants an interesting challenge that also solves one of our problems, have some fancy prices and ensure good press coverage.

This is a complicated topic and would require thoughtful planning. I have seen quite a few of those events fail horribly because people thought that providing a room and prize money would be enough.

Conclusion

Get your team culture right. Invest some money. Probably a lot. Build up the best team possible.
Take (early) google, twitter and Zappos as role models. And then go beyond what they did.

And then your recruiting problem will solve itself.

Reek 2 just got released

A couple of days ago we released the new and extremely shiny reek version 2 to the world!

For those of you who don’t know reek, reek is a static code analyzer for Ruby detecting so called code smells. Those code smells range from rather trivial ones like UncommunicativeParameterName or TooManyMethods to high-level code smells like FeatureEnvy or DataClump.

In the most simple use case you can just run

reek my/source/files

or

echo "def dirty(x,y,z); puts 'hossa!'; end" | reek

So what has happened since 1.*?

There are way too many significant changes to list them all so I restrict this list to my favourite ones (excluding the countless bugfixes):

Support

Parsing with the parser gem allows us to support all major ruby versions:

1.9.3
2.0
2.1
2.2.

We deliberately dropped support for 1.8.

New smells

We introduced 2 new smells:

– The ModuleInitialize smell
– The Prima Donna Method smell

Configuration

We completely revised our configuration handling, basically there are 3 ways of passing reek a configuration file: Using the cli -c switch, having a file ending with .reek either in your current working directory or in a parent directory, or having a file ending with .reek in your HOME directory.
This means that reek no longer tries to nest configuration files, but instead from reek‘s point of view there exists only one configuration file and one configuration.

Another cool feature is support for detecting specific smells like this:

reek lib/ --smell FeatureEnvy

This can be very helpful when refactoring when you want to focus on one group of problems.

And last but not least smell detectors can be configured or disabled in code comments like this (in addition to reek‘s regular configuration mechanism):

# This method smells of :reek:NestedIterators
def smelly_method foo
  foo.each {|bar| bar.each {|baz| baz.qux}}
end

CLI / Output / UX

We completely restructured and revised the command line interface for reek:

– We now support the yaml and html format besides the standard text format which makes reek great for compiling automated reports and statistics
– We overall revamped the UX when using reek. For instance we added color to reeks output, enabled different sorting options like “sort by issue count” and added a “show-wiki-links” switch that prints out helpful links next to each warning pointing to our github wiki that explains this particular smell and how to possibly fix ist.
– Speaking of the wiki, you now should find an extensive description of each smell reek might detect including possible solutions

rspec matchers

We made the reek_of / reek_only_of rspec matchers a little smarter – you can still just do something like:

expect(src).not_to reek_of(:UncommunicativeParameterName)

but if you really want to be more specific about this you can now add a hash of “smell_details” reek_of will check for as well like this:

expect(src).not_to reek_of(:UncommunicativeParameterName, name: 'x1' )

You can check out the details here.

Outlook

Personally I’d really like to see a couple of annoying bugs fixed, for instance:

Issue 112
Issue 27
Issue 268

Pair Programming Sucks

For quite some time, a lot of companies have been on the “yes, we do pair programming” bandwagon. Some of them even to the (ridiculous) extent that pair programming was mandatory. So something like “at least 2 days a week”.

I’ve been through that and those were certainly some bad times in my software development career.

I never liked pair programming to begin with.

First of all, it’s synchronous. You have to pay attention that very same time your partner pays attention. But people and their rythm are different and if you do this all day, this gets exhausting very quick.

Second, regardless of what technology you’re using, there will always be artefacts you have to generate and update. If you use languages like Java this might amount to a lot. But even with something concise like ruby this will steal a lot of your time.

And during that time one partner takes care of those artefacts the other drifts off – there’s just nothing you can do about it, this is how most humans work. And if one partner looses focus, he takes the other one down with him ususally.

So, in an nutshell, pair programming sucks hard.

So what are the alternatives?

Pull requests.

They have all the benefits of pair programming but none of the disadvantages. They are asynchronous by design so you can dive into problems when you feel like. Your time, your speed. Very important.

There are a couple of exceptions though where pair programming makes not only a lot of sense, but offers significant benefits:

  1. Learning workflows from your partner. Sure you can read up on git and friends, but nothing makes it easier for you than to see those git workflows in action. Also, seeing how your partner executes those workflows takes the fear away to fuck up things on the remote end when you have to do it yourself: You have not only seen how it’s done, you have seen the result of it. To stick with the git example, a lot of git novices are afraid “cause damage on the remote git repository” – seeing how easy it is to juggle multiple branches and pushing to remote lowers their mental barrier.
  2. Learning how to use tools from your partner. That’s basically how I learned vim. Granted, this only makes sense if you use something obscure and poorly documented as vim.
  3. Onboarding. That probably needs no explanation.

I guess with pair programming it’s like with everything in life: Don’t make up rules just for the sake of having them and follow them without questioning them.
Use pair programming scarcely. In most cases you can achieve the same thing better with pull requests.