And you thought the App trait is just a convenient way of creating an executable Scala program


Ok,  Let’s start discussion about the App trait uses in our code segment. Here I will try to demonstrate some use cases for the better use of App trait in our Scala code. To read more about the App trait you can refer to the documentation here

Let’s go with our daily uses of App trait 🙂

Just want to print something on console:

object MainApp extends App { 
  println("Hello Scala!")
}

In the code above, we are inheriting the main method of App. We can do this also to print the same:

object MainApp {

  def main(args: Array[String]): Unit = {
    println("Hello Scala!");
  }

}

Output for the both : Hello Scala!

Now let’s try in advance way:

/**
 * The `MainApp` object can be used to quickly add the executable code
 *
 * @author anand
 *
 */
object MainApp extends App {

  override def delayedInit(body: => Unit) = {
    print("Welcome to SCALA ")
    body
  }
 
  println("world!")

}

What do you think is going to be the output of this code block? If you answered
world! you are not correct. Because the output is Welcome to SCALA world!

Nothing special in above code block. I have just overridden the delayedInit method of DelayedInit marker trait. This method is normally never called directly from user code. Instead it is called as compiler-generated code for those classes and objects (but not traits) that inherit from the `DelayedInit` trait and that do not themselves define a `delayedInit` method.

Let us look at a good case of using DelayedInit marker trait with App trait. We want to execute a list of the methods before the object MainApp executable block.

package com.knoldus.helper

/**
 * @author anand
 *
 */
trait Helper extends DelayedInit {

  val x: Int = 10
  val y: Int = 5

  def addition(x: Int, y: Int): Unit
  def subtraction(x: Int, y: Int): Unit
  def multiplication(x: Int, y: Int): Unit
  def division(x: Int, y: Int): Unit

  override def delayedInit(body: => Unit) = {
    addition(x, y)
    subtraction(x, y)
    multiplication(x, y)
    division(x, y)
    body
  }

}
package com.knoldus.main

import com.knoldus.helper.Helper

/**
 * The `MainApp` object can be used to quickly add the executable code
 *
 * @author anand
 *
 */
object MainApp extends App with Helper {

  /**
   * This is used to calculate sum of two number
   *
   * @param x
   * @param y
   */
  def addition(x: Int, y: Int): Unit = {
    println(s"$x + $y = ${x + y}")
  }

  /**
   * This is used to subtract second number from first number
   *
   * @param x
   * @param y
   */
  def subtraction(x: Int, y: Int): Unit = {
    println(s"$x - $y = ${x - y}")
  }

  /**
   * This is used to calculate multiplication of two number
   *
   * @param x
   * @param y
   */
  def multiplication(x: Int, y: Int): Unit = {
    println(s"$x * $y = ${x * y}")
  }

  /**
   * This is used to divide first number with second number
   *
   * @param x
   * @param y
   */
  def division(x: Int, y: Int): Unit = {
    println(s"$x / $y = ${x / y}")
  }

  println("WOW: All methods have been executed successfully!")

}
Output:
10 + 5 = 15
10 - 5 = 5
10 * 5 = 50
10 / 5 = 2
WOW: All methods have been executed successfully!

Why it’s happening?

The initialization code of an object or class (but not a trait) that follows the superclass constructor invocation and the mixin-evaluation of the template’s base classes is passed to a special hook, which is inaccessible from user code. Normally, that hook simply executes the code that is passed to it. But templates inheriting the scala.DelayedInit trait can override the hook by re-implementing the delayedInit method. So all this involves a bit of magic. The App trait extends another trait, DelayedInit, that gets special handling from the compiler. All initialization code of a class with that trait is moved into delayedInit method. The main of the App trait method captures the command line arguments, calls the overridden delayedInit method, and executes the our code block.

Note: In Future versions of App trait will no longer extend DelayedInit. Scala will introduce OnCreate trait: call onCreate method after object creation with DelayedInit

Advertisements

About Anand Kumar Singh

Hi, I’m Anand Singh and I specialize in Computer Software. I’m passionate about what I do, and I love to help people. Nothing is more fulfilling than being part of a team with similar interests, and an organization that values its employees. I'm Lead Software Engineer at Sapient. Having 5+ years of experience in Java, Grails/Groovy and Scala language. Anand also knows about Javascript, jQuery, CSS and other UI design technologies. Certified developer in: * Principles of Reactive Programming – Coursera * Functional Programming Principles in Scala – Coursera * Functional Program Design in Scala – Coursera * Introduction to Big Data with Apache Spark – edX * Oracle Certified Associate (OCA) * Sun Certified Java Programmer (SCJP) I'm passionate to work with upcoming technologies and bleeding platforms providing the new way to programming & development. He is actively involved in development & maintenance of several software projects. He has been enjoying Scala for more than a year now. Anand completed his MCA from IGNOU. As a Developer, I'm continuing my journey by actively collaborating with other Developers in my field. I'm actively contributing on the TechMonad & Playing Scala platform. I likes to spend his free time in Cooking, watching Discovery for new Technology and visiting new places with friends.
This entry was posted in Scala and tagged , , , , . Bookmark the permalink.

One Response to And you thought the App trait is just a convenient way of creating an executable Scala program

  1. Reblogged this on Play!ng with Scala and commented:

    Scala App trait with DelayedInit.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s