I have a case
in my Ruby code that basically tries to match string in a couple of ways and do different things to it accordingly, kind of like that:
case inst
when Rx_inst1
(some function)
when Rx_inst2
(some other function)
end
This works beautifully (I'm not posting the RegEx as it's very, very long and works well). However, when I tried implementing the following modification, so that even when the RegEx matches a string, the condition is not executed if it contains a substring:
case inst
when Rx_inst1
(some function)
when Rx_inst2 && !/dom\./
(some other function)
end
it Rx_inst2
stopped matching inst
when it was equal Nm. Friese = Fryzyjczyk, koń fryzyjski
Nm. Friese = Fryzyjczyk, koń fryzyjski
or any other kind of string it matched before.
I got the exact same result with && /dom\\./
and && inst.include?('dom.')
which, according to other answers, are proper syntax. What am I doing wrong?
case inst
when Rx_inst1
(some function)
when Rx_inst2 && !/dom\./
(some other function)
end
case translates into bunch of if/elsif/else statements with .=== operator so your code is equvalent to
if Rx_inst1 === inst
(some function)
elsif (Rx_inst2 && !/dom\./) === inst
(some other function)
end
and (Rx_inst2 && !/dom\\./) === inst
works like this:
(Rx_inst2 && !/dom\\./)
part evaluates to !/dom\\./
(Rx_inst2 is a RegEx and is not nil or false) !/dom\\./ === inst
gives you the result so when Rx_inst2 && !/dom\\./
matches whenever !/dom\\./ === inst
matches
It's pretty obvious, Rx_inst2 && !/dom\\./
returns (due to short circuit evaluation) value of the second operand, which is !/dom\\/
(provided Rx_inst2
is indeed a Regexp
and thus truthy). You probably need to modify this regexp in Rx_inst2
, there's no short answer.
Alternatively, you could change all this case
expression a little bit, like this:
case
when inst =~ Rx_inst1
# (some function)
when inst =~ Rx_inst2 && !(inst =~ /dom\./)
# (some other function)
end
but it isn't expecially elegant form, in my opinion.
@Darigazz has nicely explained how case
works and why your code is faulty. Here are a couple ways you might write your case statement.
#1
case inst
when Rx_inst1
m1
when Rx_inst2
m2 if inst.match? /dom\./
end
nil
is returned if inst.match? /dom\\./ #=> false
inst.match? /dom\\./ #=> false
in m2 if inst.match? /dom\\./
m2 if inst.match? /dom\\./
. Depending on requirements, if
might be replaced by unless
.
#2
case inst
when Rx_inst1
m1
when /(?=.*dom\.)#{Rx_inst2}/
m2
end
where (?=.*dom\\.)
is a positive lookahead . For example,
Rx_inst2 = /Bubba|Trixie/
/(?=.*dom\.)#{Rx_inst2}/
#=> /(?=.*dom\.)(?-mix:Bubba|Trixie)/
Depending on requirements, (?=.*dom\\.)
might be replaced by the negative lookahead (?!.*dom\\.)
.
Okay, so it turned out I made it work like that:
when (!inst.include?('dom.') and Rx_inst2)
I still don't understand why I had to do all these three following things, though:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.