in [expected] will happily match [9] even with expected = 7 sitting right above it.
expected = 7
case [9]
in [expected] then puts "ok, expected=#{expected}"
end
That prints ok, expected=9. It reads like "accept only seven". It isn't. A bare variable in a pattern binds whatever arrives, so expected gets overwritten and the branch runs.
in [^expected] is the fix, and it compares against the value you already have. Fine once you know it. It's also a lot of meaning for one tiny hat.
For a single comparison I'm happy with the pin. Once the condition grows, in [value] if value == expected shows the binding and the test as two visible steps, and I'd take that over a clever compact pattern that hides what is being checked. Where a condition gets too big for the pin, I can't say yet.