RVM, Ruby 1.9.3-p194, ruby-debugger and “You need to install ruby-debug” on Ubuntu 11.10
May 12Recently I’ve been upgrading my RVM and Ruby versions. After upgrade I’ve encountered a problem connected to ruby-debugger. When starting Rails server I always ended with such a message: # Edit: this solutions fixes also this problem: Ruby-debbug doesn’t work to well with Ruby 1.9, so I use following combination in my gemsets: Until now, [...]
...więcej...
Get Rid of That Code Smell – Duplication
May 11This is a post from the Get Rid of That Code Smell series.
Removing duplication from the code is a seemingly easy task. In many cases it is pretty straight-forward – you look at similar bits of code and you move them to a common method or class that is reusable in other places. Right? No, not really. It is true that code that looks similar might be an indicator that there’s a duplication but it’s not the definitive way of determining the smell.
If we look for duplication in our code we should look for duplicated concepts instead of similarly looking lines of code. Here I want to remind you the short definition of DRY principle that I’m sure most rubyists are familiar with:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Andrew Hunt and David Thomas
The Pragmatic Programmer
There is a fantastic presentation by David Chelimsky from RubyConf 2010 titled “Maintaining Balance While Reducing Duplication”. If you missed it you should definitely check it out. There’s a beautiful quote in this talk:
DRY does not mean “don’t type the same characters twice”
David Chelimsky
Maintaining Balance While Reducing Duplication
Detecting Duplication Smell
You can use both reek and flay to aid you with finding duplication in your code but remember that these tools are not smart enough to find similar concepts. Both will find potential duplication but it’s your job to decide if it makes sense to do anything about it.
Here is an example from Virtus project where reducing duplication wasn’t such a good idea:
[crayon-4fae4603e7b90/]
The Equalizer module defines a bunch of methods. Internally it has a few private define_* methods which use @keys ivar to map it to something else. Now the metric tools complained about all these calls to @keys.map. It is true, this is a duplicated code but what’s the risk that it’s going to change? Very, very small. Is this a duplicated concept in the library? Nope.
Nevertheless I went ahead and reduced this duplication by introducing a new method so the code looked like that:
[crayon-4fae4603e7bda/]
Now the metric tools won’t complain. All the calls to @keys.map has been replaced with a call to the new compile_keys method.
This refactor did reduce duplication but with the price of increased complexity. I don’t think it was such a great idea – the risk that these duplicated calls would have to change was so low that I should’ve left this code alone despite the little duplication.
Removing Duplication
Here’s another example where it actually did make sense to reduce duplication to get cleaner code and better encapsulation:
[crayon-4fae4603e7c22/]
I think it’s easy to see duplication here. The duplicated concept is that we want to call a specific method on the value only if it’s actually available. If it’s not then we use an alternative String-based coercion.
This logic was extracted into a new method called coerce_with_method and the module looked like that:
[crayon-4fae4603e7c66/]
In fact this turned out to be so common that later on coerce_with_method was moved to the base Virtus::Coercion::Object class with a few overridden variations in other coercion sub-classes.
Summing Up
Reducing duplication should be based on finding similar concepts, not similarly looking code. The metric tools can only point you to potential duplication but you have to determine yourself if it really makes sense to do anything about it. In some cases you can just complicate your code just for the sake of reducing duplication without any real benefits.
OK! Next episode will be about “Primitive Obsession” which is extremely common in Ruby world.
więcej...
Scratch dir
May 04"AUTOMATE ALL THE THINGS!" one would say. "Time is money" other would say. "Don't make me think" another smart one would say. "Computers are our slaves and we should put as much work as we can on their circuits" I say.
I'm constantly looking for automation opportunities in my daily working habits. Today I automated one thing that was very simple but at the same time boring and fully repeatable: creating temporary "scratch directory" and cd'ing to it.
Yesterday it was like this:
- I need a scratch dir...
- I'll create it in.... ~/tmp/ or /tmp/ ... let it be /tmp/..
$ mkdir /tmp/- stop, hmm, I need a name.. q then$ mkdir /tmp/qmkdir: cannot create directory '/tmp/q': File exists- "Damn", qq then
$ mkdir /tmp/qq$ cd !$- Hooray! Wait, but what I need this dir for?
Today I created short shell function for zsh/bash:
function new-scratch {
cur_dir="$HOME/scratch"
new_dir="$HOME/tmp/scratch-`date +'%s'`"
mkdir -p $new_dir
ln -nfs $new_dir $cur_dir
cd $cur_dir
echo "New scratch dir ready for grinding ;>"
}
Thanks to above function I land in a brand new scratch dir. This dir is located in ~/tmp/ and it has unique name scratch-{TIMESTAMP}. Additionally there's symlink ~/scratch pointing to it (always to the latest scratch dir) that is handy when you need to open another terminal/shell instance in this dir.
So today when I need a scratch dir:
~/code % new-scratch
New scratch dir ready for grinding ;>
~/scratch %
One would ask: why shell function instead of shell script? Because shell scripts can't change current working directory of current (parent to them) shell. Shell functions run inside the current shell and can alter cwd.
więcej...
Konkurs na aplikację webową w Railsach
Apr 30Firma Compendium Centrum Edukacyjne zaprasza miłośników języka Ruby do wzięcia udziału w konkursie na aplikację webową w Ruby on Rails. Do wygrania jest tablet CTAB (specyfikacja). Ponieważ lubimy takie inicatywy, Rubysfera została patronem konkursu.
Aplikację należy stworzyć korzystając z zasobów thedatahub.org, a następnie opublikować ją na githubie. Prace konkursowe będą oceniane według następujących kryteriów (w skali od 1 do 5):
- opcje i funkcjonalność
- użyteczność aplikacji
- szybkość działania
- wizualizacje
- zakres danych z thedatahub.org wykorzystywanych przez aplikację
- innowacyjność
- udogodnienia dla niepełnosprawnych
Zwycięzca otrzyma tablet CTAB, urządzenie specjalnie wyprodukowane dla Compendium CE.
Zgłoszenia
Aplikacje biorące udział w konkursie należy zgłosić za pomocą pobranego formularza do 11 maja (termin został przesunięty na 25 maja) na adres mark@compendium.pl.
Aplikacja webowa powinna spełniać następujące wymagania:
- pracować bezawaryjnie na urządzeniach mobilnych
- korzystać z jednego lub więcej źródła danych z thedatahub.org (o wielkości co najmniej 1000 wpisów). Istnieje również możliwość skorzystania z własnego źródła danych, ale wcześniej należy je zgłosić do thedatahub.org.
- być opublikowana za zasadach jednej z licencji open software (GPL, MIT/X11, BSD etc.)
Pełny regulamin i skład Jury dostępny jest na stronie konkursu.
Co prawda pogoda na razie nie zachęca, ale podobno pod koniec tygodnia ma być oziębienie. Mashupowa aplikacja może być ciekawym zajęciem na długi weekend, a interesująca nagroda przypadnie do gustu fanom Andorida, zatem do dzieła!
więcej...
Spotkanie 22 maja
Apr 25Kolejne spotkanie grupy KRUG odbędzie się we wtorek 22 maja 2012 o godzinie 19:00, tradycyjnie już w Klubie Pauza na ul. Floriańskiej 18/5 (podziemia).
Zobaczymy 2 prezentacje :
- Ruby ułatwia życie - Marcin Raczkowski
- Real-time Web with WebRocket - Kriss Kowalik
Po prezentacjach, jak zwykle część nieoficjalna oraz dodatkowe atrakcje w postaci:
- 1 licencji RubyMine ufundowanej przez firmę JetBrains!
- Piwa dla każdego od firmy Lunar Logic Polska!
Zapraszamy!
...więcej...
Rails routes: limiting access to application parts from certain domains (hosts)
Apr 22Sometimes we want to handle different parts of a single application from different domains. A good example of such an approach is when we have a scope containing our API. Wouldn’t it be great if it could be served from a different domain than the rest of the application? Of course yes! Approach like this [...]
...więcej...
Get Rid of That Code Smell – Control Couple
Apr 11This is a post from the Get Rid of That Code Smell series.
If you are serious about Object Oriented Design and respecting Single Responsibility Principle then you definitely want to get rid of Control Couple code smells. In this post I will show you a simple example explaining how to identify and remove control coupling from your code. I like to think about that code smell also in the context of SRP because I like to apply it to every piece of my system – whether it’s a method, a class or a whole library. I like to be able to describe each piece with a simple sentence saying what it does, what’s the responsibility. With control coupling you introduce multiple responsibilities in a single method which is against SRP and against Object Oriented Design.
Detecting Control Couple Smell
Reek can help you with that – detecting Control Couple is turned on by default. I believe that Pelusa’s “Else Clause” and “Case Statement” lints can also be used to find places in your code with potential control coupling.
A dead-simple example of control coupling could like this:
[crayon-4fae4603ed374/]
Which is pretty self-explanatory. The say method puts an upcased sentence if loud parameter is set to true.
Let me show you a real-world example though. Let’s bring it to the class level – here’s a small snippet from Virtus:
[crayon-4fae4603ed3b9/]
DefaultValue is a class responsible for evaluating a default value of an attribute in Virtus. Its #evaluate method, depending on @value ivar, is deciding how to evaluate the value. We have multiple cases here and all of them are handled within one method. You cannot easily describe this method’s responsibility because it does different things depending on what the @value ivar actually is. If it’s a proc-like object responding to #call we call it, if it’s a duplicable object then we dup it, else we just return it as is.
I found that code pretty ugly. The repercussion of Control Couple smell in this example was that every time we were setting the default value we were performing this if/else check on @value.
Removing Control Couple Smell
The DefaultValue class was refactored by splitting the evaluate logic into 3 sub-classes. Every sub-class implements a self.handle? method which checks if its instance can actually handle the given value. This means that the logic inside #evaluate is now performed only once, prior to deciding which DefaultValue sub-class we want to initialize.
Here’s how it looks like:
[crayon-4fae4603ed401/]
Now for example FromCallable class implementation looks like that:
[crayon-4fae4603ed442/]
I liked that refactor because I could remove the if/else clause from #evaluate method, split responsibilities across 3 sub-classes and gain a small performance boost too.
Summing Up
Even if removing Control Couple smell requires writing a bit more code – it’s worth that price. Getting rid of that smell leads to better Object Oriented Design and helps you with respecting Single Responsibility Principle. I also like that it’s easier to understand what the code does because responsibilities are shared across the objects rather than jamming everything into a few methods that couple the logic to the received arguments.
In the next post we’ll see how to deal with Duplication in our code. Stay tuned.
więcej...
NoMethodError: undefined method `split’ for true:TrueClass
Apr 08Weird errors occurs: when trying to perform get request in functional tests: So WTF? This type of error occurs when we have a route with :format: but the request is performed without :format option. To fix it, just add :format into your request:
...więcej...
Mocking Doorkeeper access token with Mocha
Apr 08Recently I’ve been testing some stuff behind Doorkeeper and I needed to mock Doorkeeper token to return a stub. In older Doorkeeper versions it was done like this: However in a new Doorkeeper version, the’ve changed something and my mockings stopped working. So if you use newest Doorkeeper version, the mock should look like this:
...więcej...
Get Rid of That Code Smell – Attributes
Apr 04In this post I will show you why using attribute accessors is a code smell in most of the cases. This is a very convenient feature of Ruby but you should only consider using it if you’re implementing a data-like objects which expose, well, data to other parts of your system. A good example is an Active Record object which exposes its attributes. Another good example could be an object which wraps a response from a remote API and through attribute readers gives you access to data returned in that response. Probably every other use case should be considered as a code smell.
Detecting Attribute Smell
It’s pretty easy to find the attribute smell in your code. Just grep for usage of attr_* in your classes. Pelusa does that for you. Reek can also detect this smell although this check is turned off by default.
Here’s an attribute class which you can instantiate with a name and set its reader visibility. This is an actual piece of code that we used to have in Virtus. The information about reader visibility needed to be public. Initially we had a public attr_reader for the reader_visibility instance variable that was set in the constructor. It was an easy and convenient solution. The related piece of code looked like that:
[crayon-4fae4603f1a74/]
Now in other places we were using the value of reader_visibility so we had pieces of code like this:
[crayon-4fae4603f1ab8/]
This means that we had an instance variable exposed to the other objects which were relying on its value. This was a mistake and definitely a code smell.
Removing Attribute Smell
You probably know how to get rid of that smell, right? We should simply implement a predicate method and this is exactly what was done:
[crayon-4fae4603f1afa/]
This is much better because of two reasons. First of all we hide the private state of an object behind a public predicate method which is simply cleaner. Secondly if, for some reason, the logic for calculating the value of reader_visibility becomes more complex we will simply implement that in the predicate method. Well, it’s probably not going to be the case here but you get the idea.
What about “Tell, Don’t Ask”?
This rule is also related to the attribute smell. Whenever you rely on an object’s attribute to make a decision what to do next – you’re violating “Tell, Don’t Ask” and you’re introducing the attribute smell. Here’s a quick example:
[crayon-4fae4603f1b3d/]
This subtle difference is important because the library object should know how to deal with an empty books array and it should not be a concern “outside” of the library object. We also rely on the books property which indicates the attribute smell.
Summing Up
As you can see the attribute smell is easy to find and fix. The important thing to remember is that when you rely on the internal state of the objects you make future refactorings very difficult. So just don’t do that. Objects should expose as little information about their internal state as possible. Make things publicly visible only if you’re certain it’s really really needed. Rely on API that your objects provide instead of their internal state. This will make your life much easier.
In the next post we’ll deal with the “Control Couple” smell.
więcej...
