Category: Ruby

  • Creating service apps with Rails at tonight’s Ruby meetup

    This is another brief reminder that I’ll be giving a preview of my RailsConf talk at tonight’s Ruby meetup. The meetup starts at 7 PM at Red Hat headquarters. Hope to see you there!

  • Preview my RailsConf talk at this month’s Ruby meetup

    For those who live in the RTP area, I’ll be giving a preview of my RailsConf talk at the Raleigh-area Ruby Brigade meetup on April 17th. We meet at Red Hat headquarters on NCSU’s Centennial Campus at 7:00 PM. I’ll be talking about Teascript, homesteading, and building niche web apps that generate passive income. The talk is pretty solid, but I’ll still be asking for feedback from the group on what can be added or improved. See you there!

  • RubyConf in the southeast

    The Ruby community in the Research Triangle Park area of North Carolina has been growing by leaps and bounds lately, in large part due to the fantastic job Nathaniel Talbott has been doing with the local Ruby Brigade. Another sign of the growing interest in Ruby and Rails in the area is the just-announced Ruby Hoedown, a RubyConf of sorts that’s being hosted by the Brigade in the Raleigh area on August 10th and 11th. Details are sketchy, but you can register on the site to receive more information as it becomes available. And to all you aspiring speakers, now is the time to start thinking about what you’d like to present at the conference!

  • Overriding existing Rake tasks

    I added some long-running integration tests to a Rails application today and quickly began getting irritated that issuing the rake command runs all tests… unit, functional, AND integration. Since I run rake quite frequently, any sizable delay can quickly get annoying.

    The task that gets executed by rake is the :test task. After spending a few minutes trying to replace it, I discovered that there isn’t an immediately obvious way to override an existing task in Rake. After jumping through a few hoops, though, I did manage to do it.

    First, here’s my replacement for the existing :test task:

    task :test do
      Rake::Task["test:units"].invoke rescue got_error = true
      Rake::Task["test:functionals"].invoke rescue got_error = true
      raise "Test failures" if got_error
    end
    

    All it does is run the unit and functional tests, but no integration tests. I stuck this in my Rakefile right after the require 'tasks/rails' line. Next up, I reopened the Rake::TaskManager module to create my own little helper method to remove a task:

    Rake::TaskManager.class_eval do
      def remove_task(task_name)
        @tasks.delete(task_name.to_s)
      end
    end
    

    Lastly, I called this method from another method defined inside my Rakefile. This way, I could use syntax like remove_task :test which would fit with my other task definitions in the file. This is how everything looks put together (remember that this code should be inserted immediately after the require 'tasks/rails' line or it won’t work):

    Rake::TaskManager.class_eval do
      def remove_task(task_name)
        @tasks.delete(task_name.to_s)
      end
    end
    
    def remove_task(task_name)
      Rake.application.remove_task(task_name)
    end
    
    # Override existing test task to prevent integrations
    # from being run unless specifically asked for
    remove_task :test
    task :test do
      Rake::Task["test:units"].invoke rescue got_error = true
      Rake::Task["test:functionals"].invoke rescue got_error = true
      raise "Test failures" if got_error
    end
    

    This did the trick for me, but it’s kind of long. Anyone know a better way of doing it?

  • Selecting matching key/value pairs from a hash

    I ran into a situation today where I needed to pull out all key/value pairs from a hash that matched the keys in a pre-existing array. This is what I initially came up with:

    hash = { :foo => "foo", :bar => "bar", :bat => "bat" }
    hash.symbolize_keys.reject { |k, v| ![:foo, :bar].include?(k) }
    
    >>> returns { :foo => "foo", :bar => "bar" }
    

    Kind of ugly, ain’t it? I sure don’t want to repeat those lines elsewhere. Let’s see if we can do better:

    class Hash
      def select_all(*attrs)
        symbolize_keys.reject { |k, v| !attrs.include?(k) }
      end
    end
    
    { :foo => "foo", :bar => "bar", :bat => "bat" }.select_all(:foo, :bar)
    
    >>> returns { :foo => "foo", :bar => "bar" }
    

    Now that’s more like it. Extending Hash lets me call a method directly on my hash. I can also use this method anywhere in my Rails application if I place the Hash code in lib/hash.rb and require 'hash' from my environment.rb file. Isn’t Ruby beautiful?

    Anyone else have a better way of doing this? I’m open to suggestions.

  • AppleScript via Ruby

    Nice to see Ruby getting some attention on a non-Ruby blog.

  • Andy Hunt crashes raleigh.rb tonight

    Andy Hunt will be speaking at the Raleigh-area Ruby Brigade meetup tonight. It’s sure to be a good show, so grab a fellow geek and head on down to Red Hat headquarters at 7 PM. Signs will direct you to the correct room. Also, if you want an even bigger helping of Ruby tonight, join us at 5:30 PM at Baja Burrito for our traditional round of pre-meeting chow and conversation.

  • Mind blowing Ruby

    I’ve been writing Ruby code for over four years now. I’ve been getting paid to do so for about two years. Prior to that, the bacon I brought home came mainly through the careful crafting of lines of Java, PHP, and C# code. Matz spoiled the party for me in the mid-90s, however, by releasing such a wonderfully beautiful language that it made Java tedious and uninteresting in comparison.

    Ruby is a fantastic tool. But it’s not just a tool, it’s also an art medium. I had never truly seen beautiful code until I met Ruby. All that being said, when I was first introduced to the language it was a lot like trying to breathe while standing under Niagara Falls. The “wow-that’s-cool-but-I-don’t-quite-grok-it” moments came fast and furious. Ruby was blowing my mind on a daily basis.

    It doesn’t anymore. At least, not every day. But at least once a month, I see a code snippet or read a blog post or hear about a new way to do something and… well, there goes my mind again. For example…

    (more…)

  • Introduction to rcov, code coverage for Ruby

    Do you routinely test your code? Are you using rcov to run code coverage reports for your tests? If you aren’t, you should be. rcov is a code coverage tool for Ruby that is available as a Gem or a Rails plugin. It can generate text or HTML reports outlining what percentage of your code base is being exercised by your tests. The HTML reports even allow you to drill down and see exactly which lines in your code are being touched. If you’ve ever used a tool like Cobertura for Java, you’ll know exactly what to expect with rcov.

    Using rcov on a regular basis will enable you to isolate parts of your codebase that aren’t being tested very well (if at all). For example, the first time I ran rcov on one of my projects, it reported that the tests written against my Rails models touched 87% of the code. Not too shabby! However, my Rails controllers only had 45% coverage. Where do you think I concentrated my testing efforts after rcov was kind enough to inform me of these facts?

    Installing and using rcov with an existing Rails project is a cinch. Let’s get started:

    gem install rcov
    

    Now move to the root of your Rails project and type:

    script/plugin install http://svn.codahale.com/rails_rcov
    

    Voila! Installation complete. Don’t you just love Rails? Now let’s fall in love with Rake:

    rake test:units:rcov
    rake test:functionals:rcov
    

    Running these tasks will generate a text-based report of your project’s code coverage. The percentage of each class covered is listed, along with a total for the entire set of tests (unit vs. functional). Rcov also creates a /coverage directory beneath the root of your Rails project. Inside this directory, you’ll find some beautiful HTML-based coverage reports.

    Want to report on just your model classes? What about controllers? Easy enough:

    rake test:units:rcov SHOW_ONLY="app/models"
    rake test:units:rcov SHOW_ONLY="app/controllers"
    

    Delightful. Now I’d be set if only rcov integrated with Zen’s autotest to display a coverage report that automatically updates every time I change some code. One other minor nitpick is that, much as it seems like rake test:rcov should work, it doesn’t. Something else to add to a future release, I suppose.

    Are you in a team environment? Hook rcov up to a continuous integration system and catch Jonny slacking off on his tests… a full half hour before the morning stand-up meeting.

    For the price, you can’t beat what rcov provides. It won’t tell you if your tests are logically correct, but it sure as heck will scream at you if you’re not writing them to begin with.

  • RubyConf 2006: Day 3

    The last day of RubyConf is now almost over. It was a seriously great conference. As I mentioned previously, I’ve never been to a RubyConf before so I didn’t know what to expect. I’m glad I went. It was great hanging out with some seriously smart people. Several of the presentations went clear over my head. Several were quite entertaining. Most were incredibly intriguing. The Google Summer of Code talks were all excellent. Nice job, guys. It’s great hearing about what other folks are working on. Not only does it make me want to dig into their code, it also makes me want to keep hacking on my own projects. David, Chad, and Rich, thanks so much for coordinating this. It was a blast.

    Oh, and before I forget, yes, I do have more pics. Actually, MANY more pics. But they’ll have to wait. I’m in Lousville, it’s late, I’m tired, and I’m on vacation. If you’re lucky, maybe I’ll post these once I get back to Raleigh. And I don’t want any questions about why I’m not using Flickr and tagging them, by the way. This is the way I like doing it, and just like Matz is the benevolent dictator of Ruby, I am the benevolent dictator of my blog. Well, maybe not dictator. King, maybe. President. CEO.