'분류 전체보기'에 해당되는 글 2491건

  1. 2014.03.28 Converting Java collections to Scala collections
  2. 2014.03.28 Scala data types (bit sizes, ranges, and docs)
  3. 2014.03.28 Convert a Scala array to string with mkString
  4. 2014.03.28 Simple Scala string array examples
  5. 2014.03.28 Mutable Scala arrays (adding elements to arrays)
  6. 2014.03.28 Scala - Declaring a null var variable (field) before a try, catch, finally block
  7. 2014.03.28 The Scala try, catch, finally syntax (multiple exceptions, wildcard operator)
  8. 2014.03.28 Scala FAQ - How to create a private default/primary constructor
  9. 2014.03.28 Scala - How to rename a class when you import it (a 'rename on import' syntax example)
  10. 2014.03.28 Scala equivalent of Java .class (classOf)
  11. 2014.03.28 Class casting in Scala
  12. 2014.03.28 Scala methods: dots, spaces, and parentheses
  13. 2014.03.28 Scala functions - named arguments and default arguments
  14. 2014.03.28 How to create multiple class constructors in Scala
  15. 2014.03.28 Scala - Importing Java classes and packages
  16. 2014.03.28 Creating Scala JavaBeans with the @BeanProperty annotation
  17. 2014.03.28 A Scala Spring Framework dependency injection example
  18. 2014.03.28 Scala - How to add new methods to existing classes
  19. 2014.03.28 Scala C# style package syntax (curly brace syntax)
  20. 2014.03.28 Scala for/yield examples (for loop and yield examples)
  21. 2014.03.28 The Scala ternary operator syntax
  22. 2014.03.28 Scala if then else syntax (and returning a value from an if statement)
  23. 2014.03.28 A Scala current date/time example
  24. 2014.03.28 Scala - Using a Match Expression Like a switch Statement
  25. 2014.03.28 Simple Scala recursion examples (recursive programming)
  26. 2014.03.28 A Scala XML XPath example
  27. 2014.03.28 Code Examples for Programming in Scala
  28. 2014.03.28 SCALA DOWNLOAD PREVIOUS VERSIONS
  29. 2014.03.28 Scala (programming language)
  30. 2014.03.18 jQuery Scrollable Table Plugin
00.scala2014. 3. 28. 13:34
반응형

While working on a new Scala application, I just ran into a situation where a Java class I was using returned a Java List to me. I wasn't exactly thinking too hard at that moment, and didn't realize it was actually a Java List until I tried to use the foreach method on it, and Eclipse balked at me.

Suddenly I ran into a common problem in Scala: When you're using Java classes from Scalaapplications, those Java class will return Java collections. You can then either use them as the Java collections that they are (such as using a Java Iterator), or cast them to Scala collections.

Easily converting Java collections to Scala collections

Amazingly, to use methods like foreach, map, filter, find, and so on with my Java List, all I had to do was add this one import statement to my Scala application:

import scala.collection.JavaConversions._

Once I did that, I could suddenly use a foreach method on my List.

Let's take a quick look at how this works with the Scala command line tool (the Scala REPL). First, we'll create a java.util.List as normal, and see what the REPL shows:

scala> var list = new java.util.ArrayList[Int]()
list: java.util.ArrayList[Int] = []

scala> list.add(1)
res1: Boolean = true

scala> list.add(2)
res2: Boolean = true

Now, if I try to use the foreach method on the Java list, it will fail, as expected:

scala> list.foreach
<console>:9: error: value foreach is not a member of java.util.ArrayList[Int]
             list.foreach
                   ^

However, if I now add the magic JavaConversions import statement to my Scala code:

import scala.collection.JavaConversions._

I can then "magically" use the foreach method on my Java List object:

list.foreach { i => println(i) }
1
2

Scala, Java List, foreach, map, filter - How it works

I just started learning Scala in 2011, and it looks like programmers long before me realized the need for the Java to Scala collection conversions, and added this functionality in Scala 2.8. I haven't dug into the source code behind the scenes to see how this magic works, but I just found a nice discussion of the background at the Graham Hacking Scala website.

Graham mentions several interesting points in that article, including these notes:

If we look a bit further into the Scala API, we'll see that there's also a trait called Seq, which is a slightly better parallel to Java's List than the Iterable or Traversable traits. So what you really want to end up with when you bring your Java List into your Scala code is a Scala Seq, not a Scala List.

Conversions between Java and Scala collections with JavaConversions

While I'm on this topic, I'll conclude with a few links to the Scala website, where you can find more information:

As you can see from that second link, the JavaConversions object currently supports the following Java to Scala collections conversions:

scala.collection.Iterable <=> java.lang.Iterable
scala.collection.Iterable <=> java.util.Collection
scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
scala.collection.mutable.Buffer <=> java.util.List
scala.collection.mutable.Set <=> java.util.Set
scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap

Important for my current project, the following one-way conversions are also offered:

scala.collection.Seq         => java.util.List
scala.collection.mutable.Seq => java.util.List
scala.collection.Set         => java.util.Set
scala.collection.Map         => java.util.Map
java.util.Properties         => scala.collection.mutable.Map[String, String]

In summary, I hope this brief tutorial on converting Java collections, such as a List, to Scala collections, has been helpful.

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

Scala FAQ: What are the Scala data types? How many bits do they use to store their data, and what is the range of those data types?

Courtesy of the excellent book, Programming in Scala, here is a list and description of the Scala data types, including bit sizes and data ranges:

Data Type     Definition

Boolean       true or false

Byte          8-bit signed two's complement integer (-2^7 to 2^7-1, inclusive)
Short         16-bit signed two's complement integer (-2^15 to 2^15-1, inclusive)
Int           32-bit two's complement integer (-2^31 to 2^31-1, inclusive)
Long          64-bit two's complement integer (-2^63 to 2^63-1, inclusive)

Float         32-bit IEEE 754 single-precision float
Double        64-bit IEEE 754 double-precision float

Char          16-bit unsigned Unicode character (0 to 2^16-1, inclusive)
String        a sequence of Chars

Notes about Scala data types

The String class resides in the package java.lang, and all these other types are in the package scala.

You may have noticed that these data types in Scala have the exact same range as the corresponding data types in Java. This makes it easy to convert these Scala types to their corresponding Java primitive types.

Also interesting to note, if you're into specifics: Collectively, Byte, Short, Int, Long, and Char are calledintegral types. The integral types plus Float and Double are called numeric types. (That was again courtesy of the book, Programming in Scala.)

Official Scala data type documentation

Here are links to the official Scala docs for these data types:

And here's a link to the Programming in Scala book on Amazon:

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

Scala collections FAQ: How can I convert a Scala array to a String?

