- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: Inherited behavior from a subclass of a class that extends Actor
Fri, 2009-02-13, 02:21
On Thu, Feb 12, 2009 at 5:19 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
David,
The original code you posted will never have messages handled by the subclass, because Animal's PF has a wildcard, so messages will never fall through to the subclass given the order in which you're composing the Partials.
Yep.
--j
On Thu, Feb 12, 2009 at 5:10 PM, David Pollak <feeder.of.the.bears@gmail.com> wrote:
Jan,
You answer:
class Animal extends Actor{
def act{
react{
case msg => handleMessage(msg)
}
}
def handleMessage(msg : Any) : Unit = {
msg match {
case Reproduce => println("Reproduce")
case _ => println("Some default action")
}
}
}
class Mammal extends Animal{
override def handleMessage(msg : Any) : Unit = {
msg match {
case GrowHair => println("Grow Hair")
case msg => super.handleMessage(msg)
}
}
}
}
Is only correct if the superclass (animal) has a wildcard match in the handler.
Actors will only process messages if the message is defined at the current react handler. Got into the scala prompt and do the following:
scala> val pf1: PartialFunction[Any, Unit] = {
| case s: String => println("String: "+s)
| }
pf1: PartialFunction[Any,Unit] = <function>
scala> val jan: PartialFunction[Any, Unit] = {
| case i: Int => println("Int: "+i)
| case msg => pf1(msg)
| }
jan: PartialFunction[Any,Unit] = <function>
scala> val pf2: PartialFunction[Any, Unit] = {
| case i: Int => println("Int: "+i)
| }
pf2: PartialFunction[Any,Unit] = <function>
scala> val dpp = pf2 orElse pf1
dpp: PartialFunction[Any,Unit] = <function>
scala> jan.isDefinedAt(0.0)
res0: Boolean = true
scala> dpp.isDefinedAt(0.0)
res2: Boolean = false
scala> jan(0.0)
My solution composed a PartialFunction using orElse. Your solution does not compose the PartialFunction and isDefinedAt will always be true. However, the message is not defined for, in this case, a Double.
Thanks,
David
On Thu, Feb 12, 2009 at 4:59 PM, Jan Lohre <jan.lohre@googlemail.com> wrote:
David,
Right, Jorge wrote code that solves the problem - as I also did by the way. Jorges is actually prettier than mine, but yours will behave slightly different.
As Dustin stated that a message should be processed by the superclass actor if it cannot be processed by the subclass actor I still think yours incorrect.
That's at least what I read out of Dustins question.
I admit that you probably have more experience both with Scala and with actors than I have so this is not meant as offense. Nevertheless I have some basic knowledge (like act is called only once and react is the method involved with message handling)
I also did not take the question literally (and don't know why you seem to think I did).
Kind regards,
Jan
2009/2/13 David Pollak <feeder.of.the.bears@gmail.com>
Jan,
Jorge and I wrote code that solves the problem: how do you mix OO and the Actor model. The act method is called once and only once when an Actor is started. It is not called over and over. The thing that's called over and over is react (or receive). If you read the literal words of the request, they are nonsense. There is never a message that's passed to an act method. The message is placed in the mailbox and processed by react (or receive.) But rather than saying "re-phrase your question so you get the underlying sequence of calls right" I took a stab at answering what I believed to be the goal.
Unless I grossly misunderstood the goal (to intercept existing messages and/or add new messages to an Actor), then this solution of composing the partial function that's passed to react is the correct solution to the problem.
So, Dustin, is this a solution to your question?
Thanks,
David
On Thu, Feb 12, 2009 at 4:27 PM, Jan Lohre <jan.lohre@googlemail.com> wrote:
Sure, for the concrete example your solution is preferrable, but the requirement was:
"I'd like to send a message to a subclass of a class that extends an Actor that overrides its parent's act() method, but if the message is not found, I'd like the message passed to super.act()"
Kind regards,
Jan
2009/2/13 David Pollak <feeder.of.the.bears@gmail.com>
On Thu, Feb 12, 2009 at 4:20 PM, Jan Lohre <jan.lohre@googlemail.com> wrote:
This is the other way around, isn't it?
Yes, but the code isn't as pretty because you have to explicitly define the type:
class Mammal extends Animal {
override def handler = { val myHandler: PartialFunction[Any, Unit] = { case "GrowHair" => println("Grow hair")
}
myHandler orElse super.handler }
}
As far as I understood the subclass handler should go first and only if it can't handle the message the handler from superclass comes into play.
Kind regards,
Jan
2009/2/13 David Pollak <feeder.of.the.bears@gmail.com>
On Thu, Feb 12, 2009 at 3:37 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A bit cleaner, perhaps:
class Animal extends Actor {
def handler: PartialFunction[Any, Unit] = {
case "Reproduce" => println("Reproduce")
case _ => println("Default")
}
def act = react(handler)
}
class Mammal extends Animal {
override def handler = {
case "GrowHair" => println("Grow hair")
case msg => super.handler(msg)
}
}
Or:
class Animal extends Actor {
def handler: PartialFunction[Any, Unit] = {
case "Reproduce" => println("Reproduce")
case _ => println("Default")
}
def act = react(handler)
}
class Mammal extends Animal {
override def handler = super.handler orElse {
case "GrowHair" => println("Grow hair")
}
}
--j
On Thu, Feb 12, 2009 at 3:18 PM, Jan Lohre <jan.lohre@googlemail.com> wrote:I am a second too late but as I have it in the clipboard already I'll post it.
import scala.actors.Actor
import scala.actors.Actor._
case class Reproduce
case class GrowHair
class Animal extends Actor{
def act{
react{
case msg => handleMessage(msg)
}
}
def handleMessage(msg : Any) : Unit = {
msg match {
case Reproduce => println("Reproduce")
case _ => println("Some default action")
}
}
}
class Mammal extends Animal{
override def handleMessage(msg : Any) : Unit = {
msg match {
case GrowHair => println("Grow Hair")
case msg => super.handleMessage(msg)
}
}
}
}
Kind regards,
Jan
2009/2/12 Dustin Whitney <dustin.whitney@gmail.com>
I'd like to send a message to a subclass of a class that extends an Actor that overrides its parent's act() method, but if the message is not found, I'd like the message passed to super.act(). I have only been able to make this work in a very hackish manner. Anyone know how to properly do this?
For example, I'd like to create an instance of the Mammal class and send it a Reproduce message, but not have to create an instance of the super class to do so - which might not even be possible of I had declared Animal abstract.
import scala.actors.Actor
import scala.actors.Actor._
case class Reproduce
case class GrowHair
class Animal extends Actor{
def act{
react{
case Reproduce => println("Reproduce")
case _ => println("Some default action")
}
}
}
class Mammal extends Animal{
override def act{
react{
case GrowHair => println("Grow Hair")
case msg => { new Animal().start ! msg} // this is incredibly hackish, imho, and would not work if Animal were abstract.
}
}
}
Any insight would be appreciated.
-Dustin
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
create a PartialFunction in the superclass and override it in the subclass.
Make sure you do not have a wildcald in your partial-functions as you don't want to "eat" messages you can't handle. Also this would limit your ability to "link" actors later or use the EXIT message.
Also, to have the behavior you described, you need to invert the "orElse" in David's answer.
I'd provide you a code sample, but I think someone more versed in the details could provide a better one (or adapt the ones already described)
Also, these mailing lists have been slightly volatile lately. Most people on here are incredibly smart, so hopefully we'll all start assuming this until proven otherwise. Hopefully it will dwindle down in time, but for now I try to combat tense email chains with LOLs.
Please enjoy Google's amazing collection of mail emtoicons
Josh Scala
On Thu, Feb 12, 2009 at 8:20 PM, David Pollak <feeder.of.the.bears@gmail.com> wrote: