Season 1

0002 - How and why to avoid nil

nils are most of the time, time bombs, which don't cause problems right away (when they are born/spawned/gotten/assigned for the first time/etc.), but cause problems later, when some other piece of code tries to use them, and blows up because that code did not expect a nil.

The most offending thing is, since the code blew up after the nil was created, it's not obvious from the crash stacktrace where did that nil come from.

He discusses several ways of "handling" nils; I particularly liked the first one: arrange things so your code blows up, not when handling a nil, but then first obtaining it. That way, at least the backtrace will tell you where did that come from.

To be honest, I did not understood the other ways of managing nils. I might re-visit this because of that.

0003 - Building rspec from scratch

How to write DSLs in Ruby, using rspec as an example/guide/goal. It's nice, and understandable.

0005 - Extracting domain objects

This seems to me basically the same idea I got from Grails (the web framework): you don't have to cram your business logic in the models; most of time, you can put it in another "kind" of module, which is neither model nor view nor controller: the service.

The domain objects, for him, fulfill the same function that service modules perform in another languages/frameworks.

Actually, I think that he's kinda trapped in domain objects, because all you have in ruby are class-like things (classes and modules) which are not actually modular because you can't import just a single method/function from a module, it's always all or nothing.

0006 - Conflicting principles

A better way of writing list_of_things.collect {|thing| thing.something}

[1, 2, 3].collect(&:succ)  #=> [2, 3, 4]

Also, he mentions services! service classes.

What the what is "tell don't ask". Oh, Martin Fowler explains. Tell the object what should be done, instead of ask ing it for data and manipulating it and doing the thing yourself. Should have been "tell don't take" or "for fucks sake delegate". But I disgress.

This principle, and Demeter's Law, seem to me to be just trying to control needleses coupling in functions: tell your object to do something, instead of asking for its internals (and violating Demeter's Law) and doing it yourself, because, fundamentally, if you do that yourself you now no longer depend just on that object, but also on the object's internal structure, which might change. These two principles try to keep you out of that mess. That's ... not bad.

What IS bad is that the two guys who presented that concept for the first time (here) are also kinda trying to get you to use privates and access qualifiers and stupid shit like that. I guess we can forgive them because it was sort of still the 90's when they wrote that and collective experience using software you did not write hadn't shown yet what a stupid idea is to use access qualifiers for attributes/methods in class definitions.

0007 - Growing a test suite

Oooh, rspec has a matcher to check that a (countable) value changed from something to something else

expect {thing_that_changes_count}.to change {counter}.by some_amount

0008 - Processes and jobs

Job control

All this time and I haven't gone through how to use jobs in the shell. fg brings the last suspended job back.

jobs gives you a list of jobs, along with their IDs.

You can say fg ${job_id} if you want a specific one.

But also, you can allow one of those suspended jobs to keep running, without getting into the foreground, using bg ${job_id}

output as files

In a shell, command <(another_command) takes the output of another_command and makes it look as if it was a file, at least from command's point of view.

So you can do stuff like:

vim <(head .bashrc)

or something like that.

0009 - Exceptions and control flow

Nothing noteworthy.

Fast tests with and without Rails

He writes tests for a service. The service (and its tests) are not part of the rails application, they live in lib/ (and rspec/lib).

The tests are really fast, because:

  • He does not load neither Rails nor bundle.
  • He uses stubs instead of ActiveRecord instances.

0016 - A refactoring story

Did he just show a bunch of "git log"s after doing a refactor? I lost my time here.

Actually, I just decided to watch this because it's kind of a prerreq for the "wrapping third party APIs"

0017 - Wrapping third party APIs

About testing response handling from remote APIs

It's interesting to look at how he tests requests to third party APIs: by stubbing the responses he would obtain from the real endpoint.

Which is pretty much the same you get from using the VCR/cassettes facility; the VCR library:

  • Figures out what the stubbed response would look like, by performing an actual request to the third party API, once. And uses that response for the test.
  • Auto-generates the stubbed response in further requests.

If you test a response by stubbing it manually, you will have to adjust it should the response structure change, in the future.

Or, if you are using VCRs, you adjust your test by re-recording the cassette. And that's it.

About test speed

The difference in speed between rspec tests that require rails, versus tests that don't, is abysmal. So much, that it makes me reconsider using factories, and replacing them with stubs/mocks, just for the speed gain.

I think he also mentions in the video how much slower is rspec when you run it via bundle, and admits to not having a clue about why it is that slow. That makes two of us, buddy :/

Although, I'd like to try parallel-rspec first.