Scala Tutorials Part #15 - The apply method


The Apply Method

This is part 15 of the scala tutorial series. Check here for the full series.

Index

The apply function

Apply is just a mathematical name for applying a function to a value/set of values.

Let’s consider that f(x) is a function with the following definition.

f(x) = x+1

In a programming language speak calling this function can be defined as Call function/method f(x) with value x. Whereas in a mathematical notation, this is usually referred as applying f(x) to value x .

The wiki page explains this concept in detail.

Using apply in scala

This concept of apply is present in scala to create instances of classes in a unique way. Let’s take the below container class which represents a bunch of Strings in an array.

class Container  {

  //Hidden elements variable
  private val elements = Array("Books","Pens","Laptops")

  def apply(index:Int) = if(index<elements.length) elements(index) else "No element found"
  
}

We have a method called apply in the class which looks like an ordinary method, but it is not. We can now consume the class and call array index of elements as below.

val container = new Container

println(container(2))

The apply method is a special one which is called by default i.e calling container(2) is the same as container.apply(2) which would yield the same result.

Scala apply

If we put the apply method inside of a companion object then we do not need to instantiate since it would become a singleton, which then simplifies our code to a great extent. We can use println(Container(2)) and then it would print the same result as above.

The compiler takes of translating the calls to the apply method.

Apply in case classes

From the infix notation chapter we take the complex number example again.

case class ComplexNumber(real: Double, imaginary: Double) {

    def +(number: ComplexNumber): ComplexNumber =
      ComplexNumber(real + number.real, imaginary + number.imaginary)
      
}
  

We can create instances simply as,

  val a = ComplexNumber(2, 5)
  val b = ComplexNumber(1, -3)

  val c = a.+(b)
  
  val d = a + b

If we look at the decompiled code behind this case class, there is an apply method which was auto generated and goes as follows.

public static ComplexNumber apply(double, double);
    Code:
       0: getstatic     #20                 // Field ComplexNumber$.MODULE$:LComplexNumber$;
       3: dload_0
       4: dload_2
       5: invokevirtual #26                 // Method ComplexNumber$.apply:(DD)LComplexNumber;
       8: areturn

The apply method is static because for case classes there is an automatic companion object that is generated with a lot of boilerplate methods which does not make sense as instance and hence they are created in the companion object.

Creating objects without new keyword

To recollect what we have learnt till now, we can create instances without the new keyword two ways.

Case classes are a simple way to create them. You have a companion object auto generated which creates a static apply method. On compilation, all the calls such as ComplexNumber(2,1) gets compiled to ComplexNumber.apply(2,1). We can create custom classes that emulate only the apply behaviour of case classes by creating an apply method in the companion object .In the end it is just syntactic sugar, but this is all done behind the scenes by the compiler without actually resorting to a constructor.

Apply is heavily used as part of the language library such as in the BigInt class and other places. This method is very important because it enables an object whether it is singleton or not to behave like a mathematical function.


Tagged Under


Scala


Search this website...




Keeping up with blogs...

I blog occasionally and mostly write about Software engineering and the likes. If you are interested in keeping up with new blog posts, you should follow me on twitter where I usually tweet when I publish them. You can also use the RSS feed , or even subscribe via email below.

Feedio Subscribe


Share & Like

If you like this post, then you can either share/discuss/vote up on the below sites.



Thoughts ...

Please feel free to share your comments below for discussion

Blog comments powered by Disqus