This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Actor message case selection and keeping the message

4 replies
Hein Meling
Joined: 2010-11-10,
User offline. Last seen 42 years 45 weeks ago.

Hi

I'm wondering if it is possible to specify a named reference for a message received by an actor, specifically a typed case class.

Here is an example describing what I currently do:

def act() {
loop {
react {
case s: String =>
delay
println(s)
case MyMsg(x, y, z, from) if (x >= q) =>
val msg = MyMsg(x, y, z, from)
msgbuf.addBinding(x, msg)
....
}

case class MyMsg(x: Int, y: Int, z: String, from: Actor) extends Ordered[Promise] {
override def compare(that: MyMsg): Int = this.y compare that.y
}

So my question is this: can I assign a value name to the received MyMsg object so that I can store that in msgbuf? More or less like you can do for the String case above.

I tried to do:

case msg: MyMsg(x,y,z,from) if (x >= q)

but that didn't compile.

It seems sort of useless to do the

val msg = MyMsg(x, y, z, from)

inside the case code.

Any suggestions on how to avoid this extra object creation would be very helpful.

Thanks!

All the best,

:) Hein

Stephen Tu
Joined: 2010-02-24,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor message case selection and keeping the message
you can do:

case x @ MyMsg(x, y, z, from) if (x >= q) =>

On Wed, Nov 10, 2010 at 10:34 AM, Hein Meling <hein.meling@gmail.com> wrote:
Hi

I'm wondering if it is possible to specify a named reference for a message received by an actor, specifically a typed case class.

Here is an example describing what I currently do:

def act() {
 loop {
   react {
     case s: String =>
       delay
       println(s)
     case MyMsg(x, y, z, from) if (x >= q) =>
       val msg = MyMsg(x, y, z, from)
       msgbuf.addBinding(x, msg)
   ....
}

case class MyMsg(x: Int, y: Int, z: String, from: Actor) extends Ordered[Promise] {
 override def compare(that: MyMsg): Int = this.y compare that.y
}

So my question is this: can I assign a value name to the received MyMsg object so that I can store that in msgbuf? More or less like you can do for the String case above.

I tried to do:

 case msg: MyMsg(x,y,z,from) if (x >= q)

but that didn't compile.

It seems sort of useless to do the

 val msg = MyMsg(x, y, z, from)

inside the case code.

Any suggestions on how to avoid this extra object creation would be very helpful.

Thanks!

All the best,

:) Hein

Stephen Tu
Joined: 2010-02-24,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor message case selection and keeping the message
oops, except don't use x as the var name since you already use it within MyMsg

On Wed, Nov 10, 2010 at 11:50 AM, Stephen Tu <steve33671@gmail.com> wrote:
you can do:

case x @ MyMsg(x, y, z, from) if (x >= q) =>

On Wed, Nov 10, 2010 at 10:34 AM, Hein Meling <hein.meling@gmail.com> wrote:
Hi

I'm wondering if it is possible to specify a named reference for a message received by an actor, specifically a typed case class.

Here is an example describing what I currently do:

def act() {
 loop {
   react {
     case s: String =>
       delay
       println(s)
     case MyMsg(x, y, z, from) if (x >= q) =>
       val msg = MyMsg(x, y, z, from)
       msgbuf.addBinding(x, msg)
   ....
}

case class MyMsg(x: Int, y: Int, z: String, from: Actor) extends Ordered[Promise] {
 override def compare(that: MyMsg): Int = this.y compare that.y
}

So my question is this: can I assign a value name to the received MyMsg object so that I can store that in msgbuf? More or less like you can do for the String case above.

I tried to do:

 case msg: MyMsg(x,y,z,from) if (x >= q)

but that didn't compile.

It seems sort of useless to do the

 val msg = MyMsg(x, y, z, from)

inside the case code.

Any suggestions on how to avoid this extra object creation would be very helpful.

Thanks!

All the best,

:) Hein


Hein Meling
Joined: 2010-11-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor message case selection and keeping the message

Thanks Stephen, that worked nicely!

Any clue why : is not acceptable here? It just seems like the most intuitive approach.

Thanks again!

All the best,

:) Hein

On Nov 10, 2010, at 11:51 , Stephen Tu wrote:

> oops, except don't use x as the var name since you already use it within MyMsg
>
> On Wed, Nov 10, 2010 at 11:50 AM, Stephen Tu wrote:
> you can do:
>
> case x @ MyMsg(x, y, z, from) if (x >= q) =>
>
>
> On Wed, Nov 10, 2010 at 10:34 AM, Hein Meling wrote:
> Hi
>
> I'm wondering if it is possible to specify a named reference for a message received by an actor, specifically a typed case class.
>
> Here is an example describing what I currently do:
>
> def act() {
> loop {
> react {
> case s: String =>
> delay
> println(s)
> case MyMsg(x, y, z, from) if (x >= q) =>
> val msg = MyMsg(x, y, z, from)
> msgbuf.addBinding(x, msg)
> ....
> }
>
> case class MyMsg(x: Int, y: Int, z: String, from: Actor) extends Ordered[Promise] {
> override def compare(that: MyMsg): Int = this.y compare that.y
> }
>
> So my question is this: can I assign a value name to the received MyMsg object so that I can store that in msgbuf? More or less like you can do for the String case above.
>
> I tried to do:
>
> case msg: MyMsg(x,y,z,from) if (x >= q)
>
> but that didn't compile.
>
> It seems sort of useless to do the
>
> val msg = MyMsg(x, y, z, from)
>
> inside the case code.
>
> Any suggestions on how to avoid this extra object creation would be very helpful.
>
> Thanks!
>
> All the best,
>
> :) Hein
>
>

Stephen Tu
Joined: 2010-02-24,
User offline. Last seen 42 years 45 weeks ago.
Re: Actor message case selection and keeping the message


On Wed, Nov 10, 2010 at 11:56 AM, Hein Meling <hein.meling@gmail.com> wrote:
Thanks Stephen, that worked nicely!

Any clue why : is not acceptable here? It just seems like the most intuitive approach.

Thanks again!

All the best,

:) Hein


you use ":" to specify a type to match, and you use the "@" to bind a particular result of a matched pattern to a name. so for instance you could have also done:

case msg: MyMsg if (msg.x >= q) =>
personally i find using pattern matching w/o explicit type annotation to be more appealing, so a more elegant way IMO to express your particular match is:

     case msg @ MyMsg(x, _, _, _) if (x >= q) =>
       msgbuf.addBinding(x, msg)

where you use the "_" as a wildcard placeholder. but of course style is style so no particular method is "wrong". however, one thing to think about could be which pattern results in the most efficient bytecode output, and I have not looked into that at all.

hope that helps

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland