List Info

Thread: Qn on classes, inheritance, and threads




Qn on classes, inheritance, and threads
user name
2006-03-28 12:39:54
In a message dated 3/28/2006 5:50:21 A.M. Eastern Standard Time, jhfoo-mlextracktor.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  
 
Qn on classes, inheritance, and threads
user name
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?

Williamawaltersaol.com wrote:
> In a message dated 3/28/2006 5:50:21 A.M. Eastern
Standard Time, 
> jhfoo-mlextracktor.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
ActivePerllistserv.ActiveState.com
To unsubscribe: http:/
/listserv.ActiveState.com/mailman/mysubs
Qn on classes, inheritance, and threads
user name
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?

Williamawaltersaol.com wrote:
> In a message dated 3/28/2006 5:50:21 A.M. Eastern
Standard Time, 
> jhfoo-mlextracktor.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
ActivePerllistserv.ActiveState.com
To unsubscribe: http:/
/listserv.ActiveState.com/mailman/mysubs
[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )