00.scala2014. 3. 28. 13:03
반응형

While this may not be the recommended approach, here's how I currently handle class casting in Scala.

In Java you can cast a class like this:

Recognizer recognizer = (Recognizer)cm.lookup("recognizer").asInstanceOf;

As you can see, this is done with the "(Recognizer)" class cast operator.

In Scala you can't use the same syntax, but you can come close, like this:

val recognizer = cm.lookup("recognizer").asInstanceOf[Recognizer]

As you can see, I've used the Scala asInstanceOf function to cast the object I'm retrieving to a Recognizer, just like I did in the Java code.

A better way?

I should warn you that I don't think this is the Scala-preferred way of class casting. I think the approved/preferred way uses pattern matching, but since I don't understand the advantages of that approach yet, and it's also more complicated, I use this asInstanceOf casting approach.

More context

If it helps to see where this example comes from, I'm using Scala with the Java Spring Framework in one of my applications, and as you can see with a little more source code here, I'm retrieving a Recognizer and Microphone from my Spring application context file:

val cm = new ConfigurationManager("sarah.config.xml")
val recognizer = cm.lookup("recognizer").asInstanceOf[Recognizer]
val microphone = cm.lookup("microphone").asInstanceOf[Microphone]

If you're familiar with Spring, you know that both of those objects need to be cast to the correct object types when they are retrieved from the application context file.

Again, this is how I do class casting in Scala, but there is another (preferred) way to do this ... I might write about that some time ... but this is my preferred approach.

Posted by 1010
00.scala2014. 3. 28. 13:02
반응형

If you've started using Scala, you've seen that there are some cool things in the Scala syntax compared to Java. For instance, in Java you'd execute a method on an object like this:

object.method();

But in Scala you definitely don't need the semi-colon:

object.method()

and then you can omit the parentheses:

object.method

I think you'll agree that this Scala syntax contains much less "noise" than the Java syntax.

Scala single parameter methods: dots or spaces

Beyond that, if a Scala method takes a single parameter, like this:

object.method(param)

you can change the Scala syntax to use a space instead of a dot, while also dropping the parentheses:

object method param

This doesn't look like much in that general example, but it makes for very readable code in a real world example:

pizza add pepperoni

// same as this
pizza.add(pepperoni)

or this:

order add pizza

// same as this
order.add(pizza)

Which form you use -- the traditional dot syntax or the new Scala space syntax -- is up to you. I wasn't completely sold on the space syntax until I ran into this Scala source code in the Talking Puffin project:

def main(args: Array[String]) {
  MacInit init Main.title
  UIManager setLookAndFeel UIManager.getSystemLookAndFeelClassName
  JFrame setDefaultLookAndFeelDecorated true
  launchAllSessions
}

I like this syntax quite a bit, because it gets ride of the "noise" of the dot and parentheses, and reads more like a sentence.

Scala dot and space syntax for single parameter methods

Again, in the end, whether you choose to use the Scala dot or space syntax is up to you (and your developer team), but the general rule bears repeating:

Scala methods that take a single parameter can be invoked without dots or parentheses.

Just remember that rule, experiment a little bit, and see which one you like better.

Posted by 1010
00.scala2014. 3. 28. 13:02
반응형

A nice feature of Scala is that in addition to letting you call and define functions just like you do in Java, you can also use both named arguments and default arguments. In this brief tutorial we'll look at both of these language features.

With Scala's named arguments (parameters), you can specify the names of function or method arguments when calling the method. Here's an example:

object NamedArguments {

  def main(args: Array[String]) {
    printName(firstName="Alvin", lastName="Alexander")
  }
  
  def printName(firstName:String, lastName:String) {
    System.out.format("Your name is %s %s\n", firstName, lastName)
  }
  
}

As you can see from this example, I create the printName function in the usual fashion, and then I can call it like this:

printName(firstName="Alvin", lastName="Alexander")

or with this formatting if you prefer:

printName(firstName="Alvin", 
          lastName="Alexander")

Here I use the function parameter names when calling the function. If you've used languages like Objective-C, you've seen this syntax before. Although it's more verbose, it can also make your code easier to read.

However, if you don't like the named parameter approach, a very nice thing about Scala is that this syntax is completely optional, and you can still call your function without named parameters:

printName("Alvin", "Alexander")

Default function argument values

When writing a Scala function, you can also declare default values for your function arguments. To do this, all you have to do is supply the argument's default value after declaring the argument, like this:

def printName(firstName:String = "Unknown", lastName:String = "Unknown") {
  System.out.format("Your name is %s %s\n", firstName, lastName)
}

After you've declared your function or method like that, you can then call your function in a variety of ways, as shown here:

printName("Alvin", "Alexander")
printName("Alvin")
printName()

These three calls result in the following output:

Your name is Alvin Alexander
Your name is Alvin Unknown
Your name is Unknown Unknown

(Admittedly this isn't a great example, but it's all I could think of at the moment.)

Putting those examples together, here's a small but complete Scala example that demonstrates both named function parameters and default function parameters:

object DefaultFunctionArguments {

  def main(args: Array[String]) {
    // a basic method call
    printName("Alvin", "Alexander")

    // using named function parameters
    printName(firstName="Alvin", lastName="Alexander")
    printName(lastName="Alexander", firstName="Alvin")  // you can change the order

    // relying on default function arguments
    printName("Alvin")
    printName()
  }
  
  def printName(firstName:String = "Unknown", lastName:String = "Unknown") {
    System.out.format("Your name is %s %s\n", firstName, lastName)
  }
  
}

Scala named arguments and default argument values

I hope this brief tutorial on Scala named parameters and default parameter values has been helpful. As mentioned, you don't have to use any of this syntax, but if you come from a variety of other programming languages, like Objective C, these Scala language features can make you feel more at home.

Posted by 1010
00.scala2014. 3. 28. 13:01
반응형

Scala constructors FAQ: How do I create a Scala class with multiple constructors (secondary constructors)?

The Scala approach to defining multiple class constructors is a little different than Java, but somewhat similar. Rather than try to explain this in words, I just created some example source code to demonstrate how this works.

Here's some source code to demonstrate the Scala "multiple constructors" approach:

package tests

object MultipleConstructors {
  
  def main(args: Array[String]) {

    // (1) use the primary constructor
    val al = new Person("Alvin", "Alexander", 20)
    println(al)

    // (2) use a secondary constructor
    val fred = new Person("Fred", "Flinstone")
    println(fred)

    // (3) use a secondary constructor
    val barney = new Person("Barney")
    println(barney)

  }

}

/**
 * The main/primary constructor is defined when you define your class.
 */
class Person(val firstName: String, val lastName: String, val age: Int) {
  
  /**
   * A secondary constructor.
   */
  def this(firstName: String) {
    this(firstName, "", 0);
    println("\nNo last name or age given.")
  }
  
  /**
   * Another secondary constructor.
   */
  def this(firstName: String, lastName: String) {
    this(firstName, lastName, 0);
    println("\nNo age given.")
  }
  
  override def toString: String = {
    return "%s %s, age %d".format(firstName, lastName, age)
  }

}

If you run this example program as is, you'll get the following output:

Alvin Alexander, age 20

No age given.
Fred Flinstone, age 0

No last name or age given.
Barney , age 0

I'm not going to write any more about the Scala constructors approach today, but if you have any questions, comments, or corrections about this example, just leave a note in the Comments section below.

Posted by 1010
00.scala2014. 3. 28. 13:00
반응형

Summary: Scala import syntax examples.

I was just trying to develop a little Java/Swing application in Scala, and right away I ran into the problem of how to import Java classes and packages into a Scala application. 

In short, the following code shows how to import a Java class into a Scala application:

package imports

import javax.swing.JFrame

object jframe {
  def main(args: Array[String]) {
    val f = new JFrame
    f.setVisible(true)
  }
}

As you can see, once you import the JFrame class you can access it directly from your Scala code.

(There are other, preferred ways of writing Scala Swing applications, and I'm just using this JFrame example to make it easier for Java programmers who are new to Scala.)

Importing multiple classes

If you want to import multiple classes from a Java package, you can use the usual Java import syntax:

import javax.swing.JFrame
import javax.swing.JDialog

or you can use this Scala import syntax, if you prefer:

import javax.swing.{JFrame, JDialog}

(You'll like this syntax more when you see the "alias" example below.)

Import all classes from a package

If you want to import all classes from a Java package, use this syntax instead:

import javax.swing._

Importing classes using aliases

Another thing I just remembered that you can do when importing Java classes is that you can reference them by a different name, creating an alias for them as you import them:

import java.io.{ FileInputStream, InputStream, File => JFile }

As you can see from this example, which I just copied from the Scala Source object source code, the java.io.File class is imported, and the "File => JFile" lets us refer to the File class as JFile instead.

As you can see, there are several different ways to import Java classes and packages, depending on your needs.

Posted by 1010
00.scala2014. 3. 28. 12:59
반응형

Scala JavaBean FAQ: How do I create the Scala equivalent of a JavaBean in Java (a Scala JavaBean)?

There are times when you're working with Scala where backwards compatibility with Java and JavaBeans is required. I ran into this recently with the Java Snakeyaml library (see my Scala YAML parsing with Snakeyaml tutorial).

By default Scala doesn't generate JavaBeans for your Scala classes, which is to say that the 'get' and 'set' methods aren't created automatically for you, and Scala doesn't follow the JavaBean specification.

That being said, you can create Scala classes that do follow the JavaBean specification, using the ScalaBeanProperty annotation, as shown in the following examples. First, here's a small Scala class, where I use the BeanProperty annotation on the class properties/fields in the class constructor:

class Person(@BeanProperty var firstName: String, 
             @BeanProperty var lastName: String, 
             @BeanProperty var age: Int) {
  override def toString: String = return format("%s, %s, %d", firstName, lastName, age)
}

This is pretty cool; just by adding the @BeanProperty tag to your class fields, the get and set (getter and setter) JavaBean methods will be generated for you automatically.

Scala JavaBean example #2

Next up, here's a larger Scala class, where I use the @BeanProperty annotation on the class fields, but this time not in the class constructor:

class EmailAccount {
  @BeanProperty var accountName: String = null
  @BeanProperty var username: String = null
  @BeanProperty var password: String = null
  @BeanProperty var mailbox: String = null
  @BeanProperty var imapServerUrl: String = null
  @BeanProperty var minutesBetweenChecks: Int = 0
  @BeanProperty var protocol: String = null
  @BeanProperty var usersOfInterest = new java.util.ArrayList[String]()
}

Despite the slightly different way of creating these classes, once again, the getters and setters are created for me.

I'll leave you with these examples, but if you want to know more about why I needed to use this "Scala JavaBean" approach, and how I used them in my application, I'll again refer you to my Scala YAML parsing tutorial.

Posted by 1010
00.scala2014. 3. 28. 12:58
반응형

In my Java days I used the Spring Framework(Spring) all the time for different things, primarily involving dependency injection (DI) and pretty much anything related to a database. I became curious how Spring would work with Scala, so I created a small Scala/Spring dependency injection example project, which I'm sharing here.

The short answer is that Scala worked just fine with Spring, but it also showed me that I still have plenty to learn about inheritance in Scala.

My Spring applicationContext.xml file

I copied a Spring applicationContext.xml file from another project, then whittled it down to these bare essentials:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean id="dog" class="scalaspring.Dog">
    <constructor-arg value="Fido" />
  </bean>

  <bean id="cat" class="scalaspring.Cat">
    <constructor-arg value="Felix" />
  </bean>

</beans>

You can't tell it from there, but both the Dog and Cat classes extend an Animal class that I created. (More on that in a few moments.)

My Scala object with a main method

Next, I created a simple Scala object with a main method to test everything:

package scalaspring

import org.springframework.context.support.ClassPathXmlApplicationContext

object ScalaSpringExample
{
  def main(args: Array[String]) {
    
    // open/read the application context file
    val ctx = new ClassPathXmlApplicationContext("applicationContext.xml")

    // instantiate our dog and cat objects from the application context
    val dog = ctx.getBean("dog").asInstanceOf[Animal]
    val cat = ctx.getBean("cat").asInstanceOf[Animal]

    // let them speak
    dog.speak
    cat.speak

  }
}

As you can see from the code, I loaded the applicationContext.xml file, created my dog and catinstances by getting their bean definitions from the application context, then executed their speak methods.

One note here: Using the Scala asInstanceOf method is not considered "good practice", but I think it's very concise, particularly for a simple example like this.

My Spring-injected Scala classes

I defined my Dog and Cat classes, as well as a parent abstract class named Animal, in a file namedAnimals.scala:

package scalaspring

abstract class Animal(name: String) {
  def speak:Unit
}

class Dog(name: String) extends Animal(name) {  
  override def speak {
    println(name + " says Woof")
  }
}

class Cat(name: String) extends Animal(name) {
  override def speak {
    println(name + " says Meow")
  }
}

As you can see, all three classes have a speak method, which is implemented differently in the Dog andCat classes. I've also defined the classes using a one-argument constructor, and if you look back at the application context file, you'll see that I pass in the names "Fido" and "Felix" in my Spring bean definitions.

Note that I didn't have to make things this complicated, but I wanted to make sure that the Spring Framework was really working with Scala as expected.

My log4j.properties file

Spring wouldn't run without a logger configuration, so I copied this Log4j properties file from another project, then whittled it down to these lines:

log4j.rootLogger=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p | %d{HH:mm:ss} | %m | %F | %L%n

log4j.logger.org.springframework=INFO
log4j.logger.org.springframework.context.support.ClassPathXmlApplicationContext=INFO

I don't need all those lines, but I haven't used Log4j in a while, and didn't feel like fooling around with it, so I left it as is.

Jar files needed

I needed these jar files to get everything to run:

commons-logging-1.1.1.jar
log4j-1.2.14.jar
spring-2.5.5.jar

My project directory structure

I used the Scala sbt tool to compile and run my project, and therefore I created my directory structure like this:

./build.sbt
./lib
./lib/commons-logging-1.1.1.jar
./lib/log4j-1.2.14.jar
./lib/spring-2.5.5.jar
./project
./src
./src/main
./src/main/config
./src/main/java
./src/main/resources
./src/main/resources/applicationContext.xml
./src/main/resources/log4j.properties
./src/main/scala
./src/main/scala/scalaspring
./src/main/scala/scalaspring/Animals.scala
./src/main/scala/scalaspring/ScalaSpringTest.scala
./src/test
./src/test/java
./src/test/resources
./src/test/scala
./target

Running my Scala / Spring Framework example

Finally, when I ran my Scala / Spring Framework dependency injection example, I got this very exciting output:

Fido says Woof
Felix says Meow

I actually got more output than that from both sbt and Log4j, but that was the important part.

As you can see, Scala and the Spring Framework seem to play well together. These lines of code from my Scala main method:

val ctx = new ClassPathXmlApplicationContext("applicationContext.xml")
val dog = ctx.getBean("dog").asInstanceOf[Animal]
val cat = ctx.getBean("cat").asInstanceOf[Animal]

are very similar to the lines of code I used in a similar Java Spring Framework dependency injection example, and the Spring applicationContext.xml file and the Log4j configuration file were identical to what they'd look like in a regular Java application.

My Scala inheritance problems

One thing I learned in tackling this project is that I need to learn more about Scala inheritance, in particular, overriding constructor methods that accept fields/parameters. If you look back at my applicationContext.xml file, you'll see that I passed the names "Fido" and "Felix" in using the Spring bean "constructor-arg" parameter. I choose this route because I got tired of trying to get my class "setter" methods to work.

What I mean by that is that I wanted to define my Spring beans like this:

<bean id="dog" class="scalaspring.Dog">
  <property name="name" value="Fido"/>
</bean>

but because I haven't worked with Scala inheritance much yet, I didn't know the proper way to define the "name" field in my Animal, Dog, and Cat classes for this "setter" syntax to work. I'll update this article after I take the time to learn that.

Posted by 1010
00.scala2014. 3. 28. 12:57
반응형

Update: This article was written for Scala 2.9. Things changed a little bit in Scala 2.10, so see this new article, Creating implicit methods in Scala 2.10, for correct examples for 2.10 and newer versions of Scala.

A cool thing about implicit conversions in Scala is that they let you add new methods to existing classes, including existing Java and Scala classes such as String, File, and so on.

For instance, let's say you want to add a method to the Java String class, and this new method will increment each character in the String by one byte. The first thing you do is define a Scala class that has a method that implements the behavior you want:

class BetterString(val s: String) {
  def increment = s.map(c => (c + 1).toChar)
}

In that class I created a new method named increment, which uses the String the class is created with, and returns a new String, where each character in the String has been increased by one byte ('A' becomes 'B', 'B' becomes "C', and so on).

Next, I define an implicit conversion that ties my new class to the existing Java String class:

implicit def stringToString(s: String) = new BetterString(s)

Notice that the stringToString method is a very normal looking Scala function, but because it's preceded by the implicit keyword, some very cool "magic" happens. Here's how this works:

  • Because my implicit method stringToString accepts a String as input, Scala is smart enough to know that every time I have a String value, such as a String literal, it should look in my BetterString class for additional methods that accept a String as a parameter. (The implicit keyword has a lot of power.)
  • In my BetterString class I've defined my increment method, and it does the work of walking through each character in a String, incrementing that Char by one byte, and then returning the entire sequence of new characters when it's finished iterating over the String.

As a result, I've tied my increment method to the String class, so I can now type something like this:

"foo".increment

Testing it in the Scala REPL

If you're new to implicit conversions, I'm sure that's still a little hard to understand, so let's take a look at how this works in the Scala REPL. First we define our class:

scala> class BetterString(val s: String) {
     | def increment = s.map(c => (c + 1).toChar)
     | }
defined class BetterString

That looks just like a normal Scala class, no magic there. Next we define our stringToString function:

scala> implicit def stringToString(s: String) = new BetterString(s)
stringToString: (s: String)BetterString

Again, except for the implicit keyword, that looks like a normal function.

And now it's time for the big test. Let's create a String literal and then see if our increment method will work:

scala> "HAL".increment
res0: String = IBM

As you can see from that last line, I typed in the String "HAL", then followed it with my increment method, and that method returned a new String "IBM", which is the result of incrementing each character by one byte.

Posted by 1010
00.scala2014. 3. 28. 12:57
반응형

Depending on your personal preference, or perhaps the needs of the moment, you can use a C#-style "curly brace" package syntax in your Scala applications, instead of the usual Java-style. As a quick example of what this looks like, here are a couple of simple package names and classes:

package orderentry {
  class Order
  class LineItem
  class Foo
}

package customers {
  class Customer
  class Address
  class Foo

  package database {
    // this is the "customers.database" package/namespace
    class CustomerDao
    // this Foo is different than customers.Foo or orderentry.Foo
    class Foo
  }
}

In this example I've defined three package namespaces:

  • orderentry
  • customers
  • customers.database

As you can see from the code, I also have three classes named "Foo", and they are different classes in different packages. I have:

  • orderentry.Foo
  • customers.Foo
  • customers.database.Foo

Of course this isn't any different than what you can do in Java, but this "curly brace" package syntax is very different than what you can write in Java, so I wanted to share this alternate syntax.

Packages inside packages

As another simple example, you can include one Scala package inside another using curly braces, like this:

package tests

package foo {
  package bar {
    package baz {
      class Foo {
        override def toString = "I'm a Foo"
      }
    }
  }
}

object PackageTests {

  def main(args: Array[String]) {
    // create an instance of our Foo class
    val f = new foo.bar.baz.Foo
    println(f.toString)
  }

}

As you can see, after creating the Foo class in the foo.bar.baz package, we can create an instance of it as usual, like this:

val f = new foo.bar.baz.Foo

I hope these Scala packaging examples have been helpful.

Posted by 1010
00.scala2014. 3. 28. 12:56
반응형

I just found some notes from when I first began working with Scala, and I was working with the yieldkeyword in for loops. If you haven't worked with something like yield before, it will be helpful to know how it works. Here's a statement of how the yield keyword works in for loops, based on the documentation in the book, Programming in Scala:

For each iteration of your for loop, yield generates a value which will be remembered. It's like the for loop has a buffer you can't see, and for each iteration of your for loop, another item is added to that buffer. When your for loop finishes running, it will return this collection of all the yielded values. The type of the collection that is returned is the same type that you were iterating over, so a Map yields a Map, a List yields a List, and so on.

Also, note that the initial collection is not changed; the for/yield construct creates a new collection according to the algorithm you specify.

Given that background information, let's take a look at a few for/yield examples. First, let's just yield a collection that is identical to the collection we are looping over:

scala> for (i <- 1 to 5) yield i
res10: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5)

Nothing too exciting there, but it's a start. Next, let's double every element in our initial collection:

scala> for (i <- 1 to 5) yield i * 2
res11: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)

Here's what the modulus operator does in a for/yield loop:

scala> for (i <- 1 to 5) yield i % 2
res12: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 0, 1, 0, 1)

for loop yield examples over a Scala Array

I mentioned in my description that the for loop yield construct returns a collection that is the same as the collection it is given. To demonstrate this, let's look at the same examples with a Scala Array. Note the type of the collection that is yielded, and compare it to the previous examples:

scala> val a = Array(1, 2, 3, 4, 5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for (e <- a) yield e
res5: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for (e <- a) yield e * 2
res6: Array[Int] = Array(2, 4, 6, 8, 10)

scala> for (e <- a) yield e % 2
res7: Array[Int] = Array(1, 0, 1, 0, 1)

As you can see, in these examples an Array[Int] was yielded, while in the earlier examples an IndexedSeq[Int] was returned.

for loop, yield, and guards (for loop 'if' conditions)

If you're familiar with the Scala for comprehension syntax, you know that you can add 'if' statements to your for loop construct. Tests like these are often referred to as "guards", and you can combine them with the yield syntax, as shown here:

scala> val a = Array(1, 2, 3, 4, 5)
a: Array[Int] = Array(1, 2, 3, 4, 5)

scala> for (e <- a if e > 2) yield e
res1: Array[Int] = Array(3, 4, 5)

As you can see, adding the "if e > 2" guard condition limits the Array we return to the three elements shown.

Posted by 1010