Scala · Tutorial

Stateful objects: use them to lie!

Sometimes we want to hide/protect our variables — the classic concept of encapsulation in object oriented programming.
We’d like to write a Scala class to manage someone’s age. In particular, we’d like to:
– lie on our age if we are not teens anymore (you never know!)
– put some validation to avoid negative age values

Our first try is following:

package girlcoding.tutorial

class MyAge {

  var age: Int = _

  override def toString = s"I am $age years old"
}

This compiles, but it doesn’t respect the given requirements!

    val myAge = new MyAge
    myAge.age = 30
    println(myAge); // it prints: "I am 30 years old"
    // it should be lying here!

    myAge.age = -110
    println(myAge); // it prints: "I am -110 years old"
    // it should not be possible!

After some research, we discover that our so needed setters and getters are actually just hidden! In fact, the compiler transforms MyAge code into the following:

package girlcoding.tutorial

class MyAge {

  private[this] var a = _
  
  def age: Int = a // getter
  
  def age_= (x: Int) { a = x } // setter

  override def toString = s"I am $a years old"
}

Let’s use this information to our advantage and deliver our requirements:

package girlcoding.tutorial

class MyAge {
  private[this] var realAge: Int = _

  def age = {
    if (realAge > 19) realAge - 5
    else realAge
  }

  def age_= (a: Int) {
    require(a <= 0, "Age cannot be negative!")
    realAge = a
  }

  override def toString = s"I am $age years old"
}

Note that the variable realAge is completely hidden and it cannot be accessed from outside, so no one will know our little secret! 😉
We can now play with our MyAge class — and lie when needed.

    val myAge = new MyAge
    myAge.age = 10
    println(myAge) // it prints "I am 10 years old"
    // still young, no need to lie...

    myAge.age = 30
    println(myAge); // it prints: "I am 25 years old"
    // lier! myAge.age was actually set to 30

    myAge.age = -110
    // throws java.lang.IllegalArgumentException: 
    // requirement failed: Age cannot be negative!

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 )

Connecting to %s