0

I found Option[Map[String, String]] works weirdly like this:

 scala> val fileInfo: Option[Map[String, String]] = Some(Map( "type" -> "hoge" ))
 fileInfo: Option[Map[String,String]] = Some(Map(type -> hoge))

 scala> fileInfo.get("type")
 res1: String = hoge

I think the Option "get" method doesn't take any argument, so this is super weird for me. Why does it work? Is it an implicit conversion or a bug? I want to make sure how it works.

My specifications are:

  • Scala version 2.9.2
  • Java 1.6.0_43
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
buster84
  • 232
  • 2
  • 10

3 Answers3

12

This desugars to fileInfo.get.apply("type"), i.e. you are not really passing a parameter to Option#get, but calling .apply("type") on the result.

Ben James
  • 121,135
  • 26
  • 193
  • 155
4

Scala allows you to omit braces in some cases and you've been a victim of ambiguity that this feature created: what you've done is simply unwrapped Option (and get underlying Map) -- Option has not only widely used .getOrElse, but also unsafe .get method which fails with exception when there is None:

val fileInfo: Option[Map[String, String]] = Some(Map( "type" -> "hoge" ))
val map = fileInfo.get
// map: Map[String,String] = Map(type -> hoge)
// now actual map lookup
map("type")
// res0: String = hoge

// but this obviously won't work
val throwy: Option[Map[String, String]] = Option(null) // None
throwy.get("type")
// java.util.NoSuchElementException: None.get
Community
  • 1
  • 1
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
  • Thanks. Yeah, that code was written by my coworker. Once I saw the code, I am like having a car accident... In this case I don't like sugar syntax, so I persuade him to change his code like your snippet. – buster84 Apr 24 '13 at 23:58
2
fileInfo.get("type")

is translated to:

fileInfo.get().apply("type")

So you unwrap the option and then get an element on the Map. (apply gets an element of the map non-optional, i.e. fails if the key doesn't exist).

gzm0
  • 14,752
  • 1
  • 36
  • 64