Wednesday, January 13, 2010

Comparing Manifests

Manifests are Scala's solution to Java's type erasure. It is not a complete solution as of yet but it does have several useful applications. Manifests were originally added to Scala 2.7 in an extremely limited form but have been improved a great deal for Scala 2.8. Now more powerful comparisons of manifests are possible. For another introduction to Manifests (2.7 manifests) see Manifests.

This post looks at a few ways to create manifests as well as how to compare manifests. The goal is to create a method that can be used in testing to require that a certain exception is thrown during a code block:
  1. scala> intercepts[Exception] {println("hi :)")}                                            
  2. hi :)
  3. Expected java.lang.Exception but instead no exception was raised

The code snippet above is a failure because println does not throw an exception. In addition to requiring manifests this code snippet also is a custom control structure, for more information on those see Control Structure Tag

But before writing the intercepts methods a short inspection of the new manifest comparison operators:
  1. scala> import scala.reflect.{
  2.      |   Manifest, ClassManifest
  3.      | }
  4. import scala.reflect.{Manifest, ClassManifest}
  5. // from class creates a manifest object given a class object
  6. scala> import ClassManifest.fromClass
  7. import ClassManifest.fromClass
  8. // several comparisons using <:<
  9. scala> fromClass(classOf[Exception]) <:< fromClass(classOf[Exception])
  10. res4: Boolean = true
  11. scala> fromClass(classOf[Exception]) <:< fromClass(classOf[RuntimeException])
  12. res5: Boolean = false
  13. scala> fromClass(classOf[Exception]) <:< fromClass(classOf[AssertionError])         
  14. res6: Boolean = false
  15. // now the opposite operator >:>
  16. scala> fromClass(classOf[Exception]) >:> fromClass(classOf[AssertionError])
  17. res7: Boolean = false
  18. scala> fromClass(classOf[Exception]) >:> fromClass(classOf[RuntimeException])
  19. res8: Boolean = true
  20. scala> fromClass(classOf[Exception]) >:> fromClass(classOf[Error])           
  21. res9: Boolean = false
  22. scala> fromClass(classOf[Exception]) >:> fromClass(classOf[Throwable])
  23. res10: Boolean = false
  24. // the method singleType creates a manifest given an object
  25. scala> ClassManifest.singleType(new RuntimeException())
  26. res12: scala.reflect.Manifest[Nothing] = java.lang.RuntimeException.type
  27. scala> ClassManifest.singleType(new RuntimeException()) <:< fromClass(classOf[Throwable])
  28. res13: Boolean = true
  29. scala> fromClass(classOf[Exception]) <:< fromClass(classOf[Throwable])                   
  30. res14: Boolean = true

Now the implementation of intercepts:
  1. scala> import scala.reflect.{
  2.      |   Manifest, ClassManifest
  3.      | }
  4. import scala.reflect.{Manifest, ClassManifest}
  5. scala> 
  6. scala> import ClassManifest.singleType
  7. import ClassManifest.singleType
  8. scala>  def intercepts[E <: Throwable](test : => Unit)(implicit m:Manifest[E]) : Unit = {
  9.      |     import Predef.{println => fail}
  10.      |     try {
  11.      |       test
  12.      |       // this is a failure because test is expected to throw an exception
  13.      |       fail("Expected "+m.toString+" but instead no exception was raised")
  14.      |     }catch{
  15.      |       // this checks that the expected type (m) is a superclass of the class of e
  16.      |       case e if (m >:> singleType(e)) => ()
  17.      |       // any other error is handled here
  18.      |       case e => fail("Expected "+m.toString+" but instead got "+e.getClass)
  19.      |     }
  20.      |   }
  21. intercepts: [E <: Throwable](test: => Unit)(implicit m: scala.reflect.Manifest[E])Unit
  22. scala> intercepts[Exception] {println("hi :)")}                                            
  23. hi :)
  24. Expected java.lang.Exception but instead no exception was raised
  25. scala> intercepts[Exception] { throw new IllegalArgumentException("why not throw this :)")}
  26. scala> intercepts[Exception] { throw new AssertionError("The method should complain")}     
  27. Expected java.lang.Exception but instead got class java.lang.AssertionError

