#504 new
bahuvrihi

warning-free RSpec (a solution for 'useless use of ... in a void context' warnings)

Reported by bahuvrihi | August 22nd, 2008 @ 08:59 PM | in No-Milestone-Assigned

In 2006 a ticket was filed regarding the 'useless use of ... in a void context' warnings that come up when you run RSpec with the -w flag (see ticket 7101: http://rubyforge.org/tracker/?fu...).

The ticket is closed but I have a solution. The warning comes up because nothing is done with results of statements like:


  1.should == 1

In fact, simply doing this:


  1 == 1

Will cause a warning while this does not, because the true result is now being used for something:


  def check(*args)
  end

  check 1 == 1

One solution for warning-free RSpec is to define the check method as above... then if you want to run without warnings, you simply add 'check' before the problematic should statements:


  check 1.should == 1

Personally I think a check method like this should be included. Running ruby with -w is often useful to find issues in code, and it's unfortunate that RSpec itself may cause warnings.

Comments and changes to this ticket

  • Aslak Hellesøy

    Aslak Hellesøy August 23rd, 2008 @ 01:49 PM

    This could work, but I think there is a risk that some people will do things like:

    
      check body.weight == 77
    

    and get a lot of false positives. Or am I being paranoid?

  • bahuvrihi

    bahuvrihi August 23rd, 2008 @ 05:19 PM

    That's a good point. One option is to validate the check line includes a should/should_not statement.

    You can get at this information by using SCRIPT_LINES__ (which, if set to a hash, will store all lines parsed into the interpreter) and caller:

    
      # A method serving as the dumping ground for 'should ==' statements
      # that otherwise cause a 'useless use of <method> in void context'
      # warning. Useful if you're running tests with -w.
      #
      #   check 1.should == 1
      #
      # Check will validate that the line calling check contains a
      # should/should_not statement; the check fails if it does not.
      def check(return_value)
        caller[0] =~ /^(([A-z]:)?[^:]+):(\d+)/
    
        check_file = SCRIPT_LINES__[$1]
        violated("could not validate check: #{$1} (#{$3})") unless check_file
    
        # note the line number in caller
        # starts at 1, not 0
        line = check_file[$3.to_i - 1]
        violated("check used without should/should_not statement: #{line} (#{caller[0]})") unless line =~ /\.should(_not)?[^\w]/
      end
    

    That's the method... the attachment illustrates should/should_not statements executing without warning and a false positive causing a violation. Run '% rake spec' to get it going.

    The only downside to this, as I see it, is that you have to use SCRIPT_LINES, which will require a bit more memory and probably be minutely slower... but neither is a big deal, I imagine. Maybe there is a way to determine if you're running with -w? There must be... then you only set SCRIPT_LINES when running with -w, and have 'check' raise an error/warn otherwise. That way it's kind of an optional, use-it-if-you-want-it system.

    What do you think?

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Behaviour Driven Development for Ruby.

Shared Ticket Bins

People watching this ticket

Attachments