07.16.08

Fixing “undefined method `exitstatus’ for nil:NilClass”

Posted in Ruby at 3:12 pm by Robert Horvick

I’m trying to get some more practical experience with Ruby so I’ve started converting a few batch files that automated instrumenting some .NET assemblies for code coverage.  Basically it comes down to cleaning out some directories, running a child process in a loop, and pushing some binaries out to a sandbox test area.

It seemed like a good opportunity to also get some experience writing rake tasks.

The interface right now is:

coverage coverage:all    # Perform a complete code coverage pass from scratch
coverage coverage:clean  # Clean the coverage temp directory and sandbox
coverage coverage:cover  # Instrument the assemblies for code coverage
coverage coverage:merge  # Merge the test results
coverage coverage:run    # Run the test suite
coverage coverage:start  # Start the coverage service
coverage coverage:stop   # Stop the coverage service

During development I was doing something I thought was pretty simple - executing a process in a loop for each file in a FileList.

C:\ruby\coverage>rake coverage:cover
"E:\Program Files/Dev Suite}/instrument.exe" "foo.dll" /COVERAGE "/OUTPUTPATH:C:/output/coverage"
rake aborted!
undefined method `exitstatus' for nil:NilClass
C:/ruby/coverage/rakefile:36
(See full trace by running task with --trace)

See the problem?  I didn’t … (now it’s all I see!)

I re-ran rake with –trace and got a little more detail.  The top of the stack is:

rake aborted!
undefined method `exitstatus' for nil:NilClass
c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:899:in `sh' 

That makes sense … I’m calling sh.

In rake.rb line 899 is for this method:

def sh(*cmd, &block)
    options = (Hash === cmd.last) ? cmd.pop : {}
    unless block_given?
      show_command = cmd.join(" ")
      show_command = show_command[0,42] + “…”
      # TODO code application logic heref show_command.length > 45
      block = lambda { |ok, status|
        ok or fail “Command failed with status (#{status.exitstatus}): [#{show_command}]”
      }
    end
    rake_check_options options, :noop, :verbose
    rake_output_message cmd.join(” “) if options[:verbose]
    unless options[:noop]
      res = system(*cmd)
      block.call(res, $?)
    end
  end

 
This is where I spent 5 minutes not making the mandatory mental leap. That’s how long it took to realize that

block = lambda { |ok, status|

is creating a block object which will be called later at the block.call.

So status.exitstatus is “$?” and “$?” is the exit status of the child process … and it’s NilClass so that must mean the process never executed … which means I need to start with the most obvious culprit: the command line (specifically the executable path).

So go back to the origional error message … now do you see it? (if you don’t - there is a “}” after “Dev Suite”

C:\ruby\coverage>rake coverage:cover
"E:\Program Files/Dev Suite}/instrument.exe" "foo.dll" /COVERAGE "/OUTPUTPATH:C:/output/coverage"
rake aborted!
undefined method `exitstatus' for nil:NilClass
C:/ruby/coverage/rakefile:36
(See full trace by running task with --trace)

It sucks that rake is not resiliant to this. So I updated my local copy to check for status.nil? like so:

      block = lambda { |ok, status|
        ok or fail "Command failed with status (#{status.nil? ? "nil" : status.exitstatus}): [#{show_command}]”
      }

Summary …

If you are running a rake and get the message “undefined method `exitstatus’ for nil:NilClass” it (probably) means that the program it was trying to run was not found.

 

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

2 Comments »

  1. Luis Lavena said,

    July 16, 2008 at 5:55 pm

    Actually, you got hit by a Ruby for Windows bug :-P

    http://blog.mmediasys.com/2008/05/24/random-bits-and-experiments/

    See under “Less quirk for us” section.

    And the whole issue is covered here:

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/16786

    HTH.

  2. Robert Horvick said,

    July 16, 2008 at 6:14 pm

    @Luis

    Thanks! I appreciate the pointers. Great to see that it’s already being taken care of.

    Robert.

Leave a Comment