Monday, January 11, 2010

Matching Nulls

As a bit of explanation of one of the techniques in Regex Matching this topic reviews matching nulls.

  1. // No surprise _ matches everything
  2. scala> null match { case _ => println("null") }
  3. null
  4. // again null matches null
  5. scala> null match { case null => println("null") }
  6. null
  7. // a is bound to anything including null
  8. scala> null match { case a => println("matched value is: "+a) }
  9. matched value is: null
  10. scala> val a:String = null
  11. a: String = null
  12. // basically same as last example
  13. scala> a match {case a => println( a + " is null")}          
  14. null is null
  15. // Any matches any non-null object
  16. scala> null match {                                                
  17.      | case a:Any => println("matched value is: "+a)               
  18.      | case _ => println("null is not Any")
  19.      | }
  20. null is not Any
  21. scala> val d:String = null                             
  22. d: String = null
  23. // In fact when matching null does not match any type
  24. scala> d match {                                       
  25.      | case a:String => println("matched value is: "+a)
  26.      | case _ => println("no match")                   
  27.      | }
  28. no match
  29. scala> val data:(String,String) = ("s",null)         
  30. data: (String, String) = (s,null)
  31. // matching can safely deal with nulls but don't forget the catch all
  32. // clause or you will get a MatchError
  33. scala> data match {                                  
  34.      | case (a:String, b:String) => "shouldn't match"
  35.      | case (a:String, _) => "should match"          
  36.      | }
  37. res10: java.lang.String = should match
  38. // again null is all objects but will not match Any
  39. scala> data match {                            
  40.      | case (a:String, b:Any) => "shouldn't match"   
  41.      | case (a:String, _) => "should match"       
  42.      | }
  43. res12: java.lang.String = should match

Regular Expression 3: Regex matching

This post covers basically the same things as Matching Regular Expressions but goes into a bit more detail. I recommend reading both posts since there is unique information in each.

The primary new item I show here is that more advanced matching techniques can be used but more importantly all groups are matched even groups that are within another group.

Note: The examples use Scala 2.8. Most examples will work with 2.7 but I believe the last example is Scala 2.8 only.

  1. scala> val date = "11/01/2010"
  2. date: java.lang.String = 11/01/2010
  3. scala> val Date = """(\d\d)/(\d\d)/(\d\d\d\d)""".r
  4. Date: scala.util.matching.Regex = (\d\d)/(\d\d)/(\d\d\d\d)
  5. /*
  6. When a Regex object is used in matching each group is assigned to a variable
  7. */
  8. scala> val Date(day, month, year) = date          
  9. day: String = 11
  10. month: String = 01
  11. year: String = 2010
  12. scala> val Date = """(\d\d)/((\d\d)/(\d\d\d\d))""".r
  13. Date: scala.util.matching.Regex = (\d\d)/((\d\d)/(\d\d\d\d))
  14. /*
  15. This example demonstates how all groups must be assigned, if not there will be a matchError thrown
  16. */
  17. scala> val Date(day, monthYear, month, year) = date
  18. day: String = 11
  19. monthYear: String = 01/2010
  20. month: String = 01
  21. year: String = 2010
  22. scala> val Date(day, month, year) = date           
  23. scala.MatchError: 11/01/2010
  24. at .< init>(< console>:5)
  25. at .< clinit>(< console>)
  26. // but placeholders work in Regex matching as well:
  27. scala> val Date(day, _, month, year) = date
  28. day: String = 11
  29. month: String = 01
  30. year: String = 2010
  31. scala> val Names = """(\S+) (\S*)""".r             
  32. Names: scala.util.matching.Regex = (\S+) (\S*)
  33. scala> val Names(first, second) = "Jesse Eichar"
  34. first: String = Jesse
  35. second: String = Eichar
  36. /*
  37. If you want to use Regex's in assignment you must be sure the match will work.  Otherwise you should do real matching
  38. */
  39. scala> val Names(first, second) = "Jesse"       
  40. scala.MatchError: Jesse
  41. at .< init>(< console>:5)
  42. at .< clinit>(< console>)
  43. scala> val M = """\d{3}""".r
  44. M: scala.util.matching.Regex = \d{3}
  45. /*
  46. There must be a group in the Regex or match will fail
  47. */
  48. scala> val M(m) = "Jan"
  49. scala.MatchError: Jan
  50. at .< init>(< console>:5)
  51. at .< clinit>(< console>)

