|
List Info
Thread: Qn on classes, inheritance, and threads
|
|
| Qn on classes, inheritance, and threads |

|
2006-03-28 12:39:54 |
|
In a message dated 3/28/2006 5:50:21 A.M. Eastern Standard Time,
jhfoo-ml  extracktor .com writes:
> Hi all, > > I have a need to do this (abstracted from the
attached working code): > package BaseClass; > use threads; >
> sub doThis > { > my $this =
shift; > >
threads->create(\&doThat,$this);
at this point, the compiler is looking for a subroutine doThat
in the package
BaseClass and all classes (i.e., packages) that BaseClass derives
from.
however, BaseClass derives from nothing; in particular, it does not
derive
from DerivedClass, where a subroutine named doThat (or more
specifically,
&DerivedClass::doThat) is defined. this is what the error
message is saying.
a way around the problem is to say
threads->create(\&DerivedClass::doThat,$this);
> } > > package DerivedClass; > use base
'BaseClass'; > > sub new > { >
my $class = shift; > my $this =
$class->SUPER::new; > return bless
$this,$class; > } > > sub doThat > { >
... > } > > --- in an app that uses these objects --- >
use DerivedClass; > my $o = DerivedClass->new; >
$o->doThis; > > The error is: > Undefined subroutine
&BaseClass::doThat called at BaseClass.pm > > Notice that
doThat() is not in the base class, but rather in the > subclass.
Apparently Perl is not able to determine which package to use > for
doThat() within doThis(). I have tried:
perl knows exactly which package (or packages) to use because you
have
told it exactly which to use.
> > threads->create(\&{$this::doThat},$this); >
> and a few other permutations, but they are all wrong. I'm quite sure
> it's matter of syntax. > > I will try to explain myself
again if you are confused. > > Please advise. Thanks.
hi ji-haw --
consider the following:
-------- begin code ----------------
# t_jhfoo1.pl derived
classes
28mar06waw
use strict; use warnings;
package Foo;
sub foo { bar(); }
sub bar{ Bar::drunk(); printf
qq(i am bar in %s \n), __PACKAGE__; }
package Bar; use base 'Foo';
sub drunk { printf qq(i am drunk in %s \n),
__PACKAGE__; }
package main;
Bar->foo(); # ok: &foo() defined in Bar or in one of its base
classes Foo::foo(); # Bar::foo(); # fails: no &Bar::foo()
defined in package Bar # drunk(); # fails: no &drunk() defined in
package main
package Bar;
drunk; # ok
############################
package BaseClass; use threads;
sub doThis { my $this = shift;
# threads->create(\&doThat,$this); #
no
#
threads->create(\&DerivedClass::doThat,$this); # should work
$this->->('YES');
}
sub new ($) { &nbs p; my ($class) = _;
my %hash =
(
_status=>'STOPPED', _code
=> \&DerivedClass::doThat,
);
return bless \%hash,$class; }
package DerivedClass; use base 'BaseClass';
sub new { my $class = shift;
my $this = $class->SUPER::new; return bless
$this,$class; }
sub doThat { & nbsp; my ($message) = _;
print "in doThat: $message \n"; }
# --- in an app that uses these objects ---
package main;
# use DerivedClass; my $o =
DerivedClass->new; $o->doThis;
------------ end code ----------------
hth -- bill walters
|
| Qn on classes, inheritance, and threads |

