Daniel
Daniel

Reputation: 6039

Scala looping over a java function

I have the following Scala code in my program:

val parser = new PlainToTokenParser(...)
for {
  word: Word <- parser.next()
  if word == null
} {
  print(word)
}

where PlainToTokenParser is a java class in another library:

public class PlainToTokenParser implements Parser {

    public PlainToTokenParser(Parser p) {
        this.parser = p;
    }

    public Object next() {
       // some work here and return an output
    }
}

when compiling my scala code I get the following error:

... value filter is not a member of Object
[error]     for{ word: Word <- parser.next()
[error]  

Any idea where I am going wrong?

Upvotes: 1

Views: 83

Answers (2)

Daniel Darabos
Daniel Darabos

Reputation: 27455

The for-loop iterates over an object. You want to iterate over the Words returned by parser. But your code actually takes the first Word and tries to iterate over that. (Also a problem is that next returns an Object while your variable is of type Word.)

Scala compiles a for-loop into a series of method calls. The spec says it will translate into map, withFilter, flatMap, and foreach. The object you want to iterate over must have (at least some of) these methods for the for-loop to work. Looks like for some reason it's actually trying to call filter on the Object returned by parser.next().

(See Zeng's answer for a solution. I thought an explanation would be useful too.)

Upvotes: 1

Zang MingJie
Zang MingJie

Reputation: 5275

Because PlainToTokenParser is not a scala iterator, you must create a scala iterator to use for loop.

val parser = new PlainToTokenParser(...)
for {
  word <- Iterator.continually(parser.next).takeWhile(_ != null) // Assume null is the end
} {
  print(word)
}

BTW: you can loop through java Array/Map because scala implicit create an iterator.

Upvotes: 6

Related Questions