This will either be the first of a series of posts on "how I became a Ruby convert" or "why Ruby is the worst language on the planet."
I've spent the last two years of my life working with Python and its popular web frameworks (Django, webapp2, and Flask). Python was the first language I ever learned, so I'm admittedly a bit biased toward the "Pythonic" way of doing things. Python favors readability of code, but it also favors exactitude. I can push bits around in memory with the same ease as a GET request. The entire community feels like it's made up of scientists who want to support that - so libraries follow the Pythonic way of doing things. Boolean tests are written the same way in each library as they are in the core Python language.
So you can imagine my frustration when I start working with Ruby on Rails... and specifically, RSpec.
Let's take a look at a webapp2 test:
import unittest import webapp2 import main # assuming that 'main' is the name of our application class TestHandler(unittest.TestCase): def test_hello(self): request = webapp2.Request.blank('/') response = request.get_response(main.app) self.assertEqual(response.status_int, 200) #assuming that page should return Hello, world! self.assertEqual(response.body, 'Hello, world!')
See how nice that looks? I've got a Test Handler, which hits my main page with a GET request. The response is called by
get_response. Then I assert that the response has a 200 status code and a body of 'Hello, world!' This is simple; it is exact. It looks like a computer science project, but you also have no doubts about what you're getting.
Let's look at this in Ruby. If I want to write a simple Boolean check, similar to the above, I could do this:
require 'test/unit' require 'net/http' class TestHandler < Test::Unit::TestCase def test_hello request = Net::HTTP.get('localhost', '/') response = http.request request assert_equal response.code, 200 assert_equal response.message, 'Hello, world!' end end
I can work with this. The double colon syntax is a little weird, but I could get used to that. Now, coming from Python... I expect that I will write unit tests in a similar manner, even if I fire up another testing framework. RSpec can't be that bad, right?
I'm following a very nice walkthrough over at RailsApps that takes the reader through the construction of a Ruby on Rails app. I selected one that makes use of Devise for user authentication, RSpec for unit testing and Cucumber for behavior testing. I say to myself "oh, I have heard some things about this RSpec, let's see how cool it is."
This is a test for
index.html in RSpec:
require 'spec_helper' describe HomeController do describe "GET 'index'" do it "should be successful" do get 'index' response.should be_success end end end
WHAT THE HELL IS THIS.
This is some half Ruby core/half RSpec crap that I'm seeing in front of me. All I have to do is require
spec_helper and suddenly I can just screw up the entire vibe of my code. This does not make me happy. Now I've got to deal with this hipster code where
it "should be successful" is a valid Boolean test. Per the documentation: "RSpec uses the words 'describe' and 'it' so we can express concepts like a conversation. But that doesn't appear to be how the core of Ruby works - meaning that I have no idea when I'm supposed to be writing this pseudocode or writing actual Ruby.
Perhaps I'm off base. Maybe, once I get over the learning curve, this method of striving for natural language will make sense. But right now, I've encountered my first core gem that is just jacking my entire understanding of the language's flow around - and I've only been dealing with Ruby for a week or so. I can only hope it won't be this way for the rest of my learning experience.