Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are two things that need to be considered here.</p> <p>First, there is the problem of the "nothing". How do you chain things when a part of the chain may not return anything? The answer is using <code>Option</code> and <code>for</code> comprehensions. For example:</p> <pre><code>scala&gt; case class Address(city: Option[String] = None, street: Option[String] = None, number: Option[Int] = None) defined class Address scala&gt; case class Contact(name: String, phone: Option[String] = None, address: Option[Address] = None) defined class Contact scala&gt; case class ContactDetails(phone: Option[String] = None, address: Option[Address] = None) defined class ContactDetails scala&gt; case class Contact(phone: Option[String] = None, address: Option[Address] = None) defined class Contact scala&gt; case class Person(name: String, contactDetails: Option[Contact] = None) defined class Person scala&gt; case class Company(name: String, contactPerson: Option[Person] = None) defined class Company scala&gt; val p1 = Company("ABC", Some(Person("Dean", Some(Contact(None, Some(Address(city = Some("New England")))))))) p1: Company = Company(ABC,Some(Person(Dean,Some(Contact(None,Some(Address(Some(New England),None,None))))))) scala&gt; val p2 = Company("Finnicky", Some(Person("Gimli", None))) p2: Company = Company(Finnicky,Some(Person(Gimli,None))) scala&gt; for(company &lt;- List(p1, p2); | contactPerson &lt;- company.contactPerson; | contactDetails &lt;- contactPerson.contactDetails; | address &lt;- contactDetails.address; | city &lt;- address.city) yield city res28: List[String] = List(New England) </code></pre> <p>This is how you are supposed to write code which may return something or not in Scala.</p> <p>The second problem, of course, is that sometimes you may not have access to the source code to do the proper convertion. In this case, there is some additional syntax overhead to be head, unless an implicit can be used. I'll give an example below, in which I use an "<code>toOption</code>" function -- there is such a thing on Scala 2.8, of which I'll talk about below.</p> <pre><code>scala&gt; def toOption[T](t: T): Option[T] = if (t == null) None else Some(t) toOption: [T](t: T)Option[T] scala&gt; case class Address(city: String = null, street: String = null, number: Int = 0) defined class Address scala&gt; case class Contact(phone: String = null, address: Address = null) defined class Contact scala&gt; case class Person(name: String, contactDetails: Contact = null) defined class Person scala&gt; case class Company(name: String, contactPerson: Person = null) defined class Company scala&gt; val p1 = Company("ABC", Person("Dean", Contact(null, Address(city = "New England")))) p1: Company = Company(ABC,Person(Dean,Contact(null,Address(New England,null,0)))) scala&gt; val p2 = Company("Finnicky", Person("Gimli")) p2: Company = Company(Finnicky,Person(Gimli,null)) scala&gt; for(company &lt;- List(p1, p2); | contactPerson &lt;- toOption(company.contactPerson); | contactDetails &lt;- toOption(contactPerson.contactDetails); | address &lt;- toOption(contactDetails.address); | city &lt;- toOption(address.city)) yield city res30: List[String] = List(New England) </code></pre> <p>Remember that you can be quite creative in naming a function. So, instead of "<code>toOption</code>", I might have named it "<code>?</code>", in which case I'd write things like "<code>?(address.city)</code>".</p> <p>Thanks to nuttycom for reminding me, on Scala 2.8 there is an <code>Option</code> factory on the object <code>Option</code>, so I can just write <code>Option(something)</code>. In effect, you can replace "<code>toOption</code>" above with "<code>Option</code>". And if you prefer using <code>?</code>, you can just use <code>import</code> with rename.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload