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 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 == 77and get a lot of false positives. Or am I being paranoid?
-

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]/ endThat'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.
