On 11/03/2006 10:16 AM, Muttley Meen wrote:
On 11/3/06, Rob Dixon <[EMAIL PROTECTED]> wrote:
Mumia W. wrote:
>
> On 11/03/2006 02:23 AM, Muttley Meen wrote:
>>
>> In the attached script I implement two packages:
>> Package1 and Package2.
>>
>> Package2 is derived from Package1, which I guess I dont well.
>> Now Package1 has a method called IncErr which increments a variable
>> named $err.
>>
>> If I call something like:
>>
>> $a = Package1::new();
>> $a->IncErr();
>> print "ERR1: $a->{err}\n"; # should print 1
>>
>> all goes well, but if I call something like:
>>
>> $a = Package1::new();
>> $a->Package2->Create(); # this should call IncErr too
>
> This is not allowed because "Package2" is not a method within the class
> Package1. You want this:
Yes it is! It's an accessor method (albeit written wrongly). This is
indeed
a
very tangled web!
> my $b = Package2->new();
> $b->Create();
> print "ERR(\$b): $b->{err}\n";
>
>> print "ERR1: $a->{err}\n"; # should print 1
>> doent't work as I expected.
>>
>> Is there something wrong with the way I `bless`-ed the class
Package2 ?
>>
>>
>>
>> ------>8-----------
>> #! /usr/bin/perl
>
> use strict;
> use warnings;
> # Modify your program to work with these.
Amen.
>> package Package1 ;
>> sub new {
>> my ($class) = @_;
>> $class = __PACKAGE__ ;
>>
>> print "Call new [".$class."]\n" ;
>> $r = [];
>> $this = {};
>> $class->{err} = 0 ;
>>
>> $r->[0] = Package2::new($this->{sock_fd} );
>>
>> bless $this, $class;
>> return $this ;
>> }
>>
>> sub IncErr {
>> my $this = shift ;
>> $this->{err} += 1 ;
>> }
>>
>> sub Package2 {
>> my $this = shift ;
>> @_ ? ($r->[0] = shift) : $r->[0];
>> }
>>
>>
>>
>>
>>
>>
>> package Package2 ;
>> @ISA = ("Package1");
>> sub new {
>> my ( $this, $sock ) = @_ ;
>> $class = __PACKAGE__ unless @_;
>> $this->{sock_fd} = $sock ;
>> bless $this;
>> return $this ;
>> }
>>
>> sub Create {
>> my $this = shift;
>> print "Call Create\n" ;
>> print "ERR2: $this->{err} ( this should print 2 )\n" ;
>> $this->IncErr() ;
>> print "ERR2: $this->{err} ( this should print 3 )\n" ;
>> }
>>
>> my $a = Package1::new();
>> $a->IncErr();
>> $a->IncErr();
>> $a->Package2->Create();
>> print "ERR1: $a->{err} ( this should print 3 )\n" ;
>>
>> ------------------->8--------------------
>>
>
> I didn't look in detail at your program, but I also see that you use a
> suboptimal syntax for creating objects; don't use "::"; use "->", e.g.
>
> my $a = Package1->new();
>
> Using "::" will work, but it creates problems that will make you
> sad--such as preventing inheritance.
Is worse than suboptimal - it's wrong! Package1::new() won't pass the
package
name as the first parameter. You could write the constructor
differently of
course so that it fixes the call, but that's not how it's supposed to
work.
> Using "use strict" and "use warnings" will help you catch errors like
> the one above where you do "$a->Package2->Create()"
Not true, but still an essential technique.
Rob
Well , here is what I come up with:
#! /usr/bin/perl
use strict;
use warnings;
package Package1 ;
sub new {
my ($class) = @_ ;
print "Call new [".$class."]\n" ;
my @r = [];
my $this = {};
$this->{err} = 0 ;
$this->{r}->[0] = Package2->new();
$this->{r}->[0]->{err} = $this->{err} ;
bless $this, $class ;
return $this ;
}
sub IncErr {
print "[IncErr]\n";
my $this = shift ;
$this->{err} += 1 ;
}
#accessor method for Package2
sub Package2 {
my $this = shift ;
print "[Package2]\n" ;
@_ ? ($this->{r}->[0] = shift) : $this->{r}->[0];
}
#accessor method for err
sub err {
my $this = shift;
$this->{err};
}
package Package2 ;
our @ISA = ("Package1");
sub new {
my ( $class, $sock ) = @_ ;
my $this = {} ;
bless $this, $class;
return $this ;
}
sub Create {
my $this = shift;
print "[Package2->Create]\n" ;
print "CREATE:[EMAIL PROTECTED]>err]} \t\t( this should print 2 )\n" ;
$this->IncErr() ;
print "CREATE:[EMAIL PROTECTED]>err]} \t\t( this should print 3 )\n" ;
}
$a = Package1->new();
$a->IncErr();
$a->IncErr();
print "ERR1:\t$a->{err} \t\t( this should print 2 )\n" ;
$a->Package2->Create();
print "ERR1:\t$a->{err} \t\t( this should print 3 )\n" ;
Please bottom-post.
Why should a call to Create() on an object returned by Package2()
updatethe object $a ?
It shouldn't normally update the containing object, and it doesn't in
your program.
For your education, try this,
print "Inside ERR:\t", $a->Package2->err, "\n";
Also, typically one uses either containment or inheritance but not both.
Please explain what you're trying to do again.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>