7

I need to access a large set of Java interfaces from Scala. These interfaces have methods that might return Null, and I want to convert them to Option[T]

I found other answers that describe Option.apply() like these

How to implicitly wrap a value that can be null or an array into an Scala Option

Option-izing Java getters

However, this requires that for each Java interface, I manually create a Scala wrapper. Like this...

class ScalaFoo extends JavaFoo {
  def bar = Option(super.bar)
}

That seems messy, hard to maintain, and prone to error. I don't want all that extra code that does nothing, and I want to automatically wrap all my Java interfaces, so that if one changes, the wrapper also changes.

Surely, there is a way to do this with implicits, isn't there?

Community
  • 1
  • 1
opus111
  • 2,744
  • 4
  • 25
  • 41

2 Answers2

3

I recently ended up with something like this:

object Implicits {
  implicit class ConvertToOption[T](t: T) {
    def optional = Option(t)
  }
}

Usage:

Suppose you have a following Java interface:

public interface Fooable {
    public String getFoo();
}

public class Foo implements Fooable {
    public String getFoo() { 
        return null; 
    }
}

In your Scala code:

import Implicits._

val foo = new Foo()
val myOptionalValue = foo.getFoo.optional //returns an Option[String], in this case None because getFoo returns null
serejja
  • 22,901
  • 6
  • 64
  • 72
  • Thanks serejja, that's better. I was hoping there was some way to wrap the whole interface so I (or others) can not make the mistake of calling getFoo directly. – opus111 Mar 02 '14 at 17:31
  • I doubt you can achieve what you just said in a generic way. You have to manually write wrappers – serejja Mar 02 '14 at 17:39
3

I'm not aware of a great way to do this either. However I saw a nice approach on twitter recently:

import Option.{apply => ?}
val fooBar = ?(javaFoo.bar)
joescii
  • 6,495
  • 1
  • 27
  • 32
  • 3
    Haha, nice one. And how about this? `implicit class ConvertToOption[T](t: T) { def ? = Option(t) }`. Results in `foo.getFoo?` – serejja Mar 02 '14 at 18:35
  • I like it! Less typing. Although our Clojure friends may lament the lessened use of parentheses. :) – joescii Mar 02 '14 at 20:23