RSpec 2 Matcher Fun

Posted by Nick Sieger Thu, 20 Jan 2011 17:47:21 GMT

I was troubleshooting some JRuby code that transforms Java camelCase method names into Ruby snake_case form. We had a bunch of specs that did this, for example:

describe "Java instance method names" do
  it "should present javabean properties as attribute readers and writers" do
    methods = MethodNames.instance_methods

    methods.should include("getValue2")
    methods.should include("get_value2")
    methods.should include("value2")

    methods.should include("setValue2")
    methods.should include("set_value2")
    methods.should include("value2=")

The problem comes when these specs fail. The default error message made by the #include matcher looks like:


  1) Java instance method names should present javabean properties as attribute readers and writers
     Failure/Error: methods.should include("get_value2")
       expected [...full contents of array here...] to include "get_value2"
       @@ -1,2 +1,186 @@
       +[...all entries, one per line here...]

That’s not a terrible message, but when your array contains over 100 entries (like an array of method names), it could be a lot better. In particular, I kept scanning the failure message’s big list, unable to clearly see why the methods I was expecting weren’t there.

What I wanted to see was how my changes to the regex which splits a Java camelCase name affected the conversion. So, what I needed was a report of which method names were the closest to the ones that were not in the list. Hey, sounds like a good reason to implement a custom matcher, and take a diversion into fuzzy string matching algorithms!

I settled on porting the pseudocode in Wikipedia for the Levenshtein distance, which calculates how close in content two strings are to each other. I looked around and there are existing Levenshtein ports for Ruby, but they use native code for performance. I don’t need performance because I’m only using the Levenshtein function when there is a failure. Of course, pure Ruby code is more portable too!.

The other change I made in the specs was to pass all strings in a single matcher rather than one name per expectation, so we can see all names that fail, not just the first.

So now, the new spec looks more like this:

describe "Java instance method names" do
  let(:members) { MethodNames.instance_methods }

  it "should present javabean properties as attribute readers and writers" do
    members.should have_strings("getValue2",

The custom RSpec matcher #have_strings is declared like so:

RSpec::Matchers.define :have_strings do |*strings|
  match do |container|
    @included, @missing = [], []
    strings.flatten.each do |s|
      if container.include?(s)
        @included << s
        @missing << s

  failure_message_for_should do |container|
    "expected array of #{container.length} elements to include #{@missing.inspect}.\n" +
      "#{closest_match_message(@missing, container)}"

  failure_message_for_should_not do |container|
    "expected array of #{container.length} elements to not include #{@included.inspect}."

  def closest_match_message(missing, container) do |m|
      groups = container.group_by {|x| levenshtein(m, x) }
      "  closest match for #{m.inspect}: #{groups[groups.keys.min].inspect}"

I omitted the #levenshtein function here for brevity. (You can view the full source for details.) Now our failing spec output looks like:


  1) Java instance method names should present javabean properties as attribute readers and writers
     Failure/Error: members.should have_strings("getValue2",
       expected array of 185 elements to include ["get_my_value", "my_value", "set_my_value", "my_value="].
         closest match for "get_my_value": ["get_myvalue", "set_myvalue"]
         closest match for "my_value": ["myvalue"]
         closest match for "set_my_value": ["get_myvalue", "set_myvalue"]
         closest match for "my_value=": ["myvalue="]

Now the failure message is giving me exactly the information I need. Much better, don’t you think?

Tags ,

War on Perfect

Posted by Nick Sieger Mon, 22 Nov 2010 18:30:00 GMT

I intended to give this brief as a lightning talk at RubyConf 2010, but unfortunately did not get a chance. Though I kept the message simple, I think if you sympathize with being a perfectionist you can find some part of these points that rings true. I know I still have a ways to go in heeding my own advice, and not only in software but in my life as a whole.

Thanks to Hiro Asari for the Japanese translations and Jeremy Hinegardner for the numbers.

War on Perfect

I want to start a war.


A war on Perfection!




I hate this word.


I want to eliminate it from our vocabulary.


What is Perfect?


Ask 10 people, get 10 answers.


Different answers means disagreement.


Perfection cannot accept compromise.


Without compromise, we cannot get along, or get anything done.

妥協無しには、仲良くやって行ったり 何かを成し遂げる事は出来ないでしょう。

(Just look at politics in the USA.)


Perfect is lonely if you can’t agree or share with anyone else.

他人と合意や共有が出来ないので 完璧主義とは孤独でもあります。

We are human. No one wants to be alone.


Perfect is contagious


If you’re not embarrassed when you ship your first version you waited too long.


-- Matt Mullenweg マット・マレンウェグ

How many Ruby gems have never seen 1.0?


Any guesses?


17864 Rubygems 86837 versions バージョン

13496 gems without a version that does not start with “0”. 75 Percent!


I challenge you all to release 1.0 on your first push to Rubygems next time.


Perfect is impossible


If you seek it, you will never quite attain it.


You will worry it’s not perfect enough, and it will escape your grasp.


Perfect keeps you too focused on one thing.


Your mind will cripple you.


You won’t be able to finish it.


You’ll feel helpless because nothing is ever good enough.


Perfect ruins your productivity.


You’ll feel like your work is never done.


Perfect is harmful to your health.


We work too hard to achieve perfection.


We set our personal standards too high.


And rarely reach them.


So we worry about not being good enough.


This makes us ANXIOUS.


Anxiety can give you stress,


make you sick,


or even kill you.


We can’t be happy if we’re anxious or unhealthy.


We can’t be happy if we accept no compromises.


We can’t be happy if we’re alone.


We can’t be happy if we strive for perfection.


Matz knows this. He is WISE!


Ruby is not perfect.


(Matz knows this too!)


Matz made Ruby so we could be happy.


Perfection keeps us from:


making compromises,


getting things done,


enjoying each other’s company,


being happy.


And that’s why I hate it.


So you can either try to be:


Perfect [and be]








or you can be HAPPY.


I’ll choose to be happy. I hope you do too.



Tags , , , ,

RubyConf India 2010!

Posted by Nick Sieger Fri, 12 Mar 2010 23:21:04 GMT

I’m honored to be heading to the first ever RubyConf India in Bangalore next week. I’ll be delivering an update on Rails 3, JRuby, and what’s in store for the future of the combined platform in 2010. I’m looking forward to meeting you there!

I'm speaking at RubyConf India 2010

Tags , ,  | 2 comments

Gem clash: activerecord-jdbc-adapter and pg

Posted by Nick Sieger Thu, 28 Jan 2010 15:16:49 GMT

I got a note from a community member about an annoying problem that a few people have run into when installing activerecord-jdbc-adapter (AR-JDBC) into a C Ruby implementation:

NameError: uninitialized constant

Turns out it’s pretty easy to momentarily forget to use jruby -S gem or jgem and just gem install activerecord-jdbc-adapter and suddenly your pg Postgres gems are not working properly. I thought it was worth documenting here in case others run into this problem.

I apologize for the clash. I had to provide a stub pg.rb in AR-JDBC inside of JRuby so that I could get active_record/connection_adapters/postgresql_adapter.rb to load with a database adapter type of postgresql. Because of load path order issues, I couldn’t get AR-JDBC’s code to load before ActiveRecord’s. At the time I was thinking this wouldn’t be a problem because the pg library won’t work on JRuby anyway, right? Wrong.

I can think of a couple options going forward:

  1. Submit a patch to ActiveRecord so that active_record/connection_adapters/postgresql_adapter.rb can load without requiring pg up front and then AR-JDBC won’t have to stub it out.
  2. Display a big fat warning message when AR-JDBC is installed into anything other than JRuby.

Any other thoughts?

Tags ,  | 2 comments

New Hpricot Release

Posted by Nick Sieger Fri, 06 Nov 2009 16:06:37 GMT

It’s with a modicum of fanfare and a cocktail of orange peel, maraschino, bitters, bourbon and vermouth that I announce the 0.8.2 release of Hpricot.


The angly thingies are just two martini glasses turned on their side, see? Pouring out hpricoty goodness for you. (I don’t know if _why imbibed alcoholic beverages but I feel the desire to raise a glass to him.)

This release is mostly a refresh; the previous release was way back in April. From the Git logs I can see that there were a few bug fixes since then. Otherwise, the main addition is a modern JRuby release, thanks to Ola Bini. (the previous was the 0.6 series). This does fix a fairly old, popular JRuby bug.

As for the future of Hpricot, it’s up to you. I know it’s still a trusty tool for many; I have no grand plans to change it. So if you encounter bugs and want to send patches, I’m happy to serve as your curator.

Tags , , ,  | 2 comments

Which Tool Would You Use?

Posted by Nick Sieger Fri, 12 Jun 2009 20:34:27 GMT

I started in on the twice-yearly task of pruning our hedges today. So confronted with this task:

Shearing the shrubs

Which tool would you use?

Which tool?

I used both today, but realized I enjoy using the hand trimmers much more. With the electric trimmers, you can buzz through a lot of hedge quickly, but sometimes this happens:

Too close

With the hand trimmers, I can take my time and make precise cuts. The end result may take more time, but it turns out much, much better.

Software tools have similar feels to me. Java feels an awful lot like the electric trimmers. It’s heavy and powerful, but sometimes by the time you’ve finished with it, you’ve cut so far in that you may have missed a simpler, lighter solution.

Ruby feels like the hand trimmers. Precision, less code, more intent, and I can take my time to think through and arrive at a solution without leaving a huge trail of trimmings (code) behind me.

Tags  | 4 comments

Three Years of JRuby on Rails

Posted by Nick Sieger Wed, 13 May 2009 21:21:37 GMT

Just yesterday the 3-year mark of JRuby running Rails passed by. In the intervening period since JRuby first started to run Rails, we’ve seen:

And yet, JRuby still has plenty of untapped potential and room for growth and adoption: in the existing Ruby and Rails communities where JRuby is showing promise as a stable, performant, concurrency-enabled, and leak-proof platform; and as a transformative force to capture the mindshare of a huge army of Java developers who aren’t even aware that there’s a language and runtime that allows them to preserve their skills and existing code while developing new applications faster and with much greater enjoyment.

Here’s looking to the future of continued growth for JRuby over the next three years. The best is yet to come!

Tags , ,  | 4 comments

My Article for Ruby Advent 2008

Posted by Nick Sieger Fri, 19 Dec 2008 05:04:00 GMT

I wrote an article for Ruby Advent 2008 about using JRuby, RMagick4J, Gruff, and JMX to create a simple JVM memory monitoring application. Go check it out and let me know what you think.

I’ve also posted the source for the article.

Happy Holidays!


Tags , , , ,  | 1 comment

QCon: Interviewed by Fabio Akita

Posted by Nick Sieger Mon, 24 Nov 2008 18:51:00 GMT

Fabio Akita played the role of the Energizer Bunny, making a blur around the hallways at QCon. He managed to catch me on Thursday morning, and we had a great chat.

Fabio Bunny

Go check out our conversation on Akita On Rails to hear my take on JRuby and Rails 2.2 and more. Thanks for doing the interview Fabio!

Tags , , ,  | no comments

QCon Wrap-up: Enterprise, Have You Met Ruby?

Posted by Nick Sieger Sun, 23 Nov 2008 08:51:03 GMT

This year’s QCon San Francisco conference was my first time attending, and it was an eye-opener for me for several reasons.

First, the tutorial Ola and I gave on Monday went well, though I was mildly surprised to find that only about 10% of the attendees at our talk had any familiarity with Ruby. This turned out to work just fine as we were able to adjust and fill in a little bit of the back story on both Ruby and Rails. Still, to try to convey a sense of Ruby, Rails, and JRuby all in the span of a 2.5 hour session is a tall order!

Next, I was impressed with the diversity the conference organizers were able to achieve. There were tracks on agile development, cloud computing, REST, DSLs, design and clean code, Ruby, functional programming, real-world architectures, storage rethinking, and more. Tracks were relevant and topical even if the quality of talks was mixed.

The last item relates to my perception that Ruby is not yet seen as a worthwhile tool for enterprise software development. It leaves me with some cause for concern, though it reflects more on the state of the industry rather than on the way Ruby was presented at the conference itself.

What does it mean for Ruby to be “ready for the enterprise”? Does that imply JRuby? Running on the JVM or a Java application server, or even .NET? Reams of XML? Presence of buzzwords, such as JMS, Spring/Hibernate? Or ability to adapt to or leverage legacy code? All of these?

I would argue that Ruby already has everything it needs to be a successful enterprise software development platform, even without using JRuby. Ruby has a mature standard library, a large and ever-growing list of gems and extensions, and a vibrant community. Testing tooling, certainly seen more and more as a critical piece of software development, is also an area where Ruby excels (and brings a strong culture bias toward testing as well). Add JRuby to the mix and the ability to leverage existing infrastructure as well as code, and the picture gets even stronger. Best of all, Ruby the language is a malleable medium perfectly suited for gluing enterprise components together, creating DSLs on top of stable layers and remaining clean enough to be eminently readable and maintainable. Yet behind-the-firewall deployments appear to be elusive; if they do exist, they’re small, isolated apps that work so well, the community doesn’t hear about them. Judging from the low level of participation in Ruby-related talks at QCon, I’m inclined to believe the former.

I was speaking with Jay Fields about this topic on Friday. Jay also noticed that the the Ruby and DSL tracks were sparsely attended. (For that matter, so was the functional programming track.) His observation was that the track content was not marketed and tailored enough toward toward solving enterprise-class problems, or being approachable enough in that regard. We can certainly do better.

Do we have an issue here? Are we, the Ruby community, being too insular and not concerning ourselves enough with bringing Ruby-based solutions to the enterprise? Or perhaps businesses are waiting for more organizations that can provide services, support and indemnification? Does there need to be a Ruby, Inc. (or even a JRuby, Inc.) that looks at common enterprise problems and devises best-of-breed solutions (a sort of SpringSource for Ruby) for things like enterprise integration, security and identity, reporting, business workflow, decision support, etc. ad infinitum? Ruby should be able to do all of those while bringing the increased agility and productivity that we’ve all experienced.

I seem to have raised more questions than I am able to answer at this time. Of course, the obvious answer is that adoption of Ruby will just need more time, but I’m not willing to accept that as the only reason. I’d love to hear your opinions on contributing factors and what can be done to mitigate them. It seems like there’s a huge opportunity waiting to be tapped to help make Ruby more enterprise-worthy.

And yet, despite the less-than-stellar turnout for Ruby at QCon among conference attendees, I still had a great week, and would go back again. QCon is a fun and well-organized event overall, and I got the impression that the folks present were on the leading edge of “the enterprise”, which is exactly the people we need to engage to bring about growth in adoption of Ruby. For that reason, I hope we can kick it up a notch and take another shot at pimping Ruby at the next one. Maybe I’ll see you there!

Tags ,  | 12 comments

Older posts: 1 2 3 ... 5