Scala Actor Extension

I am new to scala. Studying the Actor, I tried to expand it to save one line of def:

import scala.actors.Actor import Actor._ class Actoo(actoo: =>Unit) extends Actor { def act() {actoo} } object run extends Application { /* // this one runs well val a = new Actor { def act() { receive { case 1 => println("1") } } } */ val a = new Actoo { receive { case 1 => println("1") } } a.start a ! 1 } 

Then the exception trace looks like this:

 java.lang.AssertionError: assertion failed: receive from channel belonging to other actor at scala.Predef$.assert(Predef.scala:92) at scala.actors.Actor$class.receive(Actor.scala:424) at Actoo.receive(actoo.scala:3) at run$$anon$1.<init>(actoo.scala:16) at run$.<init>(actoo.scala:15) at run$.<clinit>(actoo.scala) at run.main(actoo.scala) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at scala.tools.nsc.ObjectRunner$$anonfun$run$1.apply(ObjectRunner.scala:75) at scala.tools.nsc.ObjectRunner$.withContextClassLoader(ObjectRunner.scala:49) at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:74) at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:154) at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) 

There may be many alternatives that can do the same, but I better know the reason why the code above does not work.

+4
source share
3 answers

This is pretty easy. In fact, this is not related to the library of actors. Piece of code

 val a = new Actoo { receive { case 1 => println("1") } } 

interpreted by the compiler as "create a new Actoo instance" with the initialization body receive {...} and val actoo becomes equal to () . So your code is equivalent

 val a = new Actoo() { receive { case 1 => println("1") } } 

To fix the code you need to write

 val a = new Actoo ({ receive { case 1 => println("1") } }) 
+8
source

There is also an actor method in actor syntax that does what you want. It even calls start for you automatically.

 import scala.actors.Actor import Actor._ val a = actor { receive { case 1 => println("1") } } a ! 1 
+5
source

In fact, you are trying to get the current current stream from the mailbox (your own streams are also Actors).

Testify of the following:

 Welcome to Scala version 2.7.5.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13). Type in expressions to have them evaluated. Type :help for more information. scala> import scala.actors.Actor._ import scala.actors.Actor._ scala> self ! 123 scala> receive { case x => println(x) } 123 

Now what you want to execute is already in the library (Actor.actor):

 val a = actor { receive { case x => println(x) } } // no need to start aa ! 123 

By the way, it is a very bad idea to extend the application. Use def main(args: Array[String]) instead.

+1
source

All Articles