Book Image

Professional Scala

By : Mads Hartmann, Ruslan Shevchenko
Book Image

Professional Scala

By: Mads Hartmann, Ruslan Shevchenko

Overview of this book

This book teaches you how to build and contribute to Scala programs, recognizing common patterns and techniques used with the language. You’ll learn how to write concise, functional code with Scala. After an introduction to core concepts, syntax, and writing example applications with scalac, you’ll learn about the Scala Collections API and how the language handles type safety via static types out-of-the-box. You’ll then learn about advanced functional programming patterns, and how you can write your own Domain Specific Languages (DSLs). By the end of the book, you’ll be equipped with the skills you need to successfully build smart, efficient applications in Scala that can be compiled to the JVM.
Table of Contents (12 chapters)

Structure of a Scala Project


Let's look at our chatbot program in a complete runnable project. Let's navigate to the /day1-lesson1/1-project directory in our code supplement.

Note

The code is available on Github at the following link: https://github.com/TrainingByPackt/Professional-Scala

The preceding diagram is the typical directory structure of a Scala project. If you are familiar with the Java tools ecosystem, then you will notice the similarities between the maven project layout.

In src, we can see project sources ( main and test). target is a place where output artifacts are created, whereas project is used as a place to internally build the project. We will cover all of these concepts later on.

organization := "com.packt.courseware"name := "chatbot1"version := "0.1-SNAPSHOT"
scalaVersion := "2.12.4"

The head of any project is its build.sbt file. It consists of the following code:

The text inside it is a plain Scala snippet.

organization, name, and version are instances of sbt.key. For this point of view, := is a binary operator defined on keys. In Scala, any method with two arguments can be used with the syntax of a binary operator. := is a valid method name.

build.sbt is interpreted by the sbt tool.

Note

sbt – The original intention for the name, when sbt was created by Mark Harrah, was ' Simple Build Tool'. Later on, the author decided to avoid such a decipherment, and kept it as it was. You can read about the details of sbt here: https://www.scala-sbt.org/1.x/docs/index.html.

Basic sbt Commands

We will now talk about the basic sbt commands.

sbt compile should compile the project and live somewhere in its target compiled Java classes.

sbt run executes the main function of the project. Therefore, we can try to interact with our chatbot:

rssh3:1-project rssh$ sbt run
[info] Loading global plugins from /Users/rssh/.sbt/0.13/plugins
[info] Set current project to chatbot1 (in build file:/Users/rssh/work/packt/professional-scala/Lesson 1/1-project/)
[info] Running com.packt.courseware.Chatbot1
Hi! What is your name? Jon
  Jon, tell me something interesting, say 'bye' to end the talk
>qqq
interesting..
>ddd
interesting...
>bye
ok, bye
 [success] Total time: 19 s, completed Dec 1, 2017 7:18:42 AM

The output of the code is as follows:

sbt package prepares an output artifact. After running it, it will create file called target/chatbot1_2.12-0.1-SNAPSHOT.jar.

chatbot1 is the name of our project; 0.1-SNAPSHOT – version. 2.12 is the version of the Scala compiler.

Scala guarantees binary compatibility only within the scope of a minor version. If, for some reason, the project still uses scala-2.11, then it must use the library, which was created for scala-2.11. On the other hand, updating to the next compiler version can be a long process for projects with many dependencies. To allow the same library to exist in the repository with different scalaVersions, we need to have an appropriate suffix in the jar file.

sbt publish-local – publishes the artifact on to your local repository.

Now let's see our sample project and sbt tool.

Activity: Performing Basic Operations with sbt: Build, Run, Package

  1. Install sbt on your computer, if not installed beforehand.

  2. Start the sbt console by typing sbt console in the root directory of the 1-project (where build.sbt is situated).

  3. Compile the code by typing the compile command into the sbt console.

  4. Run the program by typing the sbt run command into the sbt console.

  5. When running this, say bye to the bot and return to the console.

  6. Package the program by typing package into the sbt console.

IDE

Another part of the developer toolbox is an IDE tool (Integrated Development Environment). For our book, we will use Intellij IDEA community edition with the Scala plugin. This is not the only option: other alternatives are scala-ide, based on IBM Eclipse and Ensime (http://ensime.github.io/), which brings IDE features to any programmable text editors, from vi to emacs.

All tools support importing the project layout from build.sbt.

Activity: Loading and Running a Sample Project in the IDE

  1. Import our project:

    • Go to File -> Import -> navigate to build.sbt

  2. Open the program in IDE:

    • Start IDEA

    • Press Open

    • Select day1-lesson1/1-project/build.sbt

  3. In the dialog window, which asks whether to open it as a file or as a project, select project.

  4. On the left part of the project's structure, unfold src entry.

  5. Click on main.

  6. Ensure that you can see main, as specified in the code.

  7. Ensure that project can be compiled and run via the sbt console.

For running our project from the IDE, we should edit the project's configuration (Menu: Build/ Edit configuration or Run/ Edit configuration, depending on which version of IDEA you are using).

Running the Project from IDE:

  1. Select Run/ Edit Configuration.

  2. Select Application.

  3. Set the application's name. In our case, use Chatbot1.

  4. Set the name of the Main class. In our case, it must be com.packt.courseware.Chatbot1.

  5. Actually run the application: select Run, then Chatbot1 from the dropdown menu.

REPL

Another tool that we will frequently use is REPL (Read Eval Print Loop). It is often used for quickly evaluating Scala expressions.

From sbt, we can enter REPL mode with the help of the sbt console command. Let's try some simple expressions.

Now, we'll look at how to evaluate expressions. Follow these steps to do so:

  1. Open the sbt tool.

  2. Open REPL by typing the following command:

    sbt console
  3. Type the following expressions and press Enter:

    • 2 + 2

    • "2" + 2

    • 2 + "2"

    • (1 to 8).sum

    • java.time.LocalTime.now()

Please note that we can have an interactive Scala playboard inside IDE by creating a special file type: a Scala Worksheet. It's useful, but is mainly for demonstration purposes.

Obtaining the Time Request from Our Chatbot Program

For now, let's return to our task: modifying the chatbot program so that it replies with the current time, as requested by the use of time. Let's learn how to do this:

Steps for C ompletion

  1. Check for time to match the statement:

    case "time" =>
  2. Retrieve the current time using the Java API. Use the now method of java.time.LocalTime:

         java.time.LocalTime.now()
  3. Display the output of the time using string interpolators, as follows:

    println("time is ${java.time.LocalTime.now()}")

The main method will look like this:

def main(args: Array[String]): Unit = {
val name = StdIn.readLine("Hi! What is your name?")
println(s" $name, tell me something interesting, say 'bay' to end the talk")
var timeToBye = false
while (!timeToBye)timeToBye = StdIn.readLine(">") 
match {case "bye" => println("ok, bye")truecase "time" => 
println(s"time is ${java.time.LocalTime.now()}")truecase _ => 
println("interesting...")false}
}

After we prepare and package our artifacts, we need to run them as well.

In this book, we will use the running system from unpackaged sources via sbt (as in the early days of Ruby applications), assuming that sources and sbt tools are accessible from the production environment. Using this, we can use build tool commands for sources such as sbt run. In real life, packaging for production is a bit more complex.

Popular methods for doing this are as follows:

  • Preparing a fat jar (which includes all dependencies). An sbt plugin for this exists, which can be found at the following link: https://github.com/sbt/sbt-assembly.

  • Preparing a native system package (which includes jars, dependencies, custom layouts, and so on). There is also an sbt plugin to create native system packages, which can be found at the following link: https://github.com/sbt/sbt-native-packager.