Why is there an empty string after the process (aString)! in scala?
When I start the external process it looks like we need to add a blank line after the call. Why is this causing this error?
class JobActor extends Actor {
def receive = {
case msg:String =>
Process(msg)!
// here need a blank line, otherwise it throws error
sender ! "complete"
}
}
mistake
[error] found : akka.actor.ActorRef
[error] required: scala.sys.process.ProcessLogger
[error] sender ! "complete"
[error] ^
[error] one error found
source to share
You've hit the exact reason why postfix statements are a function that generates a warning when compiled with a flag -feature
.
Here's an excerpt explaining why such a feature is still being discussed (emphasis added):
postfixOps. Only when enabled will the postfix statement (expr op) be allowed. Why store this function? Several DSLs written in Scala need notation. Why control it? Postfix operators don't interact well with semicolons . Most programmers avoid them for this reason.
( source )
Process
defines two methods
abstract def !: Int
abstract def !(log: ProcessLogger): Int
When you do
Process(msg)!
you want to call the first, but since there is no unambiguous indication that the line should end (i.e. that the semicolon should be output), the parser starts reading the next line, it finds something could syntactically be an argument ( sender
). and you end up calling the second version !
.
The resulting code is actually:
Process(msg)! sender ! "complete"
i.e.
(Process(msg).!(sender)).!("complete")
hence the error: is sender
not an instance ProcessLogger
.
To fix this, you need to unravel this ambiguity. There are many ways to do this, the simplest one is to avoid the whole postfix operator:
Process(msg).!
sender ! "complete"
Actually, given this other question of yours , you can even just do
msg.!
sender ! "complete"
source to share
It might be another case where the Scala grammar does not allow postfix operators anywhere other than the end of the expression.
The first one was described in " Why does this code need a blank line or semicolon? "
Adding a semicolon can also compile the code due to the output of the semicolon .
Process(msg)!;
sender ! "complete"
source to share