The following are a few more complex examples
  1. scala> val Date = """((\d\d)/(\d\d)/(\d{4}))|((\w{3}) (\d\d),\s?(\d{4}))""".r         
  2. Date: scala.util.matching.Regex = ((\d\d)/(\d\d)/(\d{4}))|((\w{3}) (\d\d),\s?(\d{4}))
  3. /*
  4. The Regex has an or in it.  So only 1/2 of the groups will be non-null.
  5. If the first group is a String then it is non-null and the next three elements
  6. the pattern will be day/month/year
  7. Otherwise if the 5th group is a String then the patter will be month day, year
  8. Lastly a catch all
  9. */
  10. scala> def printDate(date:String) = date match {                                      
  11.      | case Date(_:String,day,month,year,_,_,_,_) => (day,month,year)                 
  12.      | case Date(_,_,_,_,_:String,month,day,year) => (day,month,year) // process month
  13.      | case _ => ("x","x","x")                                                        
  14.      | }
  15. printDate: (date: String)(String, String, String)
  16. scala> printDate("Jan 01,2010") 
  17. res0: (String, String, String) = (01,Jan,2010)
  18. scala> printDate("01/01/2010") 
  19. res1: (String, String, String) = (01,01,2010)
  20. /*
  21. A silly example which drops the first element of the date string
  22. not useful but this demonstrates that we are matching agains a sequence so 
  23. the _* can be used to match the rest of the groups
  24. */
  25. scala> def split(date:String) = date match {         
  26.      | case d @ Date(_:String ,_*) => d drop 3       
  27.      | case d @ Date(_,_,_,_,_:String,_*) => d drop 4
  28.      | case _ => "boom"                              
  29.      | }
  30. split: (date: String)String
  31. scala> split ("Jan 31,2004")
  32. res5: String = 31,2004
  33. scala> split ("11/12/2004") 
  34. res6: String = 12/2004
  35. /*
  36. This is just a reminder that the findAllIn returns an iterator which (since it is probably a short iterator) can be converted to a sequence and processed with matching
  37. */
  38. scala> val Seq(one,two,_*) = ("""\d\d/""".r findAllIn "11/01/2010" ).toSeq  
  39. one: String = 11/
  40. two: String = 01/
  41. scala> val Seq(one,two) = ("""\d\d/""".r findAllIn "11/01/2010" ).toSeq   
  42. one: String = 11/
  43. two: String = 01/
  44. // drop the two first matches and assign the rest to d
  45. scala> val Seq(_,_,d @ _*) = ("""\d\d/""".r findAllIn "11/01/20/10/" ).toSeq
  46. d: Seq[String] = ArrayBuffer(20/, 10/)

Friday, January 8, 2010

Regular Expression 2 : The rest Regex class

This is the second installment of Regular expressions in Scala. In the first installment the basics were shown and a few of the methods in the Regex class were inspected. This topic will look at the rest of the methods in the Regex class.

Regex.findPrefixMatchOf
  1. /*
  2. returns the match if the regex is the prefix of the string
  3. */
  4. scala> "(h)(e)|(l)".r findPrefixMatchOf "hello xyz"  
  5. res2: Option[scala.util.matching.Regex.Match] = Some(he)
  6. scala> "lo".r findPrefixMatchOf "hello xyz"  
  7. res3: Option[scala.util.matching.Regex.Match] = None
  8. /*
  9. The method is essentially the same as adding the boundary regex character
  10. */
  11. scala> "^ab".r findFirstMatchIn "ababab"
  12. res8: Option[scala.util.matching.Regex.Match] = Some(ab)
  13. scala> "^ab".r findFirstMatchIn "hababab"
  14. res9: Option[scala.util.matching.Regex.Match] = None
  15. /*
  16. findPrefixOf is the same but returns the matched string instead
  17. */
  18. scala> "ab".r findPrefixOf "haababab"       
  19. res11: Option[String] = None
  20. scala> "ab".r findPrefixOf "ababab"    
  21. res12: Option[String] = Some(ab)

Regex.replaceAllIn -- Essentially the same as using String.replaceAll
Regex.replaceFirstIn -- Essentially the same as using String.replaceFirst
  1. scala> "(h)(e)|(l)".r replaceAllIn ("hello xyz","__")
  2. res13: String = ______o xyz
  3. scala> "hello xyz" replaceAll ("(h)(e)|(l)","__")    
  4. res14: java.lang.String = ______o xyz
  5. scala> "hello xyz" replaceFirst ("(h)(e)|(l)","__")  
  6. res16: java.lang.String = __llo xyz
  7. scala> "(h)(e)|(l)".r replaceFirstIn ("hello xyz","__")
  8. res17: String = __llo xyz

This next section is not Scala specific but because Regex does not provide a way to set the flags CASE_INSENSITIVE, DOTALL, etc... The section is useful to demonstrate how to do it as part of the standard regex syntax.
  1. // examples based on java blog at: <a href="http://www.javaranch.com/journal/2003/04/RegexTutorial.htm#flags">http://www.javaranch.com/journal/2003/04/RegexTutorial.htm#flags</a>
  2. scala> val input = """Hey, diddle, diddle,      
  3.      | |The cat and the fiddle,                 
  4.      | |The cow jumped over the moon.           
  5.      | |The little dog laughed                  
  6.      | |To see such sport,                      
  7.      | |And the dish ran away with the spoon.""".stripMargin
  8. input: String = 
  9. Hey, diddle, diddle,
  10. The cat and the fiddle,
  11. The cow jumped over the moon.
  12. The little dog laughed
  13. To see such sport,
  14. And the dish ran away with the spoon.
  15. // by default regex is case sensitive
  16. scala> """the \w+?(?=\W)""".r findAllIn input foreach (println _)
  17. the fiddle
  18. the moon
  19. the dish
  20. the spoon
  21. /* the (?i)  makes the match case insensitive the complete set of options are:
  22. (?idmsux)
    • i - case insensitive
    • d - only unix lines are recognized as end of line
    • m - enable multiline mode
    • s - . matches any characters including line end
    • u - Enables Unicode-aware case folding
    • x - Permits whitespace and comments in pattern
  23. */
  24. scala> """(?i)the \w+?(?=\W)""".r findAllIn input foreach (println _)
  25. The cat
  26. the fiddle
  27. The cow
  28. the moon
  29. The little
  30. the dish
  31. the spoon

Wednesday, January 6, 2010

Regular Expression 1 : Basics and findAllIn

This is the first of a series on Regular expression use in Scala. There was a previous post related that is also worth looking at but the same tips will be revisited in this series: Matching Regular Expressions.

Perhaps the most important thing for regular expressions in Scala is to be aware of the raw string syntax:
  1. /* 
  2. normal strings treat the \ character as the escape character 
  3. so this fails
  4. */
  5. scala> val normalString = "\.+((xyz)|(abc))"
  6. < console>:1: error: invalid escape character
  7.        val normalString = "\.+((xyz)|(abc))"
  8.                             ^
  9. /*
  10. raw strings a great for regular expressions so you don't have 
  11. escape \ characters
  12. */
  13. scala> val rawString = """\.+((xyz)|(abc))"""
  14. rawString: java.lang.String = \.+((xyz)|(abc))

The next thing is to realize that one can easily create a Regex object from any string with the r method:
  1. scala> val regex = """\.+((xyz)|(abc))""".r
  2. regex: scala.util.matching.Regex = \.+((xyz)|(abc))

A regex has the standard matching methods one might expect but lets look at findAllIn and the associated MatchData for now. findAllIn returns a MatchIterator which is an Iterator[String] with MatchData. When iterating over the MatchIterator the full matched string will be returned, if you need the subgroups you will need to convert the MatchIterator to an Iterator[Match].
  1. // findAllIn returns an iterator over the matches.  
  2. scala> "l|he".r findAllIn "hello xyz" foreach {println _}
  3. he
  4. l
  5. l
  6. // Each match can have multiple groups
  7. // Note: Each element in MatchIterator are strings (no Match objects)
  8. scala> ("(h)(e)|(l)".r findAllIn "hello xyz").matchData foreach { m => println(m.matched mkString ",")}   
  9. h,e
  10. l
  11. l
  12. // to access subgroups use the matchData method
  13. // Note: there are 3 subgroups in the regex
  14. scala> ("(h)(e)|(l)".r findAllIn "hello xyz").matchData foreach { m => println( m.subgroups mkString ",")}
  15. h,e,null
  16. null,null,l
  17. null,null,l
  18. /*
  19. if matched is called the full match is returned (as if you did not convert the iterator to an Iterator[Match])
  20. /*
  21. scala> ("(h)(e)|(l)".r findAllIn "hello xyz").matchData foreach { m => println(m.matched)}
  22. he
  23. l
  24. l
  25. /*
  26. The following demonstrates more of the methods on Match
  27. Essentially the elements are:
  28. (start index of match, end index of match, string before match, string after match, string the match was performed on)
  29. */
  30. scala> ("(h)(e)|(l)".r findAllIn "hello xyz").matchData foreach { m => println(m.start, m.end, m.before, m.after, m.source)}
  31. (0,2,,llo xyz,hello xyz)
  32. (2,3,he,lo xyz,hello xyz)
  33. (3,4,hel,o xyz,hello xyz)

The last methods to look at for this topic are findFirstIn, findFirstMatchIn and the Regex constructor:
  1. /*
  2. Groups names can be assigned if the Regex constructor is used
  3. */
  4. scala> val withNames = new util.matching.Regex("(h)(e)|(l)", "h", "e", "l")
  5. withNames: scala.util.matching.Regex = (h)(e)|(l)
  6. scala> withNames findFirstIn "hello xyz"
  7. res28: Option[String] = Some(he)
  8. /*
  9. I know a match will be found so I am extracting the value from the Option by assigning it to Some(he)
  10. */
  11. scala> val Some(he) = withNames findFirstMatchIn "hello xyz"  
  12. he: scala.util.matching.Regex.Match = he
  13. scala> he.groupNames
  14. res29: Seq[String] = Array(h, e, l)
  15. scala> he.group("h")
  16. res30: String = h
  17. scala> he.group("e") 
  18. res31: String = e
  19. scala> he.group(1)
  20. res32: String = h
  21. scala> he.group(2)
  22. res33: String = e
  23. // Uh oh. NullPointer warning!
  24. scala> he.group(3)
  25. res34: String = null
  26. scala> he.groupCount
  27. res35: Int = 3

Matching in for-comprehensions

At a glance a for-comprehension appears to be equivalent to a Java for-loop, but it is much much more than that. As shown in post: for-comprehensions, for-comprehensions can have guards which filter out which elements are processed:
  1. scala> for ( x <- 1 to 10; if (x >4) ) println(x)
  2. 5
  3. 6
  4. 7
  5. 8
  6. 9
  7. 10

They can be used to construct new collections:
  1. scala>?for(?i?<-?List(?"a",?"b",?"c")?)?yield?"Word:?"+i
  2. res1:?List[java.lang.String]?=?List(Word:?a,?Word:?b,?Word:?c)

They can contain multiple generators:
  1. scala> for {x <- 1 to 10                           
  2.      |      if(x%2 == 0)
  3.      |      y <- 1 to 5} yield (x,y)
  4. res1: scala.collection.immutable.IndexedSeq[(Int, Int)] = IndexedSeq((2,1), (2,2), (2,3), (2,4), (2,5), (4,1), (4,2), (4,3), (4,4), (4,5), (6,1), (6,2), (6,3), (6,4), (6,5), (8,1), (8,2), (8,3), (8,4), (8,5), (10,1), (10,2), (10,3), (10,4), (10,5))

What has not been covered is that the assignments also does pattern matching:
  1. scala> for ( (x,y) <- (6 to 1 by -2).zipWithIndex) println (x,y) 
  2. (6,0)
  3. (4,1)
  4. (2,2)

This is not surprising as this also occurs during normal assignment. But what is interesting is that the pattern matching can act as a guard as well. See Extractor examples and Assignment and Parameter Objects for more information of pattern matching and extractors.
  1. scala> val args = Array( "h=2", "b=3")
  2. args: Array[java.lang.String] = Array(h=2, b=3)
  3. scala> val Property = """(.+)=(.+)""".r 
  4. Property: scala.util.matching.Regex = (.+)=(.+)
  5. scala> for {Property(key,value) <- args } yield (key,value)
  6. res0: Array[(String, String)] = Array((h,2), (b,3))
  7. scala> Map(res0:_*)
  8. res1: scala.collection.immutable.Map[String,String] = Map(h -> 2, b -> 3)
  9. scala> res1("h")
  10. res3: String = 2

Now just for fun here is a similar example but using symbols instead of strings for the key values:
  1. scala> val args = Array( "h=2", "b=3")
  2. args: Array[java.lang.String] = Array(h=2, b=3)
  3. scala> val Property = """(.+)=(.+)""".r 
  4. Property: scala.util.matching.Regex = (.+)=(.+)
  5. scala> for {Property(key,value) <- args } yield (Symbol(key),value)
  6. res0: Array[(Symbol, String)] = Array(('h,2), ('b,3))
  7. scala> Map(res0:_*)
  8. res1: scala.collection.immutable.Map[Symbol,String] = Map('h -> 2, 'b -> 3)
  9. scala> res1('h)
  10. res2: String = 2

Tuesday, January 5, 2010

Symbols

Scala has what are called symbolic literals. A symbol is very similar to a String except that they are cached. So symbol 'hi will be the same object as 'hi declared a second time. In addition there is special syntax for creating symbols that requires only a single quote.

As odd as this may appear at first glance there are some good use cases for symbols.
  • Save memory
  • Extra semantics. Semantically they are the same object where "hi" is not necessarily the same as "hi" so 'hi has some extra semantics meaning this is the one an only 'hi object.
  • Shorter syntax. This can be useful when designing DSLs
  • Identifier syntax. When using the simpler syntax the symbol will be a valid Scala identifier so it can be good when intending to reference methods or variable, perhaps in a heavily reflection based framework


I hope that makes sense :)

  1. // This is the long way to create a symbol object
  2. scala> Symbol("hi")
  3. res10: Symbol = 'hi
  4. // This is the short way.  The symbol must be a legal Scala symbol (like a method name or value/variable name)
  5. scala> 'hi
  6. res11: Symbol = 'hi
  7. // If you *need* characters in a symbol that are not legal in Scala identifiers the Symbol 
  8. // object has a factory method for that purpose
  9. scala> Symbol("hi there")
  10. res12: Symbol = 'hi there
  11. // Not legal
  12. scala> 'hi there
  13. < console>:5: error: value there is not a member of Symbol
  14.        'hi there
  15.            ^
  16. // quotes are not legal for identifiers
  17. scala> '"hi there"
  18. < console>:1: error: unclosed character literal
  19.        '"hi there"
  20.        ^
  21. < console>:1: error: unclosed string literal
  22.        '"hi there"
  23.                  ^
  24. scala> 'hi\ there 
  25. < console>:5: error: value \ is not a member of Symbol
  26.        'hi\ there
  27.        ^
  28. // You can extract out the string from the symbol if desired quite easily
  29. scala> 'hi match { case Symbol(b) => b}        
  30. res14: String = hi
  31. // A simpler way to get the string
  32. scala> 'hi.toString drop 1
  33. res0: String = hi