Monday, November 30, 2009

Overloaded Unapply

This topic is related to previous posts on matching. I recommend reading some of them as well:
Since an Extactor is just an object with an unapply method it logically follows that an Extractor can have an overloaded unapply method. In other words can have an unapply(String) and an unapply(Int); allowing matching Strings and Ints.
  1. scala> object T{                                                         
  2.      |  def unapply(v:String)= if(v== "s") Some("yay"else None
  3.      |  def unapply(v:Int) = if(v==1) Some("hmmm"else None
  4.      | }
  5. defined module T
  6. scala> 1 match { case T(x) => println(x) }
  7. hmmm
  8. scala> "s" match { case T(x) => println(x) }
  9. yay
  10. scala> object T{                                 
  11.      | def unapplySeq(v:String) = if (v=="x") Some(List(1,2,3)) else None
  12.      | def unapplySeq(v:Int) = if (v==1) Some(List("one","two")) else None
  13.      | }
  14. defined module T
  15. scala>  "x"  match { case T(x,y,z) => println(x,y,z) }
  16. (1,2,3)
  17. scala>  1  match { case T(x,y) => println(x,y) }  
  18. (one,two)

Friday, November 27, 2009

Defining Custom Control Structures

Scala has only a handful of built-in control structures: for, while, try-catch, if, etc... However it is quite simple to define custom control structures. There are several good examples in the Scala 2.8 library. For some examples look at the classes in the scala.util.control package.

For this topic, we will develop a simplified version of the Exception class. First a demonstration of the 2.8 version.
  1. scala> import scala.util.control.Exception._
  2. import scala.util.control.Exception._
  3. scala> val numberFormat = catching(classOf[NumberFormatException])
  4. numberFormat: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException)
  5. scala> val result = numberFormat opt { "10".toInt }               
  6. result: Option[Int] = Some(10)
  7. scala> result match {
  8.      | case Some(n) => // do something
  9.      | case None => // handle this situation
  10.      |


A question that often arises when presented with the Exception control flow is why not use try-catch. There are two main reasons in my opinion.

First, people coming from certain functional style languages find that form more comfortable (so I have heard.) So in this case it is a style issue.

The other reason (and the one more pertinent to Java developers), is that it provides a nice way to handle common exceptions. Why do I say nice? First it declares when exceptions are handled before the code and that provides more context while reading the code. In addition, if you create the Catch object and assign it to a nicely named variable then it is clear what the intent is. For example there may be several reasons to catch a runtime exception and they should be handled differently. A few well-named variables can really assist in readability. A final point is that several of these variables can be defined in on object and shared throughout a project adding some consistency to a project.

Back to the topic at hand.

We will develop a simplified version: a catching method that will return Some(...) if no exception occurs or None if one of the declared exceptions has occurred or throw exception if the exception is not one we declare as handling. Now this is not what I would necessarily call a custom control flow because it does not offer a choice of execution flows. To do that I would add more components like int the Exceptions object. However, this is a good demonstration of the parts required to create a custom control struction. The key is the => in def method(arg: => T) This is a special type construct which means that a no param function is passed in but is not executed until called within the method. A few comparisons:
  1. scala> def method(arg: =>Int) = println(arg)
  2. method: (arg: => Int)Unit
  3. scala> def method2(arg: =>Int) = println("not calling arg")
  4. method2: (arg: => Int)Unit
  5. scala> var x = 1
  6. x: Int = 1
  7. // when method is called x is incremented because method calls the argument
  8. scala> method { x += 1; x }                                
  9. 2
  10. scala> println(x)          
  11. 2
  12. // when method2 is called x is not incremented because 
  13. // the argument is not called/referenced
  14. scala> method2 { x += 1; x }
  15. not calling arg
  16. scala> println(x)           
  17. 2
  18. // arg is referenced 2 times in method three so x is incremented 2 times
  19. scala> def method3(arg: => Int) = println("first call="+arg+" second call="+arg)
  20. method3: (arg: => Int)Unit
  21. scala> method3 { x += 1; x }                                                   
  22. first call=3 second call=4
  23. // Now demonstrate the standard way of defining arguments
  24. // the value passed is calculated before calling the method
  25. // so is at most called once
  26. scala> def byValue(arg: Int) = println(arg)
  27. byValue: (arg: Int)Unit
  28. scala> def byValue2(arg: Int) = println("not calling arg")
  29. byValue2: (arg: Int)Unit
  30. scala> def byValue3(arg: Int) = println("first call="+arg+" second call="+arg)
  31. byValue3: (arg: Int)Unit
  32. scala> byValue{ x += 1; x }
  33. 5
  34. scala> byValue2{ x += 1; x }
  35. not calling arg
  36. scala> println(x)
  37. 6
  38. scala> byValue3{ x += 1; x }
  39. first call=7 second call=7
  40. // And finally show the normal way to pass in a function. 
  41. // This has the benefit of allowing the reader of the code to
  42. // realize that the argument is a function
  43. // but is not a nice syntax for control flow
  44. scala> def stdFunc(arg: ()=>Int) = println(arg())
  45. stdFunc: (arg: () => Int)Unit
  46. scala> def stdFunc2(arg: ()=>Int) = println("not calling arg")
  47. stdFunc2: (arg: () => Int)Unit
  48. scdef stdFunc3(arg: ()=>Int) = println("first call="+arg()+" second call="+arg()) 
  49. stdFunc3: (arg: () => Int)Unit
  50. scala> stdFunc {() => x += 1; x }  
  51. 8
  52. scala> stdFunc2 {() => x += 1; x }
  53. not calling arg
  54. scala> println(x)
  55. 8
  56. scala> stdFunc3 {() => x += 1; x }
  57. first call=9 second call=10


Now for the complete catching example:
  1. scala> def catching[T](exceptions: Class[_]*)(body: => T) = {
  2.      | try {                                                 
  3.      | Some (body)                                           
  4.      | } catch {
  5.      | case e if (exceptions contains e.getClass) => None
  6.      | }                
  7.      | }
  8. catching: [T](exceptions: Class[_]*)(body: => T)Option[T]
  9. scala> val runtime = catching[Number](classOf[NullPointerException], classOf[NumberFormatException])_
  10. runtime: (=> java.lang.Number) => Option[java.lang.Number] = < function1>
  11. scala> runtime { "".toInt }                                                                          
  12. res2: Option[java.lang.Number] = None
  13. scala> runtime { "10".toInt }
  14. res3: Option[java.lang.Number] = Some(10)
  15. scala> runtime { throw new NullPointerException }
  16. res6: Option[java.lang.Number] = None
  17. scala> runtime { throw new RuntimeException }
  18. java.lang.RuntimeException
  19.         at $anonfun$1.apply(< console>:10)
  20.         at $anonfun$1.apply(< console>:10)
  21.         at .catching(< console>:9)
  22.         at $anonfun$1.apply(< console>:8)
  23.         at $anonfun$1.apply(< console>:8)
  24.         at .< init>(< console>:10)
  25.         at .< clinit>(< console>)
  26.         at RequestResult$.< init>(< console>:4)
  27.         at RequestResult$.< clinit>(< console>)
  28.         at RequestResult$result(< console>)
  29.         ...

Wednesday, November 25, 2009

Good Scala Style

This topic is a bit of a departure from the normal but is very important. The goal of these posts has not been(necessarily) to introduce good coding style, instead to introduce the different tools at your disposal. There have been some good styles to follow and some bad ones (hopefully more good than bad.) Today is mainly a link to a project and document that is documenting a style guide for Scala programming. I highly recommend taking a look at it and a big thanks to Daniel Spiewak for spearheading this project, although I think it has now grown beyond just Daniel so thanks to the other contributors as well.

Github project: http://github.com/davetron5000/scala-style
HTML - http://davetron5000.github.com/scala-style
PDF - http://davetron5000.github.com/scala-style/ScalaStyleGuide.pdf

Thanks again for a wonderful resource.

Varargs

Both Java and Scala have varargs. In Scala the syntax for a varargs argument is def method (param:String*). In the off-chance you are not aware of what varargs are; they allow an arbitrary number of values to be passed to the method. Some restrictions on when varargs can be used are:
  • The vararg parameter must be the last parameter in the list
  • There can not be default values for any parameters in the method containing the varargs (Scala 2.8+)

From the caller's point of view; varargs can be called as follows: method("p1""p2""p3") where the number of values is not limited. However, the () must be used.

In Java (if I remember right) only arrays can be passed in place of varargs:
  1. class C {
  2.   public static void main(String... args) {
  3.     System.out.println(args.length)
  4.   }
  5. }
  6. String[] args = new String[]{"arg1""arg2"}
  7. C.main (args)

However Scala is more general and allows any sequence to be passed to varargs, with a caveat. When a sequence is passed to varargs a hint must be provided to indicate that you are intending to have the sequence be expanded to be the varargs.
  1. def method (args:Int*) = println(args)
  2. val list = List(1,2,3)
  3. method (list:_*)  // note the use of _*

Examples:
  1. scala> def method(varargs:Int*)(more:String*) = println(varargs,more)
  2. method: (Int*)(String*)Unit
  3. scala> method(1,2,3,4)("one")
  4. (Array(1, 2, 3, 4),Array(one))
  5. scala> method(1,2,3,4)       
  6. < console>:6: error: missing arguments for method method in object $iw;
  7. follow this method with '_' if you want to treat it as a partially applied function
  8.        method(1,2,3,4)
  9.        ^
  10. scala> method(1,2,3,4)()
  11. (Array(1, 2, 3, 4),Array())
  12. scala> method()("one")  
  13. (Array(),Array(one))
  14. scala> method("one")  
  15. < console>:6: error: type mismatch;
  16.  found   : java.lang.String("one")
  17.  required: Int
  18.        method("one")
  19.               ^
  20. scala> method()()     
  21. (Array(),Array())
  22. scala> val method2 = method(1,2,3)_  
  23. method2: (String*) => Unit = < function>
  24. scala> val paramList = List("hi","ho")
  25. paramList: List[java.lang.String] = List(hi, ho)
  26. scala> method2(paramList)
  27. < console>:8: error: type mismatch;
  28.  found   : List[java.lang.String]
  29.  required: String
  30.        method2(paramList)
  31.                ^
  32. scala> method2(paramList:_*)
  33. (Array(1, 2, 3),List(hi, ho))
  34. scala> val range = (1 to 5) map {_.toString} 
  35. range: RandomAccessSeq.Projection[java.lang.String] = RangeM(1, 2, 3, 4, 5)
  36. scala> method2(range:_*)                     
  37. (Array(1, 2, 3),RangeM(1, 2, 3, 4, 5))

Tuesday, November 24, 2009

Equals, Tuples and Case-classes

This is mostly a quick tip (or opportunity for refactoring).

Most of Scala's built in classes implement a useful equals and hashcode. The very commonly used case-classes and Tuple classes are the examples that spring to mind. So this enables the following options:
  1. // Assume Box is out of your control and you cannot refactor it into a case class
  2. scala> class Box(val name:Stringval minx:Intval miny:Intval maxx:Intval maxy:Int)
  3. defined class Box
  4. scala> val box = new Box("mybox", 0, 0, 10, 10)
  5. box: Box = Box@568bf3ec
  6. // before:
  7. scala> box.minx == 0 && box.miny == 0 && box.maxx == 10 && box.maxy == 10      
  8. res3: Boolean = true
  9. // after
  10. scala> import box._
  11. import box._
  12. scala> (minx,miny,maxx,maxy) == (0,0,10,10)
  13. res5: Boolean = true
  14. // another box definition:
  15. scala> case class Box2 (name:String, ul:(Int,Int), lr:(Int,Int)) 
  16. defined class Box2
  17. // case classes have nice equals for comparison
  18. scala> box2 == Box2("a nicer box", (0,0), (10,10))
  19. res6: Boolean = true
  20. // but what if you don't want to compare names
  21. scala> import box2._
  22. import box2._
  23. scala> (ul,lr) == ((0,0),(10,10))
  24. res7: Boolean = true

Sunday, November 22, 2009

Type aliasing and implicit conversions in harmony

This topic combines advanced two topics. types and implicit methods. This topic is not really intended to be instructional as much as a illustration of the cool stuff you can do with the language. As always becareful not to cut yourself :-)

In keeping with the uniform principle of Scala, types can defined as variables. This is useful for several reasons but this topic covers a cool/fun effect of having types be declared like variables. Type Aliasing. In the example below an alias | is created for the Either class. This allows the | to be used in place of Either.
  1. // Start of example 1.  creating the type alias
  2. // define the | type
  3. scala> type |[A,B] = Either[A,B]
  4. defined type alias $bar
  5. // If a Type has 2 parameters it can be used in operator form
  6. scala> Array[Int | Long](Left(5),Right(12L))
  7. res0: Array[|[Int,Long]] = Array(Left(5), Right(12))
  8. // start of example 2.  Simplify creation of an Array (or other collection) of either
  9. scala> implicit def makeLeft[A,B](a:A):Either[A,B] = Left(a)
  10. makeLeft: [A,B](a: A)Either[A,B]
  11. scala> implicit def makeRight[A,B](b:B):Either[A,B] = Right(b) 
  12. makeRight: [A,B](b: B)Either[A,B]
  13. // Since there are implicits to convert to Right and Left the values in the Array will be wrapped
  14. // automatically.  Makes the syntax MUCH cleaner and easier to read.
  15. scala> Array[Int|String](5,"Wurst",123,2,6)
  16. res1: Array[|[Int,String]] = Array(Left(5), Right(Wurst), Left(123), Left(2), Left(6))

Friday, November 20, 2009

Either

The Scala Either class is similar in function as Option but it represents a choice. For example a method can return Either an Int or an Exception. Usage example:
  1. // If string can be converted to an Int then return Right[Int] otherwise
  2. // return a Left[String] with the error message
  3. // by convention the error state will always be the Left
  4. scala> def toInt(string:String):Either[String,Int] = {
  5.      | try { Right(string.toInt) }
  6.      | catch { case e => Left("Error: "+e.getMessage) }
  7.      | }
  8. toInt: (string: String)Either[String,Int]
  9. scala> toInt("1")
  10. res0: Either[String,Int] = Right(1)
  11. scala> toInt("booger")
  12. res1: Either[String,Int] = Left(Error: For input string: "booger")

By convention if one return value is a error state and the other the expected state then Right will contain the expected state and Left will contain the error state.
  1. scala> def toInt(string:String):Either[String,Int] = {
  2.      | try { Right(string.toInt) }
  3.      | catch { case e => Left("Error: "+e.getMessage) }
  4.      | }
  5. toInt: (string: String)Either[String,Int]
  6. scala> toInt("1")
  7. res0: Either[String,Int] = Right(1)
  8. scala> toInt("booger")
  9. res1: Either[String,Int] = Left(Error: For input string: "booger")
  10. // you can test if the value is a left or right value quite easily
  11. scala> res0.isLeft
  12. res2: Boolean = false
  13. scala> res1.isRight
  14. res3: Boolean = false
  15. scala> res0.isRight
  16. res4: Boolean = true
  17. scala> res1.isLeft 
  18. res5: Boolean = true
  19. // or matching can be used
  20. scala> res0 match {                                   
  21.      | case Left(l) => println("it is a left")        
  22.      | case Right(r) => println("it is a right")      
  23.      | }
  24. it is a right
  25. scala> res1 match {                             
  26.      | case Left(l) => println("it is a left")  
  27.      | case Right(r) => println("it is a right")
  28.      | }
  29. it is a left
  30. // Perhaps cleaner than matching even is being able to pass 
  31. // functions to the fold method:
  32. // define one function for each side of the either
  33. // first the function to handle the left side case
  34. scala> def leftFunc(errMsg:String) = println("there has been an error")             
  35. leftFunc: (errMsg: String)Unit
  36. // next the function the handle the right side case
  37. scala> def rightFunc(i:Int) = println(i+" was calculated")              
  38. rightFunc: (i: Int)Unit
  39. // then you can pass the two functions to the fold method
  40. // and the correct one will be invoked
  41. scala> res0 fold (leftFunc _, rightFunc _)
  42. 1 was calculated
  43. scala> res1 fold (leftFunc _, rightFunc _)
  44. there has been an error

Thursday, November 19, 2009

Options

Scala is forced to have a "null" value because it interoperates with Java. However unlike Java APIs the recommended way to hand cases where there may or may not be a value (IE a return value) is to return an Option object. Compare the Scala and Java idioms for handling a possible null (or None) return value:

Note: The Option class have been updated in Scala 2.8 so I am going to use some of the scala 2.8 methods. Most of the examples will work with Scala 2.7 but not all; the principal is the same for 2.7 and 2.8.

Java:
  1. /**
  2.  * Returns the annotation with the given name or null if there is no annotation
  3.  * on the objects class with the given name.
  4.  */
  5. public static < A extends java.lang.annotation.Annotation> Annotation annotation(Object obj, Class< A> annotationCls) {
  6.   return obj.getClass().getAnnotation(annotationCls)
  7. }

Scala:
  1. import java.lang.annotation.Annotation
  2. /**
  3.  * Returns the annotation with the given name.
  4.  */
  5. def annotation[A <: Annotation](obj:Object, annotationCls:Class[A]) : Option[Annotation] = {
  6.    Option (obj.getClass.getAnnotation (annotationCls))
  7. }

In the Scala version it is obvious the use of the API (and the compiler) that there are two types of legal return types. Some or None and the compiler will force you to deal with this fact. Where in Java it is very easy to forget to check for null.

Also not that it is very easy to Wrap a null in an Option using the Option objects apply method. If the parameter is a null then None is return otherwise Some is returned.

The other important aspect is how to deal with the Option object and obtain the data from the object if it is present. This is both simple and non-simple. There are a large number of possible useage patterns that can be applied to it.

Examples:
  1. scala> import java.lang.annotation.Annotation
  2. import java.lang.annotation.Annotation
  3. kscala> def annotation[A <: Annotation](obj:Object, annotationCls:Class[A]) : Option[Annotation] = { 
  4.      |    Option (obj.getClass.getAnnotation (annotationCls))                                      
  5.      | }
  6. annotation: [A <: java.lang.annotation.Annotation](obj: java.lang.Object,annotationCls: Class[A])Option[java.lang.annotation.Annotation]
  7. // strings do not have the Documented annotation so None is returned
  8. scala> annotation("x", classOf[java.lang.annotation.Documented])                                   
  9. res0: Option[java.lang.annotation.Annotation] = None
  10. // None is not defined
  11. scala> res0.isDefined
  12. res1: Boolean = false
  13. // None IS empty 
  14. scala> res0.isEmpty
  15. res26: Boolean = true
  16. // We need a some example so LineNumberInputStream has Deprecated annotation
  17. // we will use that in order to 
  18. scala> val in = new LineNumberInputStream(new ByteArrayInputStream("hello".getBytes))
  19. in: java.io.LineNumberInputStream = java.io.LineNumberInputStream@8ca9a2d
  20. scala> annotation(in, classOf[Deprecated])                                           
  21. res2: Option[java.lang.annotation.Annotation] = Some(@java.lang.Deprecated())
  22. // Some(...) is always defined even if it contains null
  23. scala> res2.isDefined
  24. res3: Boolean = true
  25. scala> val nullSome = Some(null)
  26. nullSome: Some[Null] = Some(null)
  27. scala> nullSome.isDefined
  28. res28: Boolean = true
  29. // Some is never empty
  30. scala> res2.isEmpty
  31. res4: Boolean = false
  32. // You can also test particular values as follows
  33. scala> if(res0 == None) println("its ok to use")
  34. its ok to use
  35. scala> if (res2.map {a => "found"} == Some("found")) println ("it is deprecated dont use!")
  36. it is deprecated dont use!
  37. scala> res0 match {                                                       
  38.      | case None => println("its ok to use")                              
  39.      | case Some(x:Deprecated) => println ("it is deprecated dont use!"
  40.      | }
  41. its ok to use
  42. scala> res2 match {                                                      
  43.      | case None => println("its ok to use")                             
  44.      | case Some(x:Deprecated) => println ("it is deprecated dont use!")
  45.      | }
  46. it is deprecated dont use!
  47. scala> if(Some("hi") == Some("hi")) println("a match")    
  48. match
  49. scala> if(Some("hi") == Some("ho")) println("a match")
  50. // After you have tested you can use get to obtain the value
  51. // but becareful, you will get an exception if you forget to test.
  52. scala> res0.get
  53. java.util.NoSuchElementException: None.get
  54.                           at scala.None$.get(Option.scala:169)
  55.                           at scala.None$.get(Option.scala:167)
  56.                           at .< init>(< console>:12)
  57.                           at .< clinit>(< console>)
  58.                           [snip]
  59. scala> res2.get
  60. res10: java.lang.annotation.Annotation = @java.lang.Deprecated()
  61. // a potentially better way of optaining the value is to provide a default if 
  62. // the value does not exists
  63. scala> res2.getOrElse(classOf[java.lang.annotation.Documented])
  64. res13: java.lang.Object = @java.lang.Deprecated()
  65. scala> res0.getOrElse(classOf[java.lang.annotation.Documented])
  66. res14: java.lang.Object = interface java.lang.annotation.Documented
  67. // A Option is a "monad" (dont worry too much about the term if 
  68. // you dont know it) a very (VERY) simplified meaning of that is that 
  69. // option behaves a bit like a collection of size 1 or 0
  70. // you can use similar methods on an Option as a collection.  
  71. // So exists tests each element in the Option to see if it matches 
  72. // the function passed in as the parameter
  73. // res2 has an object that is an instanceOf Annotation 
  74. scala> res2.exists {_.isInstanceOf[Annotation]}  
  75. res7: Boolean = true
  76. // None always returns false to exists
  77. scala> res0.exists {_.isInstanceOf[Annotation]}
  78. res8: Boolean = false
  79. scala> res2.exists {_.toString == "hi"}
  80. res29: Boolean = false
  81. // Similarly you can use the filter method that is present in all collections
  82. scala> res2.filter {_.toString == "hi"}    
  83. res30: Option[java.lang.annotation.Annotation] = None
  84. scala> res2.filter {_.isInstanceOf[Annotation]}
  85. res32: Option[java.lang.annotation.Annotation] = Some(@java.lang.Deprecated())
  86. // apart from just filtering you can convert the type contained 
  87. // in the Option by using map to map from one type of Option to
  88. // another type of Option in this examples we map from 
  89. // Option[Annotation] to Option[String]
  90. scala> res0.map {_.toString}.getOrElse("does not exist")                        
  91. res15: java.lang.String = does not exist
  92. scala> res2.map {_.toString}.getOrElse("does not exist")
  93. res16: java.lang.String = @java.lang.Deprecated()
  94. // Another very handy and safe way to access the value is to use foreach
  95. // this will call the function with the parameter from the Option if
  96. // the Option is Some but a noop will occur if the Option is None.
  97. scala> res2.foreach { println _ }
  98. @java.lang.Deprecated()
  99. scala> res0.foreach { println _ }
  100. // orElse is simply a method to ensure that the Option is a Some
  101. scala> res0.orElse(Some(classOf[java.lang.annotation.Documented]))
  102. res22: Option[java.lang.Object] = Some(interface java.lang.annotation.Documented)
  103. scala> res2.orElse(Some(classOf[java.lang.annotation.Documented]))
  104. res23: Option[java.lang.Object] = Some(@java.lang.Deprecated())

Wednesday, November 18, 2009

Manifests

Added in Scala 2.7 as an experimental feature is the manifest class it is a handy class allowing for very limited type reification. Take the following example:
def inspect[T](l:List[T])
If you want to know they type of T in Java you are out of luck because that type information is gone. However, Scala offers help through manifests.
  1. def inspect[T](l:List[T])(implicit manifest : scala.reflect.Manifest[T]) = println(manifest.toString)

This code snippet will print out the string representation of type T.

More Examples:
  1. scala> def inspect[T](l:List[T])(implicit manifest : scala.reflect.Manifest[T]) = println(manifest.toString)
  2. inspect: [T](List[T])(implicit scala.reflect.Manifest[T])Unit
  3. scala> inspect(List(1,2,3,4))
  4. int
  5. scala> inspect(List(List(1,2),List(3,4)))
  6. scala.List[int]
  7. scala> inspect(List(List(List(1),List(2)),List(List(3),List(4))))
  8. scala.List[scala.List[int]]
  9. scala> val l:List[Iterable[Int]] = List(List(1,2))  
  10. l: List[Iterable[Int]] = List(List(1, 2))
  11. scala> inspect(l)                                                                                           
  12. scala.collection.Iterable[Int]
  13. scala> class MV[T](val v:T)(implicit m:scala.reflect.Manifest[T]) { println(m.toString) }
  14. defined class MV
  15. scala> new MV(1)
  16. Int
  17. res1: MV[Int] = MV@180e6899
  18. scala> class MV2[T](val v:T)(implicit m:scala.reflect.Manifest[T]) {                     
  19.      | def isA[A](implicit testManifest:scala.reflect.Manifest[A]) = m.toString == testManifest.toString
  20.      | }
  21. defined class MV2
  22. scala> val x = new MV2(19)
  23. x: MV2[Int] = MV2@41ff8506
  24. scala> x.isA[String]
  25. res2: Boolean = false
  26. scala> x.isA[Int]   
  27. res3: Boolean = true
  28. scala> def isA[A](o:Object)(implicit m:Manifest[A]) = {
  29.      | val `class` = Class.forName(m.toString)         
  30.      | `class`.isAssignableFrom(o.getClass)            
  31.      | }
  32. isA: [A](o: java.lang.Object)(implicit m: scala.reflect.Manifest[A])Boolean
  33. scala> isA[java.lang.Integer](java.lang.Integer.valueOf(19))
  34. res6: Boolean = true

Tuesday, November 17, 2009

XML matching

The Scala XML support includes the ability to match on XML elements. Here are several examples. One of the most important parts to remember is to not miss the '{' and '}'.

  1. scala> <document>
  2.      |  <child1/>
  3.      |  <child2/>
  4.      | </document>
  5. res0: scala.xml.Elem =
  6. <document>
  7.         <child1></child1>
  8.         <child2></child2>
  9.        </document>
  10. scala> res0 match {
  11.        // match the document tag
  12.        // the {_*} is critical
  13.      | case <document>{_*}</document> => println("found document element")
  14.      | case _ => println("Found another element")
  15.      | }
  16. found document element
  17. scala> res0 match {
  18.        // assign the document element to e
  19.      | case e @ <document>{_*}</document> => println(e)
  20.      | case _ => println("Found another element")
  21.      | }
  22. <document>
  23.         <child1></child1>
  24.         <child2></child2>
  25.        </document>
  26. scala> res0 match {
  27.        // assign the children of document to children
  28.        // notice that there are Text elements that are part of children
  29.      | case <document>{children @ _*}</document> => println(children)
  30.      | case _ => println("Found another element")
  31.      | }
  32. ArrayBuffer(
  33.         , <child1></child1>,
  34.         , <child2></child2>,
  35.        )
  36. // the '\' is xpath like but only returns elements and attributes
  37. // in this case the \ "_" returns all element children of res0.  It
  38. // will not return the Text elements.
  39. scala> res0 \ "_" foreach {
  40.      | case <child1>{_*}</child1> => println("child1 found")
  41.      | case <child2>{_*}</child2> => println("child2 found")
  42.      | case e => println("found another element")
  43.      | }
  44. child1 found
  45. child2 found
  46. // another example of how \ does not return any text elements.  This returns
  47. // no elements
  48. scala> <doc>Hello</doc> \ "_" foreach { case scala.xml.Text(t) => println("a text element found: "+t) }
  49. // the .child returns all children of an Elem
  50. scala> <doc>Hello</doc>.child foreach { case scala.xml.Text(t) => println("a text element found: "+t) }
  51. a text element found: Hello
  52. // This example throws a match error because there are whitespace text elements
  53. // that cause the match to fail.
  54. scala> res0 match {                                                                                    
  55.      | case <document><child1/><child2/></document> => println("found the fragment")
  56.      | }
  57. scala.MatchError: <document>
  58.         <child1></child1>
  59.         <child2></child2>
  60.        </document>
  61.        at .< init>(< console>:6)
  62.        at .< clinit>(< console>)
  63.        at RequestResult$.< init>(< console>:3)
  64.        at RequestResult$.< clinit>(< console>)
  65.        at RequestResult$result(< console>)
  66.        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  67.        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMetho...
  68. // The trim method removes the whitespace nodes so now the 
  69. // match will work
  70. scala> scala.xml.Utility.trim(res0) match {                                                            
  71.      | case <document><child1/><child2/></document> => println("found the fragment")
  72.      | }
  73. found the fragment
  74. // you can select part of the tree using matching
  75. // child2 is assigned to 3 in this example.
  76. scala> scala.xml.Utility.trim(res0) match {                                           
  77.      | case <document><child1/>{e @ _*}</document> => println("found the fragment:"+e)
  78.      | }
  79. found the fragment:RandomAccessSeq(<child2></child2>)

Monday, November 16, 2009

ScalaTest BDD testing DSL

This is the first of three topics exploring some of the testing tools that you can use with Scala. They all integrate with JUnit and can be used with maven and ant.

The first example is ScalaTest. ScalaTest provides many different usage patterns but the one I will show today is a Behaviour Driven Design test. It provides a DSL for declaring a test that is nearly english in syntax and if done correctly can be given to a non technical person to review. The ScalaTest BDD test style was inspired by the work done on Specs by Eric Torreborre. I will demonstrate that library in the next topic.

I want to reiterate that ScalaTest permits several different styles of test writing. NUnit, JUnit and BDD are the main styles. So anyone that is used to NUnit or JUnit should have no problem using ScalaTest but if you like the look of the BDD test specifications then you can migrate and slowly become accustomed to that style.

If you want to integrate with JUnit one easy way to add the @RunWith annotation for the class. See JUnitRunner for details:
  1. import org.scalatest.junit.JUnitRunner
  2. import org.junit.runner.RunWith
  3. @RunWith(classOf[JUnitRunner])
  4. class StackSpec extends WordSpec {
  5. ...
  6. }

Instructions to run example:
  1. Download ScalaTest: http://www.scalatest.org/download
  2. Extract archive. For example to /tmp/
  3. Run scala with the ScalaTest jar on classpath: scala -classpath /tmp/scalatest-1.0/scalatest-1.0.jar
  4. copy in code

This example is directly taken from the ScalaTest documentation. It tests a Stack implementation.
  1. scala>  import org.scalatest.WordSpec
  2. import org.scalatest.WordSpec
  3. scala>  import scala.collection.mutable.Stack
  4. import scala.collection.mutable.Stack
  5. scala> 
  6. scala>  class StackSpec extends WordSpec {
  7.      | 
  8.      |    "A Stack" should {
  9.      | 
  10.      |      "pop values in last-in-first-out order" in {
  11.      |        val stack = new Stack[Int]
  12.      |        stack.push(1)
  13.      |        stack.push(2)
  14.      |        assert(stack.pop() === 2)
  15.      |        assert(stack.pop() === 1)
  16.      |      }
  17.      | 
  18.      |      "throw NoSuchElementException if an empty stack is popped" in {
  19.      |        val emptyStack = new Stack[String]
  20.      |        intercept[NoSuchElementException] {
  21.      |          emptyStack.pop()
  22.      |        }
  23.      |      }
  24.      |    }
  25.      |  }
  26. defined class StackSpec
  27. scala> new StackSpec().execute()
  28. A Stack 
  29. - should pop values in last-in-first-out order
  30. - should throw NoSuchElementException if an empty stack is popped

Thursday, November 12, 2009

Import Instance Properties

A truly fantastic aspect of Scala is the uniform principle that Scala attempts to adhere to. In other words Scala tries to not make any rules that only apply to a single case when it can be applied generally.

One example is matching you can see several uses of matching in the following topics:
But matching it applies to today's topic as well. This topic covers a cool trick that helps assist with parameter objects and complex return types.

This topic is another take on Assignment and Parameter Objects. There are cases when a method has a large number of parameters and the API can be cleaned up by introducing a parameter object. Or perhaps an object with several public proprties are passed to a method.
  1. scala> case class Params(p1:Int, p2:Int, p3:Int)
  2. defined class Params
  3. scala>  def method(params:Params) = {
  4.      |   println(params.p1, params.p2, params.p3)
  5.      | }
  6. method: (Params)Unit
  7. scala> method(Params(1,2,3))
  8. (1,2,3)
  9. }

The symbol 'params' introduces noise into the code. The noise can be reduced further by assigned the properties of the parameter object to local variables:
  1. scala>  case class Params(p1:Int, p2:Int, p3:Int)
  2. defined class Params
  3. scala> 
  4. scala>  def method(params:Params) = {
  5.      |   val Params(p1,p2,p3) = params
  6.      |   println(p1,p2,p3)
  7.      | }
  8. method: (Params)Unit
  9. scala> method(Params(1,2,3))
  10. (1,2,3)
  11. }

But we can do better remember that we can import methods and properties from an object:
  1. scala> object Obj {
  2.      |  val prop = 10
  3.      | }
  4. defined module Obj
  5. scala> import Obj._
  6. import Obj._
  7. scala> println(prop)
  8. 10

Since all instance are objects it is possible to import fields and methods from instances as well:
  1. scala>  case class Params(p1:Int, p2:Int, p3:Int)
  2. defined class Params
  3. scala> 
  4. scala>  def method(params:Params) = {
  5.      |   import params._
  6.      |   println(p1, p2, p3)
  7.      | }
  8. method: (Params)Unit
  9. }

The same technique is extremely useful when a method needs to return multiple values:
  1. scala>  def method() = {
  2.      |   (1,2,3)
  3.      | }
  4. method: ()(IntIntInt)
  5. scala> val retVal = method()
  6. retVal: (IntIntInt) = (1,2,3)
  7. /*
  8.  retVal is a tuple so we can import the tuple
  9.  properties.  Becareful to not do this multiple times in
  10.  the same scope
  11. */
  12. scala> import retVal._
  13. import retVal._
  14. scala> println(_1,_2,_3)
  15. (1,2,3)
  16. scala> def method2={
  17.        // Notice case class declaration can be contained in method
  18.      | case class Return(v1:Int,v2:Int)
  19.      | Return(6,7)
  20.      | }
  21. method2: java.lang.Object with ScalaObject with Product{def v1: Intdef v2: Int}
  22. scala> val r = method2
  23. r: java.lang.Object with ScalaObject with Product{def v1: Intdef v2: Int} = Return(6,7)
  24. scala> import r._
  25. import r._
  26. scala> println(v1,v2)
  27. (6,7)
  28. }