|
2006-03-29 03:03:33 |
Hello William,
Thanks for the tip. In your example you did this:
threads->create(\&DerivedClass::doThat,$this);
And it seems to work. But if I am to make the
'DerivedClass' portion
dynamic (as it has to work with other subclasses eg
DerivedClass2,
DerivedClass3), how can I do it?
I think it will have to be along the lines:
threads->create(\&$PackageName::doThat,$this);
Using a variable in place of the hard code. But I get get
the syntax right.
By the way, how does one get the class (aka package) name
from an object
instance?
Williamawalters aol.com wrote:
> In a message dated 3/28/2006 5:50:21 A.M. Eastern
Standard Time,
> jhfoo-ml extracktor.com writes:
>
> > Hi all,
> >
> > I have a need to do this (abstracted from the
attached working code):
> > package BaseClass;
> > use threads;
> >
> > sub doThis
> > {
> > my $this = shift;
> >
> > threads->create(\&doThat,$this);
>
> at this point, the compiler is looking for a subroutine
doThat in
> the package
> BaseClass and all classes (i.e., packages) that
BaseClass derives from.
> however, BaseClass derives from nothing; in particular,
it does not derive
> from DerivedClass, where a subroutine named doThat
(or more
> specifically,
> &DerivedClass::doThat) is defined. this is what
the error message is
> saying.
> a way around the problem is to say
>
>
threads->create(\&DerivedClass::doThat,$this);
> > }
> >
> > package DerivedClass;
> > use base 'BaseClass';
> >
> > sub new
> > {
> > my $class = shift;
> > my $this = $class->SUPER::new;
> > return bless $this,$class;
> > }
> >
> > sub doThat
> > {
> > ...
> > }
> >
> > --- in an app that uses these objects ---
> > use DerivedClass;
> > my $o = DerivedClass->new;
> > $o->doThis;
> >
> > The error is:
> > Undefined subroutine &BaseClass::doThat called
at BaseClass.pm
> >
> > Notice that doThat() is not in the base class, but
rather in the
> > subclass. Apparently Perl is not able to determine
which package to use
> > for doThat() within doThis(). I have tried:
>
>
> perl knows exactly which package (or packages) to use
because you have
> told it exactly which to use.
>
> >
> > threads->create(\&{$this::doThat},$this);
> >
> > and a few other permutations, but they are all
wrong. I'm quite sure
> > it's matter of syntax.
> >
> > I will try to explain myself again if you are
confused.
> >
> > Please advise. Thanks.
>
> hi ji-haw --
>
> consider the following:
>
> -------- begin code ----------------
>
> # t_jhfoo1.pl derived classes
> 28mar06waw
>
> use strict;
> use warnings;
>
> package Foo;
>
> sub foo {
> bar();
> }
>
> sub bar{
> Bar::drunk();
> printf qq(i am bar in %s \n), __PACKAGE__;
> }
>
> package Bar;
> use base 'Foo';
>
> sub drunk {
> printf qq(i am drunk in %s \n), __PACKAGE__;
> }
>
> package main;
>
> Bar->foo(); # ok: &foo() defined in Bar or in
one of its base classes
> Foo::foo();
> # Bar::foo(); # fails: no &Bar::foo() defined in
package Bar
> # drunk(); # fails: no &drunk() defined in package
main
>
> package Bar;
>
> drunk; # ok
> ############################
>
> package BaseClass;
> use threads;
>
> sub doThis
> {
> my $this = shift;
>
> # threads->create(\&doThat,$this); # no
>
> #
threads->create(\&DerivedClass::doThat,$this); #
should work
>
> $this->->('YES');
>
> }
>
> sub new ($)
> {
> my ($class) = _;
>
> my %hash = (
> _status=>'STOPPED',
> _code => \&DerivedClass::doThat,
> );
>
> return bless \%hash,$class;
> }
>
> package DerivedClass;
> use base 'BaseClass';
>
> sub new
> {
> my $class = shift;
> my $this = $class->SUPER::new;
> return bless $this,$class;
> }
>
> sub doThat
> {
> my ($message) = _;
>
> print "in doThat: $message \n";
> }
>
> # --- in an app that uses these objects ---
>
> package main;
>
> # use DerivedClass;
> my $o = DerivedClass->new;
> $o->doThis;
>
> ------------ end code ----------------
>
> hth -- bill walters
>
_______________________________________________
ActivePerl mailing list
ActivePerl listserv.ActiveState.com
To unsubscribe: http:/
/listserv.ActiveState.com/mailman/mysubs
|
|
| Qn on classes, inheritance, and threads |

|
2006-03-29 03:22:41 |
Hey William,
Ok, I've dug around, and I've got a working solution to my
problem. It's
a bit ugly though:
package BaseClass;
...
sub doThis
{
my $pFunc;
eval '$pFunc = \&'.ref($this).'::doThat';
return threads->new($pFunc,$this);
}
package DerivedClass;
...
sub doThat
{
...
}
Essentially, the 3 lines of code does the following:
1. ref($this) returns the class name
2. eval is needed to get the pointer to the instance's
overloaded class
subroutine, and store it in $pFunc
3. use $pFunc directly as a parameter in new()
My question is: is there a cleaner way to do this: ie
without the use of
eval?
Williamawalters aol.com wrote:
> In a message dated 3/28/2006 5:50:21 A.M. Eastern
Standard Time,
> jhfoo-ml extracktor.com writes:
>
> > Hi all,
> >
> > I have a need to do this (abstracted from the
attached working code):
> > package BaseClass;
> > use threads;
> >
> > sub doThis
> > {
> > my $this = shift;
> >
> > threads->create(\&doThat,$this);
>
> at this point, the compiler is looking for a subroutine
doThat in
> the package
> BaseClass and all classes (i.e., packages) that
BaseClass derives from.
> however, BaseClass derives from nothing; in particular,
it does not derive
> from DerivedClass, where a subroutine named doThat
(or more
> specifically,
> &DerivedClass::doThat) is defined. this is what
the error message is
> saying.
> a way around the problem is to say
>
>
threads->create(\&DerivedClass::doThat,$this);
> > }
> >
> > package DerivedClass;
> > use base 'BaseClass';
> >
> > sub new
> > {
> > my $class = shift;
> > my $this = $class->SUPER::new;
> > return bless $this,$class;
> > }
> >
> > sub doThat
> > {
> > ...
> > }
> >
> > --- in an app that uses these objects ---
> > use DerivedClass;
> > my $o = DerivedClass->new;
> > $o->doThis;
> >
> > The error is:
> > Undefined subroutine &BaseClass::doThat called
at BaseClass.pm
> >
> > Notice that doThat() is not in the base class, but
rather in the
> > subclass. Apparently Perl is not able to determine
which package to use
> > for doThat() within doThis(). I have tried:
>
>
> perl knows exactly which package (or packages) to use
because you have
> told it exactly which to use.
>
> >
> > threads->create(\&{$this::doThat},$this);
> >
> > and a few other permutations, but they are all
wrong. I'm quite sure
> > it's matter of syntax.
> >
> > I will try to explain myself again if you are
confused.
> >
> > Please advise. Thanks.
>
> hi ji-haw --
>
> consider the following:
>
> -------- begin code ----------------
>
> # t_jhfoo1.pl derived classes
> 28mar06waw
>
> use strict;
> use warnings;
>
> package Foo;
>
> sub foo {
> bar();
> }
>
> sub bar{
> Bar::drunk();
> printf qq(i am bar in %s \n), __PACKAGE__;
> }
>
> package Bar;
> use base 'Foo';
>
> sub drunk {
> printf qq(i am drunk in %s \n), __PACKAGE__;
> }
>
> package main;
>
> Bar->foo(); # ok: &foo() defined in Bar or in
one of its base classes
> Foo::foo();
> # Bar::foo(); # fails: no &Bar::foo() defined in
package Bar
> # drunk(); # fails: no &drunk() defined in package
main
>
> package Bar;
>
> drunk; # ok
> ############################
>
> package BaseClass;
> use threads;
>
> sub doThis
> {
> my $this = shift;
>
> # threads->create(\&doThat,$this); # no
>
> #
threads->create(\&DerivedClass::doThat,$this); #
should work
>
> $this->->('YES');
>
> }
>
> sub new ($)
> {
> my ($class) = _;
>
> my %hash = (
> _status=>'STOPPED',
> _code => \&DerivedClass::doThat,
> );
>
> return bless \%hash,$class;
> }
>
> package DerivedClass;
> use base 'BaseClass';
>
> sub new
> {
> my $class = shift;
> my $this = $class->SUPER::new;
> return bless $this,$class;
> }
>
> sub doThat
> {
> my ($message) = _;
>
> print "in doThat: $message \n";
> }
>
> # --- in an app that uses these objects ---
>
> package main;
>
> # use DerivedClass;
> my $o = DerivedClass->new;
> $o->doThis;
>
> ------------ end code ----------------
>
> hth -- bill walters
>
_______________________________________________
ActivePerl mailing list
ActivePerl listserv.ActiveState.com
To unsubscribe: http:/
/listserv.ActiveState.com/mailman/mysubs
|
|
[1-3]
|
|