Skip to content

Instantly share code, notes, and snippets.

@cloudbring
Created March 12, 2016 02:53
Show Gist options
  • Save cloudbring/bb77ad0b70e6005f0d1e to your computer and use it in GitHub Desktop.
Save cloudbring/bb77ad0b70e6005f0d1e to your computer and use it in GitHub Desktop.
// The unapply method of this object takes a string and returns an Option[String]
//   This means that the value being matched must be a string and the value extracted is also a string
scala>objectSingleParamExtractor {
     |def unapply(v:String):Option[String] =if(v.contains("Hello")) Some("Hello") elseNone
     | }
defined module SingleParamExtractor
// this Will match since the extractor will return a Some object
scala>"Hello World"match { caseSingleParamExtractor(v) => println(v) }
Hello
// this will not match and therefore an exception will be thrown
scala>"Hi World"match { caseSingleParamExtractor(v) => println(v) }   
scala.MatchError:HiWorld
                  at .(:7)
                  at .()
                  at RequestResult$.(:3)
                  at RequestResult$.()
                  at RequestResult$result()
                  at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)
                  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                  at sun.reflect.DelegatingMethodAccessorImpl.invok...
// This extractor converts the string to an int if possible.
scala>objectConvertToInt{         
     |def unapply(v:String):Option[Int] =try{ Some(v.toInt) } catch { case _ =>None }
     | }
defined module ConvertToInt
scala>"10"match { caseConvertToInt(i) => println(i)}
10
// If you want to extract multiple elements you return an Option that contains a Tuple.  
//   In this example we divide the string into two parts if it has a space
scala>objectMultipleParamExtractor {                                       
     |  def unapply(v:String):Option[(String,String)] = (v indexOf ' ') match {           
     |case x if (x>0) =>Some ((v take x, v drop x+1))
     |case _ =>None
     | }
     | }
defined module MultipleParamExtractor
scala>"hello everyone :)"match { caseMultipleParamExtractor(one, two) => println(one,two) }
(hello,everyone :))
// Any object with a unapply method can be used it does not have to be defined as an object
// So if you have a class of extractors that needs to be parameterized you can 
// create a class and use instances of that class for matching
scala>classSplitter(sep:Char){
     |def unapply(v:String):Option[(String,String)] = (v indexOf sep) match {
     |case x if (x>0) =>Some ((v take x, v drop x+1))
     |case _ =>None
     | }
     | }
defined classSplitter
// Remember that we need the matching object start with an uppercase
// See http://daily-scala.blogspot.com/2009/09/case-sensitive-matching.html 
// for details
scala>valSplitOnComma=newSplitter (',')
SplitOnComma:Splitter=Splitter@15eb9b0d
// How cool now can create splitters for all sorts of things
scala>"1,2"match { caseSplitOnComma(one,two) => println(one,two)}
(1,2)
// All extractors can also be used in assignments
scala>valSplitOnComma(one,two) ="1,2"                           
one:String=1
two:String=2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment