Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

abandon calling `get` on Option and generate compile error

Tags:

scala

scalaz

If I want to generate compile time error when calling .get on any Option value, how to go about doing this?

Haven't written any custom macros but guess it's about time for it? Any pointers?

like image 498
Vikas Pandya Avatar asked Oct 17 '14 09:10

Vikas Pandya


2 Answers

There is a compiler plugin called wartremover, that provides what you want. https://github.com/typelevel/wartremover

It has error messages and warning for some scala functions, that should be avoided for safety.

This is the description of the OptionPartial wart from the github readme page:

scala.Option has a get method which will throw if the value is None. The program should be refactored to use scala.Option#fold to explicitly handle both the Some and None cases.

compiler plugin

To add wartremover, as a plugin, to scalac, you need to add this to your project/plugins.sbt:

resolvers += Resolver.sonatypeRepo("releases")

addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.11")

And activate it in your build.sbt:

wartremoverErrors ++= Warts.unsafe

macro

https://github.com/typelevel/wartremover/blob/master/OTHER-WAYS.md descripes other ways how you can use the plugin, one of them is using it as a macro, as mentioned in the question.

Add wart remover as library to your build.sbt:

resolvers += Resolver.sonatypeRepo("releases")

libraryDependencies += "org.brianmckenna" %% "wartremover" % "0.11"

You can make any wart into a macro, like so:

scala> import language.experimental.macros
import language.experimental.macros

scala> import org.brianmckenna.wartremover.warts.Unsafe
import org.brianmckenna.wartremover.warts.Unsafe

scala> def safe(expr: Any):Any = macro Unsafe.asMacro
safe: (expr: Any)Any

scala> safe { 1.some.get  }
<console>:10: error: Option#get is disabled - use Option#fold instead
              safe { 1.some.get  }

The example is adapted from the wartremover github page.

like image 184
bmaderbacher Avatar answered Sep 29 '22 03:09

bmaderbacher


Not strictly an answer to your question, but you might prefer to use Scalaz's Maybe type, which avoids this problem by not having a .get method.

like image 39
lmm Avatar answered Sep 29 '22 01:09

lmm