01 Oct 2012
Go, Rust, Erlang, R, Closure and what all the new(er) languages around the block are all called. But one thing is certain: They are all niche languages. Why is that? Why don't we have another C or Java? One language to rule them all?
If you have ever chosen a new language to program in, you know the steps: Look at whats available, dabble in them, find out what other people think about it. Or you might do it like I did. Chose a framework, and then learn the language that this framework is written in. This way I got started in Ruby.
Big Languages Are The Past, Right?
But is the time for big languages, ones that we use for everything, coming to an end? Maybe. The last "big" language is C#, and just because it got a lot of promotion from Microsoft. Before that? Java. C. Cobol. Let's not go further into the past please!
And while no new all purpose language has come out, we get more and more niche languages. R for data processing. Rust for systems programing. ClosureScript for writing web applications in a LISP dialect.
Programming Languages Have A Short Lifespan
Is the time of the all purpose programming language coming to an end? I think so. There was a time when a company would use one language. One framework. One database. One operation system.
But today? Employees chose their operation system. Databases are mix and matched freely for whatever purpose they serve best. And programming languages are intermingled in huge systems.
The Programming Language Lifecycle
Programming languages seem to have a limited lifetime. They take a few years to mature, are then picked up, and a few more years later, replaced by something new.
And I think we should all embrace this change. Because we learn a lot about language design, programming. CPUs get faster and faster, so the language designers can get away with even more every year.
Is this cycle inevitable? Yes. It is. There are some languages which try to dump every new thing into it (hello Java, hello C#!).
But look at what happens when you just put everything in your fridge in a pan and let it cook for an hour. You get crap! The same thing happens to languages as well. The only fix is to do something new, which takes full advantage of that new paradigm.
No Good Programmer Knows Just One Language
Programmers who can just use one language are becoming a rarity. Does who do will soon be obsolete. So don't think just because you use Ruby you are save. Ruby is quite popular right now, so according to the language life cycle, it will soon be made obsolete by something better.
Will everyone switch to the new thing? Of course not, there is a good reason why big companies still search for Cobol programmers.
But those of us who want to stay ahead, who want to belong the circle of not just good programmers, but great programmers. We can't look the other way. We can't ignore all new languages and stay too comfy with our current languages.
Don't have a holy cow that you aren't ready to slaughter!
If you liked this post, you should consider hiring me freelance, part-time or full-time!
24 Sep 2012
Ah, constructors. The little, forgotten, and often abused thing. No one really thinks about it for long, no one really knows what it does. Everyone tends to ignore it until they think they need it and throws things into it with no care whatsoever. Yes, the constructor might be the best equivalent to a homeless child.
And yet, recently, I started thinking more and more about
homeless children constructors. They are a defining character of all object-oriented programming languages. And they do fulfill an important role! So let's learn a bit more about the homeless constructor.
Do's in a Constructor
Ever had a class that felt awkward to use? Where you, in practically ever method, first checked if some precondition was fulfilled? That might mean you have forgotten to put something in a constructor.
The simple rule is:
Everything the class needs in order to work goes into the constructor. For example, recently I wrote a small proxy to
Nokogiri. The class looked something like this:
class XmlHelper
def open(file)
@file = Nokogiri::XML(file)
end
def find_uas
raise 'Open the file first' unless @file
# read file etc.
end
end
With one method, that might work. But how would I add a second method here? I would have to do the same check if the file is actually opened again. Which means
the class isn't ready for operation after the constructor is called! So I fixed this the easy (but hey, stylish!) way:
class XmlHelper
def initialize(file)
@file = Nokogiri::XML(file)
end
def find_uas
raise 'Open the file first' unless @file
# read file etc.
end
end
Yes, one small change. From now on, when someone wants to make an instance of XmlHelper, he
has to provide a file to read. Which means the class is ready to be used.
Put things into the constructor if the class can't feasibly be used without it.
Another great use of constructors? Dependencies! Of course, you could add a dependency like that:
class Limb
@child = Child.new
end
We have two problems with this:
- The Limb class knows too much about its surroundings. Maybe it just needs to tell the child that it is tired. But what if we suddenly want to use the Limb class with an Adult? A dog? We can't do that with this implementation!
- Another problem is testing. We can't, in a unit test, easily replace Child with a mock or a stub. Maybe instantiation of a child is difficult (it takes 9 months for gods sake!) Or we simply want to test the interaction between Limb and Child, which is difficult if we don't know to which Child this Limb is talking to. (Remember: A constructor shouldn't do real work!)
The better way to do it?
class Limb
def initialize(body)
@body = body
end
end
Ah, now it's obvious, right? We can simply add a new body that this Limb belongs to. And the Limb doesn't care anymore if it is a child or not. For the lazy who don't want to type
Limb.new(child) all the time, we can also change the initialize call to
def initialize(body = Child.new) ... end so the Child is automatically added if we don't specify something else.
But Don't Put These Things Into the Constructor!
So now that we have a usable object after construction, what doesn't belong in there? Should we just throw everything into there?
Now that we know what to throw into a constructor, it is easy what not to throw into a constructor. In short: Everything else. If not every method in the class needs this property, if the class doesn't need this information to work correctly, then don't add it to the constructor! If some methods need a property, and the others don't, you probably should split the class up into two.
They deal with different things.
One special thing though: If the initialization logic is very complex, it might be better to put it into a builder. A builder is a separate object that can be used to build up an object. It can even build objects of different classes (that have the same method, of course) given different input.
Ah, So That's Constructors!
Yes, so it is. So please stop abusing the little homeless kid on the block and treat it with the kindness it deserves. It shouldn't be dropped all responsibilities, but don't forget that it is there and you can use it.
To summarize:
Pass a constructor all the information the class needs to work properly, but nothing more.
Have I forgotten some use case for constructors? Do you know some other constructor abuse cases? Then drop a line either here in the comments or on
Twitter!
If you liked this post, you should consider hiring me freelance, part-time or full-time!
17 Sep 2012
Just recently
Jim Weirich released
rspec-given 2.0, an extension to the RSpec DSL. It tries to add
given,
when,
then semantics to RSpec. Why? Because
given,
when,
then state
intent. So everything in a
given will be something that you expect to be present.
when is the part that should actually be tested and
then states what should happen.
This makes it easier to see what is just a test helper, which code is actually under test and what should happen to the different moving parts. Go read the
readme in the rspec-given repository, Jim does a way more thorough job at explaining the semantics. Or if you know Cucumber, you can just continue! For the rest, I will be waiting, right here.
Back already? Good! Let's continue!
A Primer on RSpec Given
So, if we want to write a Math library that uses a very strange notation, a spec could look like this:
describe "Math" do
describe "#+" do
it "adds two values" do
let(:value_one) { 2 }
let(:value_two) { 3 }
Math.+ value_one, value_two
Math.result.should == 5
end
end
end
I know, I know, it's a very contrived example, sorry... :(
But what are we testing now?
Math.+ or
Math.result?
With rspec-given, we could specify intent a lot clearer:
describe "Math" do
describe "#+" do
context "adds two values" do
Given(:value_one) {2}
Given(:value_two) {3}
When { Math.+ value_one, value_two }
Then { Math.result.should == 5 }
end
end
end
So we have two preconditions (setting
value_one and
value_two), which are just there to help the test. Then we have the code we actually want to test (
Math.+). And we have a post condition, that needs to be true at the end. But in the second example it is clear that we don't test
Math.result, but
Math.+! Also notice that
then replaces the need for an
it block.
I guess we all can agree that the second example is way more specific which code is there for what purpose. Which I like.
But that got me to ask one question: How do you extend the DSL? Let's see:
Extending DSLs
First things first (because it wouldn't make sense to mention the first thing at the end I guess? That saying has never made sense to me, sorry...), I'm looking at rspec-given-2.0.0.beta3. This way, Jim can't ninja change things in there and then tell me I'm totally wrong.
Second things second (that doesn't exist, does it?): Let's have a look at the first file:
rspec/given.rb. If we ignore RSpec 1 (someones still using that?), we include different files. One of the interesting files is configure.rb. Here the important lines (actually, all lines in this file except the includes):
RSpec.configure do |c|
c.extend(RSpec::Given::ClassExtensions)
c.include(RSpec::Given::InstanceExtensions)
c.include(RSpec::Given::HaveFailed)
end
(
On Github)
He uses RSpec.configure to extend and include a few extensions. If we take a look at RSpecs rubydocs, we can find
RSpec.configure. Even more important, the Configuration object has two methods:
extend and
include! Now that's handy, because that's exactly what we used!
These two are really similar.
#extend is used to add methods to example groups (but not the examples itself). It is added to the
describe block, but not the
it block.
Now guess what
#include does. Right! It adds methods to the example itself, but not to the example group!
Now we know how we can add custom stuff to RSpec examples and example groups! Which is exactly what rspec-given does!
The class and instance extensions can be seen in
extensions.rb.
That's How You Extend a DSL
RSpec nicely enough provided everything we need to extend it's syntax with our own methods. Of course this isn't just handy for rspec-given. Everyone can extend RSpec with its own syntax, which might come in handy once in a while.
I suggest you have a look at the
RSpec Configuration object, because it can actually do a lot. Did you know that it can show you the 10 slowest examples, automatically? Or that RSpec has
before, after, and around hooks?
So not only have we learned what rspec-given is, how it works, but also how we can extend RSpec ourselves! Thanks Jim!
If you liked this post, you should consider hiring me freelance, part-time or full-time!
10 Sep 2012
Fun Fact: You most likely fall into the same trap that I do: The expert's dilemma!
The Expert's Dilemma?
Yes, the expert's dilemma. What is it, you might ask. In fact, if you don't ask yourself this question right now, why are you even reading? Maybe this piece then isn't for you. If you are, however, wondering what that is and why you most likely also fall into this trap, read on.
The expert's dilemma is quite simple: We try to emulate experts as well as we can. We try to listen to their opinions, follow them, and carry out everything they say. The problem with that? If you are not an expert,
most of the things they say don't matter to you!
Yes, seriously!
Let me illustrate through two examples: Fitness and Starcraft II. I know, I know, both of those have nothing to do with programming (except that progamer looks almost like programmer), but bear with me. Just a moment now.
Let's talk about Starcraft II
Starcraft II is a really simple game. You have so-called harvesters, that gather resources. With these resources you can build more gatherers, units to attack or defend, or new structures and research to make everything stronger. Simple as that.
Now of course the pros are talking about balance, and that this unit might be a bit better if it had one attack power more than it has now. Or that if you delay action X, you can do action Y Z seconds faster. And other such fun things. If you follow all this advice, you fall into the trap of the expert's dilemma.
When I started playing Starcraft II, it worked something like this:
Andreas: "Wohoo, I play Starcraft II. Let's just try to play so I have fun!"
The Pro: "But Andreas, what are you doing? You should have a plan, you should scout your opponent!"
One week later
Andreas: "Whohoo, I play Starcraft II. I even scout!"
The Pro: "But Andreas, what are you doing? You should control each unit into his last detail!"
One week later
Andreas: "Wohoo, I have a lot of free time!"
Why did that happen? Because I tried to follow all the experts advice, I forgot that I first need to learn the basics: Gathering resources! So I started to lose a lot and I quit.
So all the questions about balance and all that don't play a role for people like me, because other things play a much bigger role. For the pros who play all in the same percentile, they do. But for me?
Let's talk about fitness
Ah, fitness. Where everyone has an opinion. And everyone has a different opinion. It sucks! It makes it hard to start. So let's take the journey for a normal beginner (like me!):
Andreas: "Wohoo, I started with a fitness routine! So I run a few times per week and do some bodyweight exercises."
The Pro: "But Andreas, what are you doing? Running hurts your muscle gain, so stop that!"
One week later
Andreas: "Wohoo, I started to do a lot of bodyweight exercises!"
The Pro: "But Andreas, what are you doing? If you would vary them more, you could get better results! Also, start doing them on 5 days instead of 3."
One week later
Andreas: "Wohoo, I'm playing Starcraft II!"
Queue a rage comic here...
Result: Instead of following what I was doing and enjoying, I stopped doing anything. Instead of getting 80% of the results, I now get 0%!
This Is A Blog About Programming, Right?
Yes, absolutely. Now let me tie it back to programming.
TDD, BDD, refactoring,
SOLID, performance, method to line ration, line per class ratio, test coverage, newest trends, etc. etc. etc. Sounds familiar? Do you get it now? No?
Damn it!
That was the point of the whole post.
Let me try again: There are a lot of buzzwords and other things to follow, which can choke a beginner. A beginner should be doing. (
Careful: Controversial statement following!) If it isn't perfect, who cares?
It is more important to do than to do it perfectly!
Experts Are Nice, But...
I know the experts just mean well. But a beginner or intermediate
can't possibly follow all advice! It will confuse her or him more than actually following through with it!
So don't blindly follow experts advice, just keep being awesome and improving along the way!
Don't get bogged down, don't try to do it all perfectly from the beginning. Add stuff slowly and concentrate on the basics. Because like in Starcraft II and in fitness, it is better to do the basics right than butchering all the experts advice.
Did you fall into this trap yet? Share your (horror?) stories!
If you liked this post, you should consider hiring me freelance, part-time or full-time!
03 Sep 2012
Developing a Rails application is awesome. Why? Because the testing stack is really, really good! But, this is also a problem. There is so much to choose from, that it sometimes is really hard to figure out what is useful and what isn't.
I don't know about you, but my Gemfile tends to have a lot of stuff in the group
:development, :test.
group :development, :test do
gem 'rspec-rails'
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
gem 'capybara'
gem 'launchy'
gem 'rr'
gem 'awesome_print'
gem 'jasminerice'
gem 'guard-jasmine'
gem 'poltergeist'
end
Holy crap that's big! Of course, it also has some helpers only for development:
group :development do
gem 'guard'
gem 'libnotify'
gem 'guard-spork'
gem 'guard-cucumber'
gem 'guard-rspec'
gem 'guard-livereload'
gem 'spork'
gem 'pry-rails'
gem 'pry-stack_explorer'
gem 'pry-debugger'
end
Not too shaby, huh? So let me get into the details for each of those.
Guard
Guard is an amazing tool to automate nearly everything. Don't believe me? Take a look at all the possible
Guard extensions on Github! So what does Guard do?
It basically is a system that runs in the background and can watch files. Extensions tell it (through a
Guardfile
) that it should do something if a specific file pattern changes. For example, the
Cucumber guard checks for this:
guard 'cucumber', :cli => "--drb" do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
end
It looks at all features in the features directory, and Guard will call the Cucumber guard if one of these files changes. In term, guard-cucumber will call Cucumber and show it to you on the console. Neat, isn't it?
Of course, this isn't just for Cucumber! I also use the
RSpec guard (for RSpec tests, duh!),
Spork and
livereload.
Spork is a DRb (Distributed Ruby) server that preloads the Rails environment so the tests run faster. Adding this guard makes Guard start the DRb server for Cucumber and RSpec automatically when starting Guard itself.
Another very neat guard is guard-livereload. Thanks to an extension in Chrome, this guard will automatically reload the page I have open when I change the ERb or the CSS files. Makes fiddling with CSS a lot easier!
You Have To PRY It From My Cold Dead Hands
PRY is one of those tools that you just have to know (and love). It is an alternative to IRB, and way better! Just add a
binding.pry to your code and Pry will open in that context when the code runs over it. It allows you to change into classes and objects to inspect them more closely. And edit the methods if you want to!
Some additions I added to Pry (and there are a few
Pry plugins) are
pry-debugger, so I can step through code and see what it really does. To complement Pry Debugger, I also use
pry-stack_explorer. This plugin allows us to move up the stack and see the state of the code there.
Of course, in a perfect world, we never have to use one of these tools, but yeah... Real world and these things...
Testing tools
You might now say: "Hey! You said you will talk about
testing tools, not support tools!" And you are right! (Though these support tools are amazing for testing!)
Yes, testing tools. For my testing needs I use the standard combo
RSpec,
Cucumber,
database_cleaner,
Capybara and
rr stack. I don't think I have to explain these (Do I? If I do, you should tell me so in the comments!)
Additionally I use
launchy to launch a browser window with the current state of the page to debug Cucumber steps.
I also make copious use of
awesome_print, because it is, well, awesome! awesome_print can be used instead of
puts or
pp to output objects and have an easier time inspecting them. (Pry also can use awesome_print for it's built in printing habits!)
Last But Not Least: JavaScript Testing
Something I struggled with for a bit, but found a good solution for, is JavaScript testing. There are two aspects here: One is Cucumbers Javascript support. For some acceptance tests, I needed Javascript to run. Per default, Cucumber uses Selenium (with a real browser), which is slow and not awesome at all! And then there are the Javascript unit tests, that also need to run.
For the unit tests I settled on
Jasmine. Why? Because it seems it even tries to be as close to RSpec as possible, so I don't have to learn yet another testing system. To run them, I of course, use a guard:
guard-jasmine (Who's surprised?)
guard-jasmine uses
PhantomJS to run the Javascript tests in a headless mode (without a user interface), which makes them fast (not incredibly fast, but at least fast).
Of course we also want to integrate the Jasmine unit tests with the asset pipeline so we can use CoffeeScript. Luckily, Brad Phelan solved that problem and released
JasmineRice.
Now, this doesn't yet solve the Cucumber problem. For that, we can use
Poltergeist. Poltergeist is a PhantomJS driver for Capybara. Do you see how this neatly matches up with guard-jasmine? Nice, isn't it? I just configured Capybara to use Poltergeist instead of Selenium, and now the tests run at an acceptable rate.
So, What's Your stack?
Yes, that is my "standard" Rails testing stack. I think this covers about everything I need. One thing that's not included (because I currently don't need it) is something like
VCR. VCR records HTTP interactions, so that during testing the HTTP calls don't have to be made, but can be replayed by VCR. Which makes things even quicker.
Have I missed something? Added something superfluous? What do you use for your testing stack?
If you liked this post, you should follow me on Twitter and sign up for the RSS feed!