Replace .get with operator !

Rationale: when looking for code that might crash it's
easier to spot exclamation marks than invocations of get.
This commit is contained in:
Mark Spanbroek 2021-04-19 15:52:07 +02:00
parent db9e1a343a
commit 0569625f6a
5 changed files with 51 additions and 14 deletions

View File

@ -126,6 +126,19 @@ let z = x |? 3
# z equals 3
```
### Obtaining value with !
The `!` operator returns the value of an Option when you're absolutely sure that
it contains a value.
```nim
x = 42.some
let dare = !x # dare equals 42
x = int.none
let crash = !x # raises a Defect
```
### Operators
The operators `[]`, `-`, `+`, `@`, `*`, `/`, `div`, `mod`, `shl`, `shr`, `&`,

View File

@ -7,7 +7,7 @@ import ./without
include ./errorban
export options
export options except get
export chaining
export indexing
export without
@ -15,6 +15,9 @@ export without
template `?`*(T: typed): type Option[T] =
Option[T]
template `!`*[T](option: ?T): T =
option.get
template `->?`*[T,U](option: ?T, expression: U): ?U =
if option.isSome:
expression.some

View File

@ -8,7 +8,7 @@ import ./without
include ./errorban
export resultsbase except ok, err, isOk, isErr
export resultsbase except ok, err, isOk, isErr, get
export chaining
export indexing
export without
@ -18,6 +18,9 @@ type ResultFailure* = object of CatchableError
template `?!`*(T: typed): type Result[T, ref CatchableError] =
Result[T, ref CatchableError]
template `!`*[T](value: ?!T): T =
value.get
proc success*[T](value: T): ?!T =
ok(?!T, value)

View File

@ -11,6 +11,10 @@ suite "optionals":
check (?string is Option[string])
check (?seq[bool] is Option[seq[bool]])
test "! gets value or raises Defect":
check !42.some == 42
expect Defect: discard !int.none
test ".? can be used for chaining optionals":
let a: ?seq[int] = @[41, 42].some
let b: ?seq[int] = seq[int].none
@ -25,10 +29,10 @@ suite "optionals":
test ".? chain can be followed by . calls and operators":
let a = @[41, 42].some
check a.?len.get == 2
check a.?len.get.uint8.uint64 == 2'u64
check a.?len.get() == 2
check a.?len.get().uint8.uint64 == 2'u64
check a.?len.unsafeGet == 2
check a.?len.unsafeGet.uint8.uint64 == 2'u64
check a.?len.unsafeGet() == 2
check a.?len.unsafeGet().uint8.uint64 == 2'u64
check a.?deduplicate()[0].?uint8.?uint64 == 41'u64.some
check a.?len + 1 == 3.some
check a.?deduplicate()[0] + 1 == 42.some
@ -147,10 +151,10 @@ suite "optionals":
check table.?["a"].isSome
check table.?["a"].isSome()
check table.?["a"][0] == 41.some
check table.?["a"].?len.get == 2
check table.?["a"].?len.get.uint8.uint64 == 2'u64
check table.?["a"].?len.get() == 2
check table.?["a"].?len.get().uint8.uint64 == 2'u64
check table.?["a"].?len.unsafeGet == 2
check table.?["a"].?len.unsafeGet.uint8.uint64 == 2'u64
check table.?["a"].?len.unsafeGet() == 2
check table.?["a"].?len.unsafeGet().uint8.uint64 == 2'u64
check table.?["a"].?deduplicate()[0].?uint8.?uint64 == 41'u64.some
check table.?["a"].?len + 1 == 3.some
check table.?["a"].?deduplicate()[0] + 1 == 42.some
@ -277,6 +281,16 @@ suite "optionals":
let z = x |? 3
check z == 3
# Obtaining value with !
x = 42.some
let dare = !x
check dare == 42
x = int.none
expect Defect:
let crash {.used.} = !x
# Operators
numbers = @[1, 2, 3].some

View File

@ -14,6 +14,10 @@ suite "result":
check (?!string is Result[string, ref CatchableError])
check (?!seq[bool] is Result[seq[bool], ref CatchableError])
test "! gets value or raises Defect":
check !42.success == 42
expect Defect: discard !int.failure error
test ".? can be used for chaining results":
let a: ?!seq[int] = @[41, 42].success
let b: ?!seq[int] = seq[int].failure error
@ -28,10 +32,10 @@ suite "result":
test ".? chain can be followed by . calls and operators":
let a = @[41, 42].success
check (a.?len.get == 2)
check (a.?len.get.uint8.uint64 == 2'u64)
check (a.?len.get() == 2)
check (a.?len.get().uint8.uint64 == 2'u64)
check (a.?len.unsafeGet == 2)
check (a.?len.unsafeGet.uint8.uint64 == 2'u64)
check (a.?len.unsafeGet() == 2)
check (a.?len.unsafeGet().uint8.uint64 == 2'u64)
check (a.?deduplicate()[0].?uint8.?uint64 == 41'u64.success)
check (a.?len + 1 == 3.success)
check (a.?deduplicate()[0] + 1 == 42.success)