I'm writing a test that checks coordinates of a point to have a certain value, e.g.:
it "should work" do
p = do_something # returns a Point(x, y)
p.x.should eq 0 # errors (see below)
end
But it fails to compile with the following error:
Error: undefined method 'x' for Nil (compile-time type is (Point | Nil))
I was able to reduce the issue to the following minimal example which does not compile:
struct Point
property x : Int32
property y : Int32
def initialize(@x, @y)
end
end
begin
p = Point.new 0, 0
ensure
p.x == 0
end
Which throws the same error:
❯ crystal src/debug.cr
Showing last frame. Use --error-trace for full trace.
In src/debug.cr:11:7
11 | p.x == 0
^
Error: undefined method 'x' for Nil (compile-time type is (Point | Nil))
Now, I came across a similar bug report on the programming language Github tracker: Nil type check fails when using ensure, apparently this is an issue that has to be addressed by the Crystal language.
My question is, how can I check the value of p.x without triggering this error in an ensure block? I'm kind of clueless how to access this.
For context, I'm writing a cryptographic library which operates on points on the an elliptic curve, so it's everything about checking the coordinates here.
There is a couple of possibilities here, e.g. you can replace the line p.x == 0 with either of:
p.try &.x == 0 - p will be checked for being Nil, and only when it's not Nil, the comparison will run.p.not_nil!.x == 0 - you command the compiler that p can never be Nil, but if it actually happens to be nil, the line will raise at runtime.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With