Rspec runner setting $KCODE considered harmful?

I ran across a problem today in which some code ran fine in regular
operation but failed in a test case. I scratched my head and thought
“why
would running from within the test harness change the behavior of my
code?”
Clearly it was the Heisenberg uncertainty principle in action! :slight_smile:

I discovered the root cause was that the rspec runner is setting the
magical
ruby global, $KCODE, to ‘u’. However, my application (which is not a
rails
app) had never specified $KCODE. I was relying on some default behavior
of
regular expressions under ruby 1.8 (byte-wise character matching
semantics)
that change when $KCODE is set to “u”. Specifically, all regular
expressions change their default behavior to utf-8 character-wise
semantics.
A simple example of this phenomenon: kcode_gotcha.rb · GitHub

I’ve corrected the issue on my end by adopting the $KCODE=‘u’ semantics
in
my application, but this led me to a couple comments/questions I thought
would be relevant to raise with other rspec-minded folks:

  • Is it necessary for rspec to set $KCODE or is this a bug? Wouldn’t it
    be
    better if it didn’t twiddle any magical globals that change
    interpreter-wide
    behaviors? It reminds me of the bad days of perl when some distant code
    would unexpectedly change out your line terminator character on you.

  • It seems like a good idea to call out all the things the rspec
    environment
    changes that affect natural runtime behavior of code: twiddling of
    globals,
    class monkey patches, etc. It’d be great to get these into a list of
    publicly documented pitfalls for people to watch out for.

Thanks for listening. Rspec has brought huge value to my engineering
project
and I really appreciate the tool!

-Josh

On Sep 22, 2010, at 9:47 PM, Josh Whiting wrote:

Thanks for listening. Rspec has brought huge value to my engineering project and I really appreciate the tool!
I don’t remember the details, but that was added to solve a particular
problem back in 2005 or 2006. Changing it in RSpec-1 would break some
existing specs with a minor upgrade, so that’s a non-option.

This does not get set, however, in RSpec-2. I added a note about this to
http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown

Cheers,
David

On Thu, Sep 23, 2010 at 6:44 AM, David C.
[email protected]wrote:

This does not get set, however, in RSpec-2. I added a note about this to
http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown

Great, thanks for the pointer. Agreed changing something like this
should
probably not be done a point release…

Cheers
Josh