How to add some action in constructor?

greenoldman picture greenoldman · Oct 12, 2011 · Viewed 7.1k times · Source

Naive question I believe, but all I find is just calling other constructors from constructors. I need to call a method. My class (beginning):

class ScopedIterator[T](val iter : Iterator[T])
{
  private var had_next : Boolean;
  private var value : T;

  moveNext();
  
  ...

so I would like to have a constructor with single argument, and in such constructor call a method moveNext. That's all.

When I compile the code I get error:

error: abstract member may not have private modifier

private var had_next : Boolean;

and the same for value.

I changed it to:

class ScopedIterator[T]
{
  private var had_next : Boolean;
  private var value : T;
  private var iter : Iterator[T];

  def this(it : Iterator[T]) =
  {
    iter = it;
    moveNext();
  }

  ...

But now I get error on "iter=it":

error: 'this' expected but identifier found.

iter = it;

How to write such constructor in Scala?

Answer

Philippe picture Philippe · Oct 12, 2011

The first problem is that your definitions of had_next and value are abstract: these members have no right-hand side.

Try instead:

class ScopedIterator[T](val iter : Iterator[T]) {
  private var had_next : Boolean = _
  private var value : T = _
  ...
}

Here, _ means "default uninitialized value". For example, the following works for me in the console:

class ScopedIterator[T](val iter : Iterator[T]) {
  private var had_next : Boolean = _
  private var value : T = _

  init()

  def init() : Unit = { println("init !") }
}

scala> new ScopedIterator(List(1,2,3).toIterator)
init !
resN: ScopedIterator[Int] = ...

The second problem ("'this' expected...") comes because in Scala, auxiliary constructors must always call another constructor as their first statement. So your constructor could start with this(), for instance. For more details, see Section 6.7 in Programming in Scala.