Below code should be a good example of strange Ruby behaviour when it comes to the OR operator:
def search_by_name_active
if request.path == (name_search_registrants_path \
|| new_registrant_path)
'active'
end
end
And the specs:
describe "#search_by_name_active" do
it "should return active if current page is new_registrant" do
allow(helper.request).to receive(:path).and_return(new_registrant_path)
expect(helper.search_by_name_active).to eq('active')
end
end
Which gives me an error:
Failure/Error: expect(helper.search_by_name_active).to eq('active')
expected: "active"
got: nil
If I remove the brackets:
def search_by_name_active
if request.path == name_search_registrants_path \
|| new_registrant_path
'active'
end
end
The first spec will passed but not the below one:
it "should return nil if current page is not search_by_name" do
allow(helper.request).to receive(:path).and_return(id_search_registrants_path)
expect(helper.search_by_name_active).to be_nil
end
Failure/Error: expect(helper.search_by_name_active).to be_nil
expected: nil
got: "active"
WTF?! Is there any other way to write this logical equation besides an additional if like below?
def search_by_name_active
if request.path == name_search_registrants_path
'active'
elsif request.path == new_registrant_path
'active'
end
end
CodePudding user response:
This behaviour is expected in all programming languages, not just ruby. To simplify your example a little:
x == (a || b)
...is not equivalent to:
(x == a) || (x == b)
The first expression is evaluating (a || b)
before comparing it to x
. So you're only comparing x
to one of the values, not both of them.
The generic way to write this in all programming languages would to instead use the second code sample above. Or in other words, using your specific example:
if request.path == name_search_registrants_path \
|| request.path == new_registrant_path
Or, there are a couple of ruby-specific ways we can shorten this code:
# Works in any ruby code
if [name_search_registrants_path, new_registrant_path].include?(request.path)
# Works in any rails code
if requst.path.in? [name_search_registrants_path, new_registrant_path]
The second example is rails-specific, because it's using this extension to the core ruby language.