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>


Reply via email to