user1893354
user1893354

Reputation: 5938

Scala Apply Method in companion object

I have created a companion object for my Scala class with an apply method in it so that I can create an instance of my class without using 'new'.

object StanfordTokenizer{
  def apply() = new StanfordTokenizer()
}

class StanfordTokenizer() extends Tokenizer{


  def tokenizeFile(docFile: java.io.File) = new PTBTokenizer(new FileReader(docFile), new CoreLabelTokenFactory(), "").tokenize.map(x => x.word().toLowerCase).toList

  def tokenizeString(str: String) = new PTBTokenizer(new StringReader(str), new CoreLabelTokenFactory(), "").tokenize.map(x => x.word.toLowerCase()).toList

}

However when I try to instantiate the StanfordTokenizer class without 'new' e.g. StandfordTokenizer.tokenizeString(str).

I get the error

value tokenizeString is not a member of object StanfordTokenizer

However, if I explicitly include the apply method like StandfordTokenizer.apply().tokenizeString(str) it does work.

I feel like I am missing something fundamental about companion objects. Can someone shed some light on this for me? ^

Upvotes: 0

Views: 503

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

It's exactly as the compiler message says. tokenizeString is a member of the class StandfordTokenizer, but not its companion object. The companion object does not inherit any methods from the class. Therefore, in order to use tokenizeString, you need an instance of StandfordTokenizer in order to call it.

StandfordTokenizer.apply creates an instance of the class StandfordTokenizer, which has the method tokenizeString. It seems as though the class StandfordTokenizer holds no real information, and won't have more than one instance. If that is true, you should probably just make it an object, and you'll be able to acquire the behavior you're looking for.

object StanfordTokenizer extends Tokenizer {

    def tokenizeFile(docFile: java.io.File) = ...

    def tokenizeString(str: String) = ...

}

This should work as well (as a class):

StandfordTokenizer().tokenizeString(str)

StandfordTokenizer without parenthesis does not call apply, it references the object. StandfordTokenizer() does call apply, and creates a new instance of the class. This is probably the source of your confusion.

Upvotes: 4

Related Questions