A simple way to convert a Scala array to a String is with the mkString method of the Array class. (Although I've written "array", the same technique also works with any Scala sequence, including Array, List, Seq, ArrayBuffer, Vector, and other sequence types.)

Here's a quick array to string example using the Scala REPL:

scala> val args = Array("Hello", "world", "it's", "me")
args: Array[java.lang.String] = Array(Hello, world, it's, me)

scala> val string = args.mkString(" ")
string: String = Hello world it's me

In this first statement:

val args = Array("Hello", "world", "it's", "me")

I create a Scala array named args, and in this second statement:

val string = args.mkString(" ")

I create a new String variable named string, separating each String in the array with a space character, which I specified when calling the mkString function.

Using other separator strings

Note that I could have given the mkString function any String to use as a separating character, like this:

scala> val string = args.mkString("\n")
string: String = 
Hello
world
it's
me

or like this:

scala> val string = args.mkString(" . ")
string: String = Hello . world . it's . me

Converting a Scala Int array to a String

As a final example, you can also use the Scala mkString method to convert an Int array to a String, like this:

scala> val numbers = Array(1,2,3)
numbers: Array[Int] = Array(1, 2, 3)

scala> val string = numbers.mkString(", ")
string: String = 1, 2, 3

In summary, I hope these Scala "Array to String" examples have been helpful.

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

Scala array FAQ: How do I create a String array in Scala?

There are a few different ways to create String arrays in Scala. If you know all your array elements initially, you can create a Scala string array like this:

val fruits = Array("Apple", "Banana", "Orange")

If you don't know the strings that you want in your array initially, but know the size of your array, you can create it first, then populate it later, like this:

val fruits = new Array[String](3)

// somewhere later in the code ...

fruits(0) = "Apple"
fruits(1) = "Banana"
fruits(2) = "Orange"

Mutable Scala String arrays

Note that if you want to create a mutable Scala String array, you really want to use the Scala ArrayBufferclass instead of the Array class, like this:

import scala.collection.mutable.ArrayBuffer
var fruits = ArrayBuffer[String]()
fruits += "Apple"
fruits += "Banana"
fruits += "Orange"

See my Mutable Scala arrays (adding elements to arrays) tutorial for more information on using the Scala ArrayBuffer.

I can add more Scala String array syntax examples over time, but for now, those are the two most common approaches I know.

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

Just a quick note today that if you want to create a mutable Scala array -- particularly an array that can grow in size after you first declare it -- you need to use the Scala ArrayBuffer class instead of the Array class, which can't grow.

Here's a short example of how to instantiate an ArrayBuffer object, then add elements to the array:

import scala.collection.mutable.ArrayBuffer

var fruits = ArrayBuffer[String]()
fruits += "Apple"
fruits += "Banana"
fruits += "Orange"

Once you have an ArrayBuffer object, you can generally use it like an Array, getting elements like this:

println(fruits(0))

getting the array length like this:

println(fruits.length)

and so on.

Again, the only trick here is knowing that you can't add elements to a Scala array, and therefore, if you want to grow an array, you need to use the ArrayBuffer class instead.

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

Sometimes when you're writing Scala code, you need to create a null variable (a var, not a val), such as when you need to declare a variable right before using it in a try, catch, finally block. I just ran into this when writing a Scala IMAP email client, where I needed to create two variables right before the trydeclaration, so I could reference the fields in the try block and also in the finally block.

The way you declare a null var variable in Scala is like this:

var store: Store = null
var inbox: Folder = null

As you can see from that code, the secret is knowing that you have to assign the type to the variable when you declare it. If you don't do this, Scala won't know the data type of the variable, so it won't allow you to do this, but if you do it, Scala will be happy.

A complete example

As for my specific problem -- needing to declare a Scala variable right before a try/catch/finally clause -- here's what the solution looks like:

// (1) declare the null variables
var store: Store = null
var inbox: Folder = null

try {
  // (2) use the variables/fields in the try block
  store = session.getStore("imaps")
  inbox = getFolder(store, "INBOX")
  // rest of the code here ...
  catch {
    case e: NoSuchProviderException =>  e.printStackTrace()
                                        System.exit(1)
    case me: MessagingException =>      me.printStackTrace()
                                        System.exit(2)
} finally {
  // (3) use the variables/fields in the finally clause
  inbox.close
  store.close
}

In summary, I hope this short example of how to declare an empty/null variable before a try/catch block in Scala has been helpful.

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

Scala FAQ: Can you share some examples of the Scala try/catch/finally syntax? Also, can you show how to catch multiple exceptions, and just one exception with the Scala wildcard operator (_)?

The general Scala try/catch/finally syntax looks like this:

try
{
  // your scala code here
} 
catch
{
  case foo: FooException => handleFooException(foo)
  case bar: BarException => handleBarException(bar)
  case _ => println("Got some other kind of exception")
}
finally
{
  // your scala code here, such as to close a database connection
}

As you can see, the Scala try-catch-finally syntax is similar to the Java try-catch-finally syntax, except for the catch area, which uses Scala's pattern matching capabilities to handle the different exceptions you might run into.

In that example, I'm intentionally catching a FooException and a BarException, and then I'm using the Scala "_" wildcard operator to catch any other exceptions that might occur.

Using the Scala _ wildcard operator in a catch clause

One drawback of using Scala's wildcard character (_) in a catch clause is that you can't refer to it in your code, such as if you want to print the exception.

In the excellent book, Programmming Scala, the authors suggest naming your exception variable instead of using the wildcard, which you can then refer to in your own code, something like this:

try
{
  // your scala code here
} 
catch
{
  case foo: FooException => handleFooException(foo)
  case bar: BarException => handleBarException(bar)
  
  // handling any other exception that might come up
  case unknown => println("Got this unknown exception: " + unknown)
}
finally
{
  // your scala code here, such as to close a database connection
}

As you can see from that code, I just name a variable "unknown", which I can then refer to by name.

Printing a Scala exception's stack trace

Finally, here's another Scala try/catch example, where I demonstrate how to print the stack trace from an exception:

def runAppleScriptCommand(c: AppleScriptCommand) {
  val scriptEngineManager = new ScriptEngineManager
  val appleScriptEngine = scriptEngineManager.getEngineByName("AppleScript")
  try {
    appleScriptEngine.eval(c.command)
  } catch {
    case e: ScriptException => e.printStackTrace
  }
}

Scala try/catch/finally examples - Summary

I hope these examples of the Scala try/catch/finally syntax have been helpful. As usual, if you have any questions, comments, corrections, or better examples, just leave a note in the comments section below.

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

I haven't had the need for this syntax yet, but I just saw some code that shows how to create a private primary constructor in Scala, and I thought I'd test it and share an example of it.

In the example below, I've made the primary constructor of the Order class private:

object PrivateConstructorTests {

  def main(args: Array[String]) {
    val o = new Order  // this won't compile
  }

}

// note the 'private' keyword here
class Order private() {
  
  def this(orderId: Long) {
    this();
    // more code here ...
  }  
  
}

Private primary constructor syntax

The primary constructor is made private in this unusual looking line of code:

class Order private() {

This syntax might make a little more sense if I show a primary constructor that takes a parameter:

class Order private(customerId: Long) {

In either case, the "private" keyword in the location shown makes the primary constructor private.

Getting back to the first source code example, as you saw from the comment included in the source code, this line of code won't even compile because the primary constructor is private:

val o = new Order  // this won't compile

Again, I haven't had a need to use this Scala "private constructor" syntax yet, but I used to use it in Java when I wanted to enforce the Singleton Pattern, as is done in the Java Calendar class.

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

Scala offers a cool feature where you can rename a class when you import it, including both Scala and Java classes. The basic syntax to rename a class on import looks like this:

import scala.collection.mutable.{Map => MMap}

and this:

import java.util.{HashMap => JavaMap}

If all you needed to know, I hope those "rename on import" syntax examples were helpful.

Why rename a class on import?

An interesting question is, "Why would I want to rename a class on import?"

I've found that I do it to avoid namespace collisions, and/or to make things more clear. For instance, inScala the immutable Map class is imported by default, and if you want to use the mutable version you have to import it manually, as shown here:

# using Map w/o an import gives you an immutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

# after the import, the same syntax gives you a mutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.mutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

This can seem confusing, so one way to work around this confusion -- and make your code more obvious -- is to rename the mutable Map class when you import it. Here's a similar example, but in this case I rename the mutable Map class when I import it:

# at first i get an immutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

# i rename the mutable Map class when i import it
scala> import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{Map=>MMap}

# here i still get an immutable Map
scala> val m = Map("name" -> "Al")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

# but here i get a mutable Map by referring to MMap
scala> val m = MMap("name" -> "Al")
m: scala.collection.mutable.Map[java.lang.String,java.lang.String] = Map(name -> Al)

I personally like this approach, because again it makes the code more obvious. You could correctly argue that I could have made it even more obvious if I renamed the class to MutableMap, but in this case I opted for brevity.

Summary

There are many more ways you can use this ability to rename classes when you import them in Scala, and if you have a good example you'd like to share, just leave a note below. Until then, reporting live from Boulder, Colorado, this is Alvin Alexander.

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

In Java, you sometimes refer to .class in your source code, like this:

info = new DataLine.Info(TargetDataLine.class, null);

As you can see, I refer to TargetDataLine.class in this code. This works fine in Java, but if you've tried it in Scala, you know the .class part of that code won't work.

In Scala, if you want to use ".class", you instead need to use the classOf function: The following Scala classOf code is equivalent to the previous Java .class code:

val info = new DataLine.Info(classOf[TargetDataLine], null)

In summary:

In Java, use Foo.class
In Scala, use classOf[Foo]

Scala getClass and classOf

I won't take any time to discuss this today, but if you're interested in a little more information, here's the output from a short Scala REPL session that shows how to use getClass and classOf:

scala> val s = "Foo"
s: java.lang.String = Foo

scala> s.getClass
res7: java.lang.Class[_ <: java.lang.String] = class java.lang.String

scala> s.getClass.toString
res8: java.lang.String = class java.lang.String

scala> classOf[String]
res9: java.lang.Class[String] = class java.lang.String


Posted by 1010
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
00.scala2014. 3. 28. 12:56
반응형

Scala FAQ: What is the Scala ternary operator syntax?

In other programming languages there is a definite, unique ternary operator syntax, but in Scala, the ternary operator is just the normal Scala if/else syntax:

if (i == 1) x else y

The beauty of this is (a) it is just the normal if/else syntax, so you don't have to remember something else, and (b) it's easy to read.

Also, as you can see from this example, you can use the Scala ternary operator syntax on the right hand side of the equation, as you might be used to doing with Java:

val a = if (i == 1) x else y;

Contrast the readability of the Scala ternary syntax with the Java ternary operator syntax:

i == 1 ? x : y


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

Scala FAQ: Can you share some examples of the Scala if/then/else syntax? Also, can you show a function that returns a value from an if/then/else statement?

In its most basic use, the Scala if/then/else syntax is very similar to Java:

if (your test)
{
  // do something
}
else if (some test)
{
// do something
}
else
{
// do some default thing
}

A nice improvement on the Java if/then/else syntax is that you can Scala if/then statements also return a value. As a result, there's no need for a ternary operator in Scala.

This means that you can write if/then statements in Scala like this:

val x = if (a > b) a else b

where you assign the result of your if/then expression to a Scala variable.

Assigning if statement results in a function

You can also assign the results from a Scala if statement in a simple function, like this absolute value function:

def abs(x: Int) = if (x >= 0) x else -x


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

Scala date/time FAQ: How do I get the current date and time in Scala?

The following code demonstrates how to get the current time in Scala, and then further shows how to get other information, such as the current minute, using the Java SimpleDateFormat class:

def onTheFives :Boolean = {
  val today = Calendar.getInstance().getTime()
  val minuteFormat = new SimpleDateFormat("mm")
  val currentMinuteAsString = minuteFormat.format(today)
  try {
    val currentMinute = Integer.parseInt(currentMinuteAsString)
    if (currentMinute % 5 == 0) return true
    else return false
  } catch {
    case _ => return false
  }
}

As you can see, you get the current time in Scala with this line of code:

val today = Calendar.getInstance().getTime()

This uses the Java Calendar class, which you'll have to import into your Scala application.

I later get the "current minute" from the current time object using the Java SimpleDateFormat class using these lines of code:

val minuteFormat = new SimpleDateFormat("mm")
val currentMinuteAsString = minuteFormat.format(today)

One problem with this approach is that the minute comes back as a String, which can be something like "01". Because I'm trying to get my computer to speak the current time to me, I don't want that leading zero, so I convert the String to an Int using the code shown in the try/catch brackets.

Getting the current hour in Scala

On a related note, if you want to get the current hour in Scala, you can use this very similar method:

def getCurrentHour: String = {
  val today = Calendar.getInstance().getTime()
  val hourFormat = new SimpleDateFormat("hh")
  try {
    // returns something like "01" if i just return at this point, so cast it to
    // an int, then back to a string (or return the leading '0' if you prefer)
    val currentHour = Integer.parseInt(hourFormat.format(today))
    return "" + currentHour
  } catch {
    // TODO return Some/None/Whatever
    case _ => return "0"
  }
  return hourFormat.format(today)
}

This code returns the current hour as a String. (I'm sure there are probably better ways to write this, but my writing time for today is up, so I'll have to leave the code like this for now.)

More Scala SimpleDateFormat examples

On a related note I'll share the following Scala code, which shows a few more SimpleDateFormat examples:

val today = Calendar.getInstance().getTime()
    
// create the date/time formatters
val minuteFormat = new SimpleDateFormat("mm")
val hourFormat = new SimpleDateFormat("hh")
val amPmFormat = new SimpleDateFormat("a")

val currentHour = hourFormat.format(today)      // 12
val currentMinute = minuteFormat.format(today)  // 29
val amOrPm = amPmFormat.format(today)           // PM


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

Problem: You have a situation where you want to create something like a simple Java integer-based switch statement, such as matching the days in a week, months in a year, and other situations where an integer maps to a result.

Solution

To use a Scala match expression like a Java switch statement, use this approach:

i match {
  case 1  => println("January")
  case 2  => println("February")
  case 3  => println("March")
  case 4  => println("April")
  case 5  => println("May")
  case 6  => println("June")
  case 7  => println("July")
  case 8  => println("August")
  case 9  => println("September")
  case 10 => println("October")
  case 11 => println("November")
  case 12 => println("December")
  // catch the default with a variable so you can print it
  case whoa  => println("Unexpected case: " + whoa.toString)
}

That example shows how to take an action based on a match. A more functional approach returns a value from a match expression:

val month = i match {
  case 1  => "January"
  case 2  => "February"
  case 3  => "March"
  case 4  => "April"
  case 5  => "May"
  case 6  => "June"
  case 7  => "July"
  case 8  => "August"
  case 9  => "September"
  case 10 => "October"
  case 11 => "November"
  case 12 => "December"
  case _  => "Invalid month"  // the default, catch-all
}

The @switch annotation

When writing simple match expressions like this, it’s recommended that you use the @switchannotation. This annotation provides a warning at compile time if the switch can’t be compiled to atableswitch or lookupswitch.

Compiling your match expression to a tableswitch or lookupswitch is better for performance, because it results in a branch table rather than a decision tree. When a value is given to the expression, it can jump directly to the result rather than working through the decision tree.

Here’s the official description from the @switch annotation documentation:

“An annotation to be applied to a match expression. If present, the compiler will verify that the match has been compiled to a tableswitch or lookupswitch, and issue an error if it instead compiles into a series of conditional expressions.”

The effect of the @switch annotation is demonstrated with a simple example. First, place the following code in a file named SwitchDemo.scala:

// Version 1 - compiles to a tableswitch
import scala.annotation.switch

class SwitchDemo {

  val i = 1
  val x = (i: @switch) match {
    case 1  => "One"
    case 2  => "Two"
    case _  => "Other"
  }

}

Then compile the code as usual:

$ scalac SwitchDemo.scala

Compiling this class produces no warnings, and creates the output file SwitchDemo.class. Next, disassemble that file with this javap command:

$ javap -c SwitchDemo

The output from this command shows a tableswitch, like this:

16:  tableswitch{ //1 to 2
            1: 50;
            2: 45;
            default: 40 }

This shows that Scala was able to optimize your match expression to a tableswitch. (This is a good thing.)

Next, make a minor change to the code, replacing the integer literal 2 with a value:

import scala.annotation.switch

// Version 2 - leads to a compiler warning
class SwitchDemo {

  val i = 1
  val Two = 2                     // added
  val x = (i: @switch) match {
    case 1  => "One"
    case Two => "Two"             // replaced the '2'
    case _  => "Other"
  }

}

Again, compile the code with scalac, but right away you’ll see a warning message:

$ scalac SwitchDemo.scala 

SwitchDemo.scala:7: warning: could not emit switch for @switch annotated match
  val x = (i: @switch) match {
               ^
one warning found

This warning message is saying that neither a tableswitch nor lookupswitch could be generated for the match expression. You can confirm this by running the javap command on the SwitchDemo.class file that was generated. When you look at that output, you’ll see that the tableswitch shown in the previous example is now gone.

In his book, Scala In Depth, Joshua Suereth states that the following conditions must be true for Scala to apply the tableswitch optimization:

  1. The matched value must be a known integer.
  2. The matched expression must be “simple.” It can’t contain any type checks, if statements, or extractors.
  3. The expression must also have its value available at compile time.
  4. There should be more than two case statements.

For more information on how JVM switches work, see the Oracle document, “Compiling Switches.”

Discussion

As demonstrated in other recipes, you aren’t limited to matching only integers; the match expression is incredibly flexible:

def getClassAsString(x: Any):String = x match {
  case s: String => s + " is a String"
  case i: Int => "Int"
  case f: Float => "Float"
  case l: List[_] => "List"
  case p: Person => "Person"
  case _ => "Unknown"
}

Handling the default case

The examples in the Solution showed the two ways you can handle the default, “catch all” case. First, if you’re not concerned about the value of the default match, you can catch it with the UNDERSCORE wildcard:

case _ => println("Got a default match")

Conversely, if you are interested in what fell down to the default match, assign a variable name to it. You can then use that variable on the right side of the expression:

case default => println(default)

Using the name default often makes the most sense and leads to readable code, but you can use any legal name for the variable:

case oops => println(oops)

You can generate a MatchError if you don’t handle the default case. For instance, given this matchexpression:

i match {
  case 0 => println("0 received")
  case 1 => println("1 is good, too")
}

If i is a value other than 0 or 1, the expression throws a MatchError:

scala.MatchError: 42 (of class java.lang.Integer)
  at .<init>(<console>:9)
  at .<clinit>(<console>)
    much more error output here ...

So unless you’re intentionally writing a partial function, you’ll want to handle the default case. (See Recipe 9.8, “Creating Functions that Work for a Subset of Data (Partial Functions),” for more information on partial functions.)

Do you really need a switch statement?

Of course you don’t really need a switch statement if you have a data structure that maps month numbers to month names. In that case, just use a Map:

val monthNumberToName = Map(
    1  -> "January",
    2  -> "February",
    3  -> "March",
    4  -> "April",
    5  -> "May",
    6  -> "June",
    7  -> "July",
    8  -> "August",
    9  -> "September",
    10 -> "October",
    11 -> "November",
    12 -> "December"
)

val monthName = monthNumberToName(4)
println(monthName)  // prints "April"


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


As I’ve been learning more about Scala andfunctional programming, I’ve been looking at accomplishing more tasks with recursive programming techniques. As part of my studies I put together a number of Scala recursion examples below, including:

  • Sum
  • Product
  • Max
  • Fibonacci
  • Factorial

I won’t write too much about recursion theory today, just some basic thoughts. I’ll come back here and add more when I have some good thoughts or better examples to share.

Thinking in recursion

When I’m going to write a recursive method, I usually think about it like this:

  • I know I want to do something with a collection of data elements.
  • Therefore, my function will usually take this collection as an argument.
  • Within the function I usually have two branches:
    • In one case, when I’m handling the situation of being at the last element of the collection, I do some “ending” operation. For instance, in the Sumexample below, when I get to the Nil element in a List, I return 0 and let the recursive method calls unroll.
    • In the second case, as when the function is not at the end of the list, I write the code for my main algorithm; it operates on the current element in the collection (the ’head’ element); I then recursively call my function, passing it the remainder of the collection (the ’tail’).
  • When the function calls unroll, the function returns whatever it is that I’m calculating. For instance, in the sum, product, and max functions that follow, the function returns anInt. In the Fibonacci example the function prints its result as it goes along, so it doesn’t return anything.

As another note, in some cases it helps to have an “accumulator” function inside your main function. I show this in the examples that follow, and I’ll describe it more at some point in the future.

A recursive ’sum’ function

The following code shows three ways to calculate the sum of a List[Int] recursively. I don’t think the first approach is practical; it is simple, but results in a StackOverflowError when the list is large.

The second approach shows how to fix the first approach by using a tail-recursive algorithm. This solution uses the “accumulator” I mentioned above.

The third approach shows how to use an if/else construct instead of a match expression. It’s taken from the URL shown.

With that introduction, here’s the code:

package recursion

import scala.annotation.tailrec

/**
 * Different ways to calculate the sum of a list using 
 * recursive Scala methods.
 */
object Sum extends App {

  val list = List.range(1, 100)
  println(sum(list))
  println(sum2(list))
  println(sum3(list))
  println(sumWithReduce(list))
  
  // (1) yields a "java.lang.StackOverflowError" with large lists
  def sum(ints: List[Int]): Int = ints match { 
    case Nil => 0
    case x :: tail => x + sum(tail)
  }

  // (2) tail-recursive solution
  def sum2(ints: List[Int]): Int = {
    @tailrec
    def sumAccumulator(ints: List[Int], accum: Int): Int = {
      ints match {
        case Nil => accum
        case x :: tail => sumAccumulator(tail, accum + x)
      }
    }
    sumAccumulator(ints, 0)
  }
  
  // (3) good descriptions of recursion here:
  // stackoverflow.com/questions/12496959/summing-values-in-a-list
  // this example is from that page:
  def sum3(xs: List[Int]): Int = {
    if (xs.isEmpty) 0
    else xs.head + sum3(xs.tail)
  }
  
}

I don’t want to stray too far from the point of this article, but while I’m talking about “sum” algorithms, another way you can calculate the sum of a List[Int] in Scala is to use the reduceLeft method on theList:

def sumWithReduce(ints: List[Int]) = {
  ints.reduceLeft(_ + _)
}

(That’s all I’ll say about reduceLeft today.)

Calculating the “product” of a List[Int] recursively

Calculating the product of a List[Int] is very similar to calculating the sum; you just multiply the values inside the function, and return 1 in the Nil case. Therefore I’ll just show the following code without discussing it:

package recursion

import scala.annotation.tailrec

/**
 * Different ways to calculate the product of a List[Int] recursion.
 */
object Product extends App {

  val list = List(1, 2, 3, 4)
  println(product(List(1, 2, 3, 4)))
  println(product2(List(1, 2, 3, 4)))

  // (1) basic recursion; yields a "java.lang.StackOverflowError" with large lists
  def product(ints: List[Int]): Int = ints match { 
    case Nil => 1
    case x :: tail => x * product(tail)
  }

//  // (2) tail-recursive solution
  def product2(ints: List[Int]): Int = {
    @tailrec
    def productAccumulator(ints: List[Int], accum: Int): Int = {
      ints match {
        case Nil => accum
        case x :: tail => productAccumulator(tail, accum * x)
      }
    }
    productAccumulator(ints, 1)
  }

}

Calculating the “max” of a List[Int] recursively

Calculating the “max” of a List[Int] recursively is a little different than calculating the sum or product. In this algorithm you need to keep track of the highest value found as you go along, so I jump right into using an accumulator function inside the outer function.

I show two approaches in the source code below, the first using a match expression and the second using an if/else expression:

package main.scala.recursion

import scala.annotation.tailrec

object Max extends App {

  val list = List.range(1, 100000)
  println(max(list))
  println(max2(list))
  
  // 1 - using `match`
  def max(ints: List[Int]): Int = { 
    @tailrec
    def maxAccum(ints: List[Int], theMax: Int): Int = {
      ints match {
        case Nil => theMax
        case x :: tail =>
          val newMax = if (x > theMax) x else theMax
          maxAccum(tail, newMax)
      }
    }
    maxAccum(ints, 0)
  }

  // 2 - using if/else
  def max2(ints: List[Int]): Int = { 
    @tailrec
    def maxAccum2(ints: List[Int], theMax: Int): Int = {
      if (ints.isEmpty) {
        return theMax
      } else {
        val newMax = if (ints.head > theMax) ints.head else theMax
        maxAccum2(ints.tail, newMax)
      }
    }
    maxAccum2(ints, 0)
  }

}

A Scala Fibonacci recursion example

The code below shows one way to calculate a Fibonacci sequence recursively using Scala:

package recursion

/**
 * Calculating a Fibonacci sequence recursively using Scala.
 */
object Fibonacci extends App {

  println(fib(1, 2))
  
  def fib(prevPrev: Int, prev: Int) {
    val next = prevPrev + prev
    println(next)
    if (next > 1000000) System.exit(0)
    fib(prev, next)
  }

}

There are other ways to calculate a Fibonacci sequence, but since my function takes two Int values as arguments and prints as it goes along, this solution works.

Recursive factorial algorithms

Finally, without much discussion, the following Scala code shows two different recursive factorial algorithms, with the second solution showing the tail-recursive solution:

package recursion

import scala.annotation.tailrec

object Factorial extends App {

  println(factorial(5))
  println(factorial2(5))

  // 1 - basic recursive factorial method
  def factorial(n: Int): Int = { 
    if (n == 0) 
      return 1
    else
      return n * factorial(n-1)
  }
  
  // 2 - tail-recursive factorial method
  def factorial2(n: Long): Long = {
    @tailrec
    def factorialAccumulator(acc: Long, n: Long): Long = {
      if (n == 0) acc
      else factorialAccumulator(n*acc, n-1)
    }
    factorialAccumulator(1, n)
  }
 
}


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

A Scala XML XPath example

I'm not going to take any time to describe the following Scala XML/XPath example, other than to say that when it's run, it produces the following output, which is a simulated receipt for an order at a pizza store:

14 thin (Cheese, Sausage)        12.00
Breadsticks                       4.00
Federal Tax                       0.80
State Tax                         0.80
Local Tax                         0.40
TOTAL:                           18.00

The XML

The XML that represents the "order" is shown at the bottom of the code, but I'll repeat it here for your convenience:

def getXml = {
  <order>
    <item name="Pizza" price="12.00">
      <pizza>
        <crust type="thin" size="14" />
        <topping>cheese</topping>
        <topping>sausage</topping>
      </pizza>
    </item>
    <item name="Breadsticks" price="4.00">
      <breadsticks />
    </item>
    <tax type="federal">0.80</tax>
    <tax type="state">0.80</tax>
    <tax type="local">0.40</tax>
  </order>
}

The Scala XML XPath code

Given that extremely limited introduction, here is today's Scala XML and XPath example code:

package com.devdaily.xmltests

import scala.xml._

/**
 * A Scala XML XPath example.
 * Author: Alvin Alexander, http://devdaily.com
 */
object ScalaXmlXpathExample extends App {

  println(getReceipt(getXml))

  def getReceipt(xml: Elem): String = {
    val sb = new StringBuilder
    sb.append(getLineItemsReceiptString(xml))
    sb.append(getTaxItemsReceiptString(xml))
    sb.append(getTotalLineForReceipt(xml))
    sb.toString
  }
  
  def getLineItemsReceiptString(xml: Elem) = {
    buildReceiptString(getOrderItems(xml), getOrderItemNameAndPrice)
  }
  
  def getTaxItemsReceiptString(xml: Elem) = {
    buildReceiptString(getTaxItems(xml), getTaxItemNameAndAmount)
  }
  
  def getTotalLineForReceipt(xml: Elem) = {
    "%-30s  %6.2f\n".format("TOTAL:", getTotalPrice(getOrderItems(xml), getTaxItems(xml)))
  }
  
  def getOrderItems(rootNode: Elem) = rootNode \ "item"
  def getTaxItems(rootNode: Elem) = rootNode \ "tax"

  // can reuse the other methods, or make these calls.
  // specifying Double as the return type here is needed, otherwise Scala
  // will make it a BoxedUnit.
  def getTotalPrice(items: NodeSeq, taxItems: NodeSeq): Double = {
    val priceWithoutTax = items.map(i => (i \ "@price").text.toDouble).sum
    val totalTax = taxItems.map(i => i.text.toDouble).sum
    priceWithoutTax + totalTax
  }
  
  // items can be orderItems or taxItems; the function 'f' should
  // correspond to that data type (getOrderItemNameAndPrice or getTaxItemNameAndAmount).
  def buildReceiptString(items: NodeSeq, f:(Node) => (String, Double)) = {
    val sb = new StringBuilder
    items.foreach{ i =>
      val (name, value) = f(i)
      sb.append("%-30s  %6.2f\n".format(name, value))
    }
    sb.toString
  }
  
  def getOrderItemNameAndPrice(itemNode: Node) = {
    val name = getDisplayableOrderItemName(itemNode)
    val price = (itemNode \ "@price").text.toDouble
    (name, price)
  }
  
  def getDisplayableOrderItemName(itemNode: Node): String = {
    getItemName(itemNode) match {
      case "Pizza" => getPizzaNameForReceipt(itemNode)
      case "Breadsticks" => getBreadsticksNameForReceipt(itemNode)
      case _ => "other"
    }
  }
  
  def getTaxItemNameAndAmount(taxNode: Node) = {
    val name = getDisplayableTaxItemName(taxNode)
    val amount = taxNode.text.toDouble
    (name, amount)
  }
  
  def getDisplayableTaxItemName(taxNode: Node) = {
    getTaxItemName(taxNode) match {
      case "local" => "Local Tax"
      case "state" => "State Tax"
      case "federal" => "Federal Tax"
      case _ => "Unknown Tax"
    }
  }

  def getTaxItemName(taxNode: Node) = (taxNode \ "@type").text
  def getItemName(itemNode: Node) = (itemNode \ "@name").text
  def getBreadsticksNameForReceipt(item: Node) = "Breadsticks"

  // want a name like: 12" Thin (Cheese, Sausage)
  def getPizzaNameForReceipt(itemNode: Node) = {
    val pizzaNode = (itemNode \ "pizza")(0)
    val crust = getPizzaCrust(pizzaNode)
    val size = getPizzaSize(pizzaNode)
    "%2d %s %s".format(size, crust, getPizzaToppingsForReceipt(pizzaNode))
  }
  
  def getPizzaToppingsForReceipt(pizzaNode: Node) = {
    getToppings(pizzaNode).map(_.capitalize).mkString("(", ", ", ")")
  }
  
  def getToppings(pizzaNode: Node) = (pizzaNode \ "topping").map(_.text)
  def getPizzaCrust(pizzaNode: Node) = (pizzaNode \ "crust" \ "@type").text
  def getPizzaSize(pizzaNode: Node) = (pizzaNode \ "crust" \ "@size").text.toInt
  
  def getXml = {
    <order>
      <item name="Pizza" price="12.00">
        <pizza>
          <crust type="thin" size="14" />
          <topping>cheese</topping>
          <topping>sausage</topping>
        </pizza>
      </item>
      <item name="Breadsticks" price="4.00">
        <breadsticks />
      </item>
      <tax type="federal">0.80</tax>
      <tax type="state">0.80</tax>
      <tax type="local">0.40</tax>
    </order>
  }

}


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

http://booksites.artima.com/programming_in_scala/examples/html/ch01.html



Code Examples for

Programming in Scala

by Martin Odersky, Lex Spoon, Bill Venners

  1. A Scalable Language
  2. First Steps in Scala
  3. Next Steps in Scala
  4. Classes and Objects
  5. Basic Types and Operations
  6. Functional Objects
  7. Built-in Control Structures
  8. Functions and Closures
  9. Control Abstraction
  10. Composition and Inheritance
  11. Scala's Hierarchy
  12. Traits
  13. Packages and Imports
  14. Assertions and Unit Testing
  15. Case Classes and Pattern Matching
  16. Working with Lists
  17. Collections
  18. Stateful Objects
  19. Type Parameterization
  20. Abstract Members
  21. Implicit Conversions and Parameters
  22. Implementing Lists
  23. For Expressions Revisited
  24. Extractors
  25. Annotations
  26. Working with XML
  27. Modular Programming Using Objects
  28. Object Equality
  29. Combining Scala and Java
  30. Actors and Concurrency
  31. Combinator Parsing
  32. GUI Programming
  33. The SCells Spreadsheet

For more information about Programming in Scala(the "Stairway Book"), please visit:

http://www.artima.com/shop/programming_in_scala

and:

http://booksites.artima.com/programming_in_scala

Copyright © 2007-2008 Artima, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


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

Scala (/ˈskɑːlə/ skah-lə) is an object-functional programming and scripting language for general software applications,statically typed, designed to concisely express solutions in an elegant,[6] type-safe and lightweight (low ceremonial) manner. Scala has full support for functional programming (including curryingpattern matchingalgebraic data typeslazy evaluationtail recursionimmutability, etc.). It cleans up what are often considered poor design decisions in Java (such astype erasurechecked exceptions, the non-unified type system) and adds a number of other features designed to allow cleaner, more concise and more expressive code to be written.[5]

Scala source code is intended to be compiled to Java bytecode, so that the resulting executable code runs on a Java virtual machine. Java libraries may be used directly in Scala code, and vice versa. Like Java, Scala is statically typed and object-oriented, and uses a curly-brace syntax reminiscent of the C programming language. Unlike Java, Scala has many features of functional programming languages like SchemeStandard ML and Haskell, including anonymous functionstype inferencelist comprehensions (known in Scala as "for-comprehensions"), lazy initialization, extensive language and library support for avoiding side-effects, for pattern matching, case classes, delimited continuationshigher-order types, and much better support for covariance and contravariance. Scala has a unified type system as in C#, but unlike in Java, in which all types, including primitive types like integer and boolean, are subclasses of the type Any. Scala likewise has other features present in C# but not Java, including anonymous typesoperator overloading, optional parameters, named parametersraw strings (that may be multi-line in Scala), and no checked exceptions.

The name Scala is a portmanteau of "scalable" and "language", signifying that it is designed to grow with the demands of its users.

History[edit]

The design of Scala started in 2001 at the École Polytechnique Fédérale de Lausanne (EPFL) by Martin Odersky, following on from work on Funnel, a programming language combining ideas from functional programming and Petri nets.[7] Odersky had previously worked on Generic Java and javac, Sun's Java compiler.[7]

Scala was released late 2003/early 2004 on the Java platform, and on the .NET platform in June 2004.[5][7][8] A second version of the language, v2.0, was released in March 2006.[5] The .NET support was officially dropped in 2012.[9]

On 17 January 2011 the Scala team won a five-year research grant of over €2.3 million from the European Research Council.[10] On 12 May 2011, Odersky and collaborators launched Typesafe Inc., a company to provide commercial support, training, and services for Scala. Typesafe received a $3 million investment fromGreylock Partners.[11][12][13][14]

Platforms and license[edit]

Scala runs on the Java platform (Java Virtual Machine) and is compatible with existing Java programs. It also runs on Android smartphones.[15] There was an alternative implementation for the .NET platform,[16][17] but it was dropped.

The Scala software distribution, including compiler and libraries, is released under a BSD license.[18]

Examples[edit]

"Hello World" example[edit]

The Hello World program written in Scala has this form:

 object HelloWorld extends App {
   println("Hello, World!")
 }

Unlike the stand-alone Hello World application for Java, there is no class declaration and nothing is declared to be static; a singleton object created when the objectkeyword is used instead.

With the program saved in a file named HelloWorld.scala, it can be compiled from the command line:

$ scalac HelloWorld.scala

To run it:

$ scala HelloWorld (You may need to use the "-cp" key to set the classpath like in Java).

This is analogous to the process for compiling and running Java code. Indeed, Scala's compilation and execution model is identical to that of Java, making it compatible with Java build tools such as Ant.

A shorter version of the "Hello World" Scala program is:

println("Hello, World!")

Saved in a file named HelloWorld2.scala, this can be run as a script without prior compilation using:

$ scala HelloWorld2.scala

Commands can also be entered directly into the Scala interpreter, using the option -e:

$ scala -e 'println("Hello, World!")'

A basic example[edit]

The following example shows the differences between Java and Scala syntax:

// Java:
int mathFunction(int num) {
    int numSquare = num*num;
    return (int) (Math.cbrt(numSquare) +
      Math.log(numSquare));
}
// Scala: Direct conversion from Java
 
// no import needed; scala.math
// already imported as `math`
def mathFunction(num: Int): Int = {
  var numSquare: Int = num*num
  return (math.cbrt(numSquare) + math.log(numSquare)).
    asInstanceOf[Int]
}
// Scala: More idiomatic
// Uses type inference, omits `return` statement,
// uses `toInt` method
 
import math._
def intRoot23(num: Int) = {
  val numSquare = num*num
  (cbrt(numSquare) + log(numSquare)).toInt
}

Some syntactic differences in this code are:

  • Scala does not require semicolons to end statements.
  • Value types are capitalized: Int, Double, Boolean instead of int, double, boolean.
  • Parameter and return types follow, as in Pascal, rather than precede as in C.
  • Functions must be preceded by def.
  • Local or class variables must be preceded by val (indicates an immutable variable) or var (indicates a mutable variable).
  • The return operator is unnecessary in a function (although allowed); the value of the last executed statement or expression is normally the function's value.
  • Instead of the Java cast operator (Type) foo, Scala uses foo.asInstanceOf[Type], or a specialized function such as toDouble or toInt.
  • Instead of Java's import foo.*;, Scala uses import foo._.
  • Function or method foo() can also be called as just foo; method thread.send(signo) can also be called as just thread send signo; and method foo.toString()can also be called as just foo toString.

These syntactic relaxations are designed to allow support for domain-specific languages.

Some other basic syntactic differences:

  • Array references are written like function calls, e.g. array(i) rather than array[i]. (Internally in Scala, both arrays and functions are conceptualized as kinds of mathematical mappings from one object to another.)
  • Generic types are written as e.g. List[String] rather than Java's List<String>.
  • Instead of the pseudo-type void, Scala has the actual singleton class Unit (see below).

An example with classes[edit]

The following example contrasts the definition of classes in Java and Scala.

// Java:
public class Point {
  private final double x, y;
 
  public Point(final double X, final double Y) {
    x = X;
    y = Y;
  }
 
  public double getX() {
    return x;
  }
 
  public double getY() {
    return y;
  }
 
  public Point(
    final double X, final double Y,
    final boolean ADD2GRID
  ) {
    this(X, Y);
 
    if (ADD2GRID)
      grid.add(this);
  }
 
  public Point() {
    this(0.0, 0.0);
  }
 
  double distanceToPoint(final Point OTHER) {
    return distanceBetweenPoints(x, y,
      OTHER.x, OTHER.y);
  }
 
  private static Grid grid = new Grid();
 
  static double distanceBetweenPoints(
      final double X1, final double Y1,
      final double X2, final double Y2
  ) {
    double xDist = X1 - X2;
    double yDist = Y1 - Y2;
    return Math.sqrt(xDist*xDist + yDist*yDist);
  }
}
// Scala
class Point(
    val x: Double, val y: Double,
    addToGrid: Boolean = false
) {
  import Point._
 
  if (addToGrid)
    grid.add(this)
 
  def this() {
    this(0.0, 0.0)
  }
 
  def distanceToPoint(other: Point) =
    distanceBetweenPoints(x, y, other.x, other.y)
}
 
object Point {
  private val grid = new Grid()
 
  def distanceBetweenPoints(x1: Double, y1: Double,
      x2: Double, y2: Double) = {
    val xDist = x1 - x2
    val yDist = y1 - y2
    math.sqrt(xDist*xDist + yDist*yDist)
  }
}

The above code shows some of the conceptual differences between Java and Scala's handling of classes:

  • Scala has no static variables or methods. Instead, it has singleton objects, which are essentially classes with only one object in the class. Singleton objects are declared using object instead of class. It is common to place static variables and methods in a singleton object with the same name as the class name, which is then known as a companion object. (The underlying class for the singleton object has a $ appended. Hence, for class Foo with companion object object Foo, under the hood there's a class Foo$ containing the companion object's code, and a single object of this class is created, using the singleton pattern.)
  • In place of constructor parameters, Scala has class parameters, which are placed on the class itself, similar to parameters to a function. When declared with a valor var modifier, fields are also defined with the same name, and automatically initialized from the class parameters. (Under the hood, external access to public fields always goes through accessor (getter) and mutator (setter) methods, which are automatically created. The accessor function has the same name as the field, which is why it's unnecessary in the above example to explicitly declare accessor methods.) Note that alternative constructors can also be declared, as in Java. Code that would go into the default constructor (other than initializing the member variables) goes directly at class level.
  • Default visibility in Scala is public.

Features (with reference to Java)[edit]

Scala has the same compilation model as Java and C#, namely separate compilation and dynamic class loading, so that Scala code can call Java libraries, or .NET libraries in the .NET implementation.

Scala's operational characteristics are the same as Java's. The Scala compiler generates byte code that is nearly identical to that generated by the Java compiler. In fact, Scala code can be decompiled to readable Java code, with the exception of certain constructor operations. To the JVM, Scala code and Java code are indistinguishable. The only difference is a single extra runtime library, scala-library.jar.[19]

Scala adds a large number of features compared with Java, and has some fundamental differences in its underlying model of expressions and types, which make the language theoretically cleaner and eliminate a number of "corner cases" in Java. From the Scala perspective, this is practically important because a number of additional features in Scala are also available in C#. Examples include:

Syntactic flexibility[edit]

As mentioned above, Scala has a good deal of syntactic flexibility, compared with Java. The following are some examples:

  • Semicolons are unnecessary; lines are automatically joined if they begin or end with a token that cannot normally come in this position, or if there are unclosed parentheses or brackets.
  • Any method can be used as an infix operator, e.g. "%d apples".format(num) and "%d apples" format num are equivalent. In fact, arithmetic operators like + and <<are treated just like any other methods, since function names are allowed to consist of sequences of arbitrary symbols (with a few exceptions made for things like parens, brackets and braces that must be handled specially); the only special treatment that such symbol-named methods undergo concerns the handling of precedence.
  • Methods apply and update have syntactic short forms. foo()—where foo is a value (singleton object or class instance)—is short for foo.apply(), and foo() = 42is short for foo.update(42). Similarly, foo(42) is short for foo.apply(42), and foo(4) = 2 is short for foo.update(4, 2). This is used for collection classes and extends to many other cases, such as STM cells.
  • Scala distinguishes between no-parens (def foo = 42) and empty-parens (def foo() = 42) methods. When calling an empty-parens method, the parentheses may be omitted, which is useful when calling into Java libraries which do not know this distinction, e.g., using foo.toString instead of foo.toString(). By convention a method should be defined with empty-parens when it performs side effects.
  • Method names ending in colon (:) expect the argument on the left-hand-side and the receiver on the right-hand-side. For example, the 4 :: 2 :: Nil is the same as Nil.::(2).::(4), the first form corresponding visually to the result (a list with first element 4 and second element 2).
  • Class body variables can be transparently implemented as separate getter and setter methods. For trait FooLike { var bar: Int }, an implementation may beobject Foo extends FooLike { private var x = 0; def bar = x; def bar_=(value: Int) { x = value }}. The call site will still be able to use a concisefoo.bar = 42.
  • The use of curly braces instead of parentheses is allowed in method calls. This allows pure library implementations of new control structures.[20] For example,breakable { ... if (...) break() ... } looks as if breakable was a language defined keyword, but really is just a method taking a thunk argument. Methods that take thunks or functions often place these in a second parameter list, allowing to mix parentheses and curly braces syntax: Vector.fill(4) { math.random } is the same as Vector.fill(4)(math.random). The curly braces variant allows the expression to span multiple lines.
  • For-expressions (explained further down) can accommodate any type that defines monadic methods such as mapflatMap and filter.

By themselves, these may seem like questionable choices, but collectively they serve the purpose of allowing domain-specific languages to be defined in Scala without needing to extend the compiler. For example, Erlang's special syntax for sending a message to an actor, i.e. actor ! message can be (and is) implemented in a Scala library without needing language extensions.

Unified type system[edit]

Java makes a sharp distinction between primitive types (e.g. int and boolean) and reference types (any class). Only reference types are part of the inheritance scheme, deriving from java.lang.Object. In Scala, however, all types inherit from a top-level class Any, whose immediate children are AnyVal (value types, such asInt and Boolean) and AnyRef (reference types, as in Java). This means that the Java distinction between primitive types and boxed types (e.g. int vs. Integer) is not present in Scala; boxing and unboxing is completely transparent to the user. Scala 2.10 allows for new value types to be defined by the user.

For-expressions[edit]

Instead of the Java "foreach" loops for looping through an iterator, Scala has a much more powerful concept of for-expressions. These are similar to list comprehensions in a languages such as Haskell, or a combination of list comprehensions and generator expressions in Python. For-expressions using the yieldkeyword allow a new collection to be generated by iterating over an existing one, returning a new collection of the same type. They are translated by the compiler into a series of mapflatMap and filter calls. Where yield is not used, the code approximates to an imperative-style loop, by translating to foreach.

A simple example is:

val s = for (x <- 1 to 25 if x*x > 50) yield 2*x

The result of running it is the following vector:

Vector(16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50)

(Note that the expression 1 to 25 is not special syntax. The method to is rather defined in the standard Scala library as an extension method on integers, using a technique known as implicit conversions[21] that allows new methods to be added to existing types.)

A more complex example of iterating over a map is:

// Given a map specifying Twitter users mentioned in a set of tweets,
// and number of times each user was mentioned, look up the users
// in a map of known politicians, and return a new map giving only the
// Democratic politicians (as objects, rather than strings).
val dem_mentions = for {
    (mention, times) <- mentions
    account          <- accounts.get(mention)
    if account.party == "Democratic"
  } yield (account, times)

Expression (mention, times) <- mentions is an example of pattern matching (see below). Iterating over a map returns a set of key-value tuples, and pattern-matching allows the tuples to easily be destructured into separate variables for the key and value. Similarly, the result of the comprehension also returns key-value tuples, which are automatically built back up into a map because the source object (from the variable mentions) is a map. Note that if mentions instead held a list, set, array or other collection of tuples, exactly the same code above would yield a new collection of the same type.

Functional tendencies[edit]

While supporting all of the object-oriented features available in Java (and in fact, augmenting them in various ways), Scala also provides a large number of capabilities that are normally found only in functional programming languages. Together, these features allow Scala programs to be written in an almost completely functional style, and also allow functional and object-oriented styles to be mixed.

Examples are:

Everything is an expression[edit]

Unlike C or Java, but similar to languages such as Lisp, Scala makes no distinction between statements and expressions. All statements are in fact expressions that evaluate to some value. Functions that would be declared as returning void in C or Java, and statements like while that logically do not return a value, are in Scala considered to return the type Unit, which is a singleton type, with only one object of that type. Functions and operators that never return at all (e.g. the throw operator or a function that always exits non-locally using an exception) logically have return type Nothing, a special type containing no objects that is a bottom type, i.e. a subclass of every possible type. (This in turn makes type Nothing compatible with every type, allowing type inference to function correctly.)

Similarly, an if-then-else "statement" is actually an expression, which produces a value, i.e. the result of evaluating one of the two branches. This means that such a block of code can be inserted wherever an expression is desired, obviating the need for a ternary operator in Scala:

// Java:
int hexDigit = x >= 10 ? x + 'A' - 10 : x + '0';
// Scala:
val hexDigit = if (x >= 10) x + 'A' - 10 else x + '0'

For similar reasons, return statements are unnecessary in Scala, and in fact are discouraged. As in Lisp, the last expression in a block of code is the value of that block of code, and if the block of code is the body of a function, it will be returned by the function.

Note that a special syntax exists for functions returning Unit, which emphasizes the similarity between such functions and Java void-returning functions:

def printValue(x: String) {
  println("I ate a %s".format(x))
}

However, the function may equally well be written with explicit return type:

def printValue(x: String): Unit = {
  println("I ate a %s".format(x))
}

or equivalently (with type inference, and omitting the unnecessary braces):

def printValue(x: String) = println("I ate a %s" format x)

Type inference[edit]

Due to type inference, the type of variables, function return values, and many other expressions can typically be omitted, as the compiler can deduce it. Examples areval x = "foo" (for an immutable, constant variable or immutable object) or var x = 1.5 (for a variable whose value can later be changed). Type inference in Scala is essentially local, in contrast to the more global Hindley-Milner algorithm used in HaskellML and other more purely functional languages. This is done to facilitate object-oriented programming. The result is that certain types still need to be declared (most notably, function parameters, and the return types of recursive functions), e.g.

def formatApples(x: Int) = "I ate %d apples".format(x)

or (with a return type declared for a recursive function)

def factorial(x: Int): Int =
  if (x == 0)
    1
  else
    x*factorial(x - 1)

Anonymous functions[edit]

In Scala, functions are objects, and a convenient syntax exists for specifying anonymous functions. An example is the expression x => x < 2, which specifies a function with a single parameter, that compares its argument to see if it is less than 2. It is equivalent to the Lisp form (lambda (x) (< x 2)). Note that neither the type of x nor the return type need be explicitly specified, and can generally be inferred by type inference; but they can be explicitly specified, e.g. as (x: Int) => x < 2 or even (x: Int) => (x < 2): Boolean.

Anonymous functions behave as true closures in that they automatically capture any variables that are lexically available in the environment of the enclosing function. Those variables will be available even after the enclosing function returns, and unlike in the case of Java's "anonymous inner classes" do not need to be declared as final. (It is even possible to modify such variables if they are mutable, and the modified value will be available the next time the anonymous function is called.)

An even shorter form of anonymous function uses placeholder variables: For example, the following:

list map { x => sqrt(x) }

can be written more concisely as

list map { sqrt(_) }

Immutability[edit]

Scala enforces a distinction between immutable (unmodifiable, read-only) variables, whose value cannot be changed once assigned, and mutable variables, which can be changed. A similar distinction is made between immutable and mutable objects. The distinction must be made when a variable is declared: Immutable variables are declared with val while mutable variables use var. Similarly, all of the collection objects (container types) in Scala, e.g. linked listsarrayssets andhash tables, are available in mutable and immutable variants, with the immutable variant considered the more basic and default implementation. The immutable variants are "persistent" data types in that they create a new object that encloses the old object and adds the new member(s); this is similar to how linked lists are built up in Lisp, where elements are prepended by creating a new "cons" cell with a pointer to the new element (the "head") and the old list (the "tail"). Persistent structures of this sort essentially remember the entire history of operations and allow for very easy concurrency — no locks are needed as no shared objects are ever modified.

Lazy (non-strict) evaluation[edit]

Evaluation is strict ("eager") by default. In other words, Scala evaluates expressions as soon as they are available, rather than as needed. However, you can declare a variable non-strict ("lazy") with the lazy keyword, meaning that the code to produce the variable's value will not be evaluated until the first time the variable is referenced. Non-strict collections of various types also exist (such as the type Stream, a non-strict linked list), and any collection can be made non-strict with theview method. Non-strict collections provide a good semantic fit to things like server-produced data, where the evaluation of the code to generate later elements of a list (that in turn triggers a request to a server, possibly located somewhere else on the web) only happens when the elements are actually needed.

Tail recursion[edit]

Functional programming languages commonly provide tail call optimization to allow for extensive use of recursion without stack overflow problems. Limitations in Java bytecode complicate tail call optimization on the JVM. In general, a function that calls itself with a tail call can be optimized, but mutually recursive functions cannot.Trampolines have been suggested as a workaround.[22] Trampoline support has been provided by the Scala library with the object scala.util.control.TailCallssince Scala 2.8.0 (released July 14, 2010).[23]

Case classes and pattern matching[edit]

Scala has built-in support for pattern matching, which can be thought of as a more sophisticated, extensible version of a switch statement, where arbitrary data types can be matched (rather than just simple types like integers, booleans and strings), including arbitrary nesting. A special type of class known as a case class is provided, which includes automatic support for pattern matching and can be used to model the algebraic data types used in many functional programming languages. (From the perspective of Scala, a case class is simply a normal class for which the compiler automatically adds certain behaviors that could also be provided manually—e.g. definitions of methods providing for deep comparisons and hashing, and destructuring a case class on its constructor parameters during pattern matching.)

An example of a definition of the quicksort algorithm using pattern matching is as follows:

def qsort(list: List[Int]): List[Int] = list match {
  case Nil => Nil
  case pivot :: tail =>
    val (smaller, rest) = tail.partition(_ < pivot)
    qsort(smaller) ::: pivot :: qsort(rest)
}

The idea here is that we partition a list into the elements less than a pivot and the elements not less, recursively sort each part, and paste the results together with the pivot in between. This uses the same divide-and-conquer strategy of mergesort and other fast sorting algorithms.

The match operator is used to do pattern matching on the object stored in list. Each case expression is tried in turn to see if it will match, and the first match determines the result. In this case, Nil only matches the literal object Nil, but pivot :: tail matches a non-empty list, and simultaneously destructures the list according to the pattern given. In this case, the associated code will have access to a local variable named pivot holding the head of the list, and another variabletail holding the tail of the list. Note that these variables are read-only, and are semantically very similar to variable bindings established using the let operator in Lisp and Scheme.

Pattern matching also happens in local variable declarations. In this case, the return value of the call to tail.partition is a tuple — in this case, two lists. (Tuples differ from other types of containers, e.g. lists, in that they are always of fixed size and the elements can be of differing types — although here they are both the same.) Pattern matching is the easiest way of fetching the two parts of the tuple.

The form _ < pivot is a declaration of an anonymous function with a placeholder variable; see the section above on anonymous functions.

The list operators :: (which adds an element onto the beginning of a list, similar to cons in Lisp and Scheme) and ::: (which appends two lists together, similar toappend in Lisp and Scheme) both appear. Despite appearances, there is nothing "built-in" about either of these operators. As specified above, any string of symbols can serve as function name, and a method applied to an object can be written "infix"-style without the period or parentheses. The line above as written:

qsort(smaller) ::: pivot :: qsort(rest)

could also be written as follows:

qsort(rest).::(pivot).:::(qsort(smaller))

in more standard method-call notation. (Methods that end with a colon are right-associative and bind to the object to the right.)

Partial functions[edit]

In the pattern-matching example above, the body of the match operator is a partial function, which consists of a series of case expressions, with the first matching expression prevailing, similar to the body of a switch statement. Partial functions are also used in the exception-handling portion of a try statement:

try {
  ...
} catch {
  case nfe:NumberFormatException => { println(nfe); List(0) }
  case _ => Nil
}

Finally, a partial function can be used by itself, and the result of calling it is equivalent to doing a match over it. For example, the previous code for quicksort can be written as follows:

val qsort: List[Int] => List[Int] = {
  case Nil => Nil
  case pivot :: tail =>
    val (smaller, rest) = tail.partition(_ < pivot)
    qsort(smaller) ::: pivot :: qsort(rest)
}

Here a read-only variable is declared whose type is a function from lists of integers to lists of integers, and bind it to a partial function. (Note that the single parameter of the partial function is never explicitly declared or named.) However, we can still call this variable exactly as if it were a normal function:

scala> qsort(List(6,2,5,9))
res32: List[Int] = List(2, 5, 6, 9)

Object-oriented extensions[edit]

Scala is a pure object-oriented language in the sense that every value is an objectData types and behaviors of objects are described by classes and traits. Class abstractions are extended by subclassing and by a flexible mixin-based composition mechanism to avoid the problems of multiple inheritance.

Traits are Scala's replacement for Java's interfaces. Interfaces in Java are highly restricted, able only to contain abstract function declarations. This has led to criticism that providing convenience methods in interfaces is awkward (the same methods must be reimplemented in every implementation), and extending a published interface in a backwards-compatible way is impossible. Traits are similar to mixin classes in that they have nearly all the power of a regular abstract class, lacking only class parameters (Scala's equivalent to Java's constructor parameters), since traits are always mixed in with a class. The super operator behaves specially in traits, allowing traits to be chained using composition in addition to inheritance. The following example is a simple window system:

abstract class Window {
  // abstract
  def draw()
}
 
class SimpleWindow extends Window {
  def draw() {
    println("in SimpleWindow")
    // draw a basic window
  }
}
 
trait WindowDecoration extends Window { }
 
trait HorizontalScrollbarDecoration extends WindowDecoration {
  // "abstract override" is needed here in order for "super()" to work because the parent
  // function is abstract. If it were concrete, regular "override" would be enough.
  abstract override def draw() {
    println("in HorizontalScrollbarDecoration")
    super.draw()
    // now draw a horizontal scrollbar
  }
}
 
trait VerticalScrollbarDecoration extends WindowDecoration {
  abstract override def draw() {
    println("in VerticalScrollbarDecoration")
    super.draw()
    // now draw a vertical scrollbar
  }
}
 
trait TitleDecoration extends WindowDecoration {
  abstract override def draw() {
    println("in TitleDecoration")
    super.draw()
    // now draw the title bar
  }
}

A variable may be declared as follows:

val mywin = new SimpleWindow with VerticalScrollbarDecoration with HorizontalScrollbarDecoration with TitleDecoration

The result of calling mywin.draw() is

in TitleDecoration
in HorizontalScrollbarDecoration
in VerticalScrollbarDecoration
in SimpleWindow

In other words, the call to draw first executed the code in TitleDecoration (the last trait mixed in), then (through the super() calls) threaded back through the other mixed-in traits and eventually to the code in Window itself, even though none of the traits inherited from one another. This is similar to the decorator pattern, but is more concise and less error-prone, as it doesn't require explicitly encapsulating the parent window, explicitly forwarding functions whose implementation isn't changed, or relying on run-time initialization of entity relationships. In other languages, a similar effect could be achieved at compile-time with a long linear chain of implementation inheritance, but with the disadvantage compared to Scala that one linear inheritance chain would have to be declared for each possible combination of the mix-ins.

Expressive type system[edit]

Scala is equipped with an expressive static type system that enforces the safe and coherent use of abstractions. In particular, the type system supports:

Scala is able to infer types by usage. This makes most static type declarations optional. Static types need not be explicitly declared unless a compiler error indicates the need. In practice, some static type declarations are included for the sake of code clarity.

Type enrichment[edit]

A common technique in Scala, known as "enrich my library" (formerly "pimp my library",[21] now discouraged due to its connotation), allows new methods to be used as if they were added to existing types. This is similar to the C# concept of extension methods but more powerful, because the technique is not limited to adding methods and can for instance also be used to implement new interfaces. In Scala, this technique involves declaring an implicit conversion from the type "receiving" the method to a new type (typically, a class) that wraps the original type and provides the additional method. If a method cannot be found for a given type, the compiler automatically searches for any applicable implicit conversions to types that provide the method in question.

This technique allows new methods to be added to an existing class using an add-on library such that only code that imports the add-on library gets the new functionality, and all other code is unaffected.

The following example shows the enrichment of type Int with methods isEven and isOdd:

object MyExtensions {
  implicit class IntPredicates(i: Int) {
    def isEven = i % 2 == 0
    def isOdd  = !isEven
  }
}
 
import MyExtensions._  // bring implicit enrichment into scope
4.isEven  // -> true

Importing the members of MyExtensions brings the implicit conversion to extension class IntPredicates into scope.[24]

Concurrency[edit]

Scala standard library includes support for the actor model, in addition to the standard Java concurrency APIs. The company called Typesafe provides a stack[25] that includes Akka,[26] a separate open source framework that provides actor-based concurrency. Akka actors may be distributed or combined with software transactional memory ("transactors"). Alternative CSP implementations for channel-based message passing are Communicating Scala Objects,[27] or simply via JCSP.

An Actor is like a thread instance with a mailbox. It can be created by system.actorOf, overriding the receive method to receive messages and using the !(exclamation point) method to send a message.[28] The following example shows an EchoServer which can receive messages and then print them.

val echoServer = actor(new Act {
  become {
    case msg => println("echo " + msg)
  }
})
echoServer ! "hi"

Scala also comes with built-in support for data-parallel programming in the form of Parallel Collections [29] integrated into its Standard Library since version 2.9.0.

The following example shows how to use Parallel Collections to improve performance.[30]

val urls = List("http://scala-lang.org",  "https://github.com/scala/scala")
 
def fromURL(url: String) = scala.io.Source.fromURL(url)
  .getLines().mkString("\n")
 
val t = System.currentTimeMillis()
urls.par.map(fromURL(_))
println("time: " + (System.currentTimeMillis - t) + "ms")

Cluster Computing[edit]

Two significant cluster computing solutions are based on Scala: the open source Apache Spark and the commercial GridGain. Additionally, Apache Kafka, thepublish-subscribe message queue popular with Spark and other stream processing technologies, is written in Scala.

Testing[edit]

There are several ways to test code in Scala:

  • ScalaTest supports multiple testing styles and can integrate with Java-based testing frameworks
  • ScalaCheck, a library similar to Haskell's QuickCheck
  • specs2, a library for writing executable software specifications
  • ScalaMock provides support for testing high-order and curried functions
  • JUnit or TestNG, two popular testing frameworks written in Java

Versions[edit]

VersionReleasedFeaturesStatusNotes
2.012-Mar-2006___
2.1.823-Aug-2006___
2.3.023-Nov-2006___
2.4.009-Mar-2007___
2.5.002-May-2007___
2.6.027-Jul-2007___
2.7.007-Feb-2008___
2.8.014-Jul-2010Revision the common, uniform, and all-encompassing framework for collection types.__
2.9.012-May-2011___
2.1004-Jan-2013
  • Value Classes
  • Implicit Classes
  • String Interpolation
  • Futures and Promises
  • Dynamic and applyDynamic
  • Dependent method types: * def identity(x: AnyRef): x.type = x // the return type says we return exactly what we got
  • New ByteCode emitter based on ASM: Can target JDK 1.5, 1.6 and 1.7 / Emits 1.6 bytecode by default / Old 1.5 backend is deprecated
  • A new Pattern Matcher: rewritten from scratch to generate more robust code (no more exponential blow-up!) / code generation and analyses are now independent (the latter can be turned off with -Xno-patmat-analysis)
  • Scaladoc Improvements
  • Implicits (-implicits flag)
  • Diagrams (-diagrams flag, requires graphviz)
  • Groups (-groups)
  • Modularized Language features
  • Parallel Collections are now configurable with custom thread pools
  • Akka Actors now part of the distribution\\scala.actors have been deprecated and the akka implementation is now included in the distribution.
  • Performance Improvements: Faster inliner / Range#sum is now O(1)
  • Update of ForkJoin library
  • Fixes in immutable TreeSet/TreeMap
  • Improvements to PartialFunctions
  • Addition of ??? and NotImplementedError
  • Addition of IsTraversableOnce + IsTraversableLike type classes for extension methods
  • Deprecations and cleanup
  • Floating point and octal literal syntax deprecation
  • Removed scala.dbc

Experimental features

__
2.10.206-Jun-2013___
2.10.301-Oct-2013_Current_
2.11.0-M411-Jul-2013__Milestone 4 pre-release

Comparison with other JVM languages[edit]

Scala is often compared with Groovy and Clojure, two other programming languages also using the JVM. Among the main differences are:

  1. Scala is statically typed, while both Groovy and Clojure are dynamically typed. This adds complexity in the type system but allows many errors to be caught at compile time that would otherwise only manifest at runtime, and tends to result in significantly faster execution. (Note, however, that current versions of both Groovy and Clojure allow for optional type annotations, and Java 7 adds an "invoke dynamic" byte code that should aid in the execution of dynamic languages on the JVM. Both features should decrease the running time of Groovy and Clojure.)
  2. Compared with Groovy, Scala diverges more from Java in its fundamental design. The primary purpose of Groovy was to make Java programming easier and less verbose, while Scala (in addition to having the same goal) was designed from the ground up to allow for a functional programming style in addition toobject-oriented programming, and introduces a number of more "cutting-edge" features from functional programming languages like Haskell that are not often seen in mainstream languages.
  3. Compared with Clojure, Scala is less of an extreme transition for a Java programmer. Clojure inherits from Lisp, with the result that it has a radically different syntax from Java and has a strong emphasis on functional programming while de-emphasizing object-oriented programming. Scala, on the other hand, maintains most of Java's syntax and attempts to be agnostic between object-oriented and functional programming styles, allowing either or both according to the programmer's taste.


Posted by 1010
반응형

This jQuery plugin converts a properly formatted table, having thead and tbody elements (tfoot optional), into a scrollable table. Scrollable tables are most useful when having to display lots of tubular data in a fixed space.

Show Me The Money (Demo)

citystate codeziplatitudelongitudecounty
HoltsvilleNY0050140.8152-73.0455Suffolk
HoltsvilleNY0054440.8152-73.0455Suffolk
AdjuntasPR0060118.1788-66.7516Adjuntas
AguadaPR0060218.381389-67.188611Aguada
AguadillaPR0060318.4554-67.1308Aguadilla
AguadillaPR0060418.4812-67.1467Aguadilla
AguadillaPR0060518.429444-67.154444Aguadilla
MaricaoPR0060618.182778-66.980278Maricao
AnascoPR0061018.284722-67.14Anasco
AngelesPR0061118.286944-66.799722Utuado
AreciboPR0061218.4389-66.6924Arecibo
AreciboPR0061318.1399-66.6344Arecibo
AreciboPR0061418.1399-66.6344Arecibo
BajaderoPR0061618.428611-66.683611Arecibo
BarcelonetaPR0061718.4525-66.538889Barceloneta
10215--9

Table Scroll Plugin Overview

The tablescroll jQuery plugin is a simple markup manipulation plugin, it will manipulate the table, create a couple of new elements and wrap everything in a DIV.

Using the plugin is pretty straight forward, when you download the plugin you can view the demo file to get up to speed and begin working with it immediately.

The HTML TABLE markup is also pretty basic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<table id="thetable" cellspacing="0">
<thead>
    <tr>
      <td>city</td>
      <td>state code</td>
      <td>zip</td>
      <td>latitude</td>
      <td>longitude</td>
      <td>county</td>
    </tr>
</thead>
<tfoot>
    <tr>
      <td>city</td>
      <td>state code</td>
      <td>zip</td>
      <td>latitude</td>
      <td>longitude</td>
      <td>county</td>
    </tr>
</tfoot>
<tbody>
    <tr class="first">
      <td>Holtsville</td>
      <td>NY</td>
      <td>00501</td>
      <td>40.8152</td>
      <td>-73.0455</td>
      <td>Suffolk</td>
    </tr>
    <tr>
      <td>Holtsville</td>
      <td>NY</td>
      <td>00544</td>
      <td>40.8152</td>
      <td>-73.0455</td>
      <td>Suffolk</td>
    </tr>
    <tr>
      <td>Adjuntas</td>
      <td>PR</td>
      <td>00601</td>
      <td>18.1788</td>
      <td>-66.7516</td>
      <td>Adjuntas</td>
    </tr>
</tbody>
</table>

Styling the table should go pretty smoothly, but be warned, the plugin does some width/height calculations which require the styles to be in place prior to doing the calculations.

Here is the demo CSS which should get you started:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.tablescroll {
    font: 12px normal Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif;
}
 
.tablescroll td,
.tablescroll_wrapper,
.tablescroll_head,
.tablescroll_foot {
    border:1px solid #ccc;
}
 
.tablescroll td {
    padding:3px 5px;
    border-bottom:0;
    border-right:0;
}
 
.tablescroll_wrapper {
    background-color:#fff;
    border-left:0;
}
 
.tablescroll_head,
.tablescroll_foot {
    background-color:#eee;
    border-left:0;
    border-top:0;
    font-size:11px;
    font-weight:bold;
}
 
.tablescroll_head {
    margin-bottom:3px;
}
 
.tablescroll_foot {
    margin-top:3px;
}
 
.tablescroll tbody tr.first td {
    border-top:0;
}

The plugin is basic and only has a few options:

1
2
3
4
5
6
7
$.fn.tableScroll.defaults =
{
    flush: true, // makes the last thead and tbody column flush with the scrollbar
    width: null, // width of the table (head, body and foot), null defaults to the tables natural width
    height: 100, // height of the scrollable area
    containerClass: 'tablescroll' // the plugin wraps the table in a div with this css class
};

Like most jQuery plugins, implementation is a snap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
jQuery(document).ready(function($)
{
    $('#thetable').tableScroll({height:200});
 
    // other examples
 
    // sets the table to have a scrollable area of 200px
    $('#thetable').tableScroll({height:200});
 
    // sets a hard width limit for the table, setting this too small
    // may not always work
    $('#thetable').tableScroll({width:400});
 
    // by default the plugin will wrap everything in a div with this
    // css class, if it finds that you have manually wrapped the
    // table with a custom element using this same css class it
    // will forgo creating a container DIV element
    $('#thetable').tableScroll({containerClass:'myCustomClass'});
});

Like many projects, we developers build out of necessity. I couldn’t quite find what I needed, so i wrote my own! This plugin accomplished all of what I needed, and I thought it useful enough that I would share. If you have any feature requests and/or bug reports please let me know. And the plugin name is pretty generic too (if you have a better one, feel free to drop me a line).

I’ve tested the plugin on Windows with Chrome, FF 3.6, IE 6, IE 8, Safari 4. If anyone is on a Mac, please let me know what your results are?

Download

jQuery TableScroll plugin, this project is on github

Posted by 1010