Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Object Oriented Perl : Query
I have a base class called as Weapon  and I have derived classes 'Gun'
and 'RocketLauncher'.  I   need to instantiate  Gun  or RocketLauncher
based on a parameter say distance from  the target. If the distance is
less  than 20m  I  need  a  gun  and  if it is   more I   will  need a
RocketLauncher.

This is my attempt  at a Perl code  that does this.  Is this the right
way to do this. Any pointers will be of help.

#! /usr/local/bin/perl -w

package Weapon;

use strict;

sub new {
my ( $self ) = @_;
my $class = ref($self) || $self;
return  bless {  }, $class;
}

sub hitPoints {
my ( $self ) = @_;
return $self->{hitpoints};
}

sub fire {
my ( $self, $target ) = @_;
print "Destroyed the target !! ", $self->hitPoints;
#$target->hurt($self->hitPoints);
}

package Gun;
use strict;
use base 'Weapon';

sub new {
my ( $self ) = @_;
my $class = ref($self) || $self;
$self = new Weapon();

$self->{type} = 'GUN';
$self->{hitpoints} = 10;

return $self;
}


package RocketLauncher;
use strict;
use base 'Weapon';

sub new {
my ( $self ) = @_;
my $class = ref($self) || $self;
$self = new Weapon();

$self->{type} = 'ROCKET';
$self->{hitpoints} = 100;
return $self;

}

1;


--
For this hour :
Fools  ignore  complexity.  Pragmatists  suffer it. Some can avoid it.
Geniuses remove it.
Alan Perlis

Report this thread to moderator Post Follow-up to this message
Old Post
Thens
09-06-04 01:57 PM


Re: Object Oriented Perl : Query
Thens  <thens@NOSPAMti.com> wrote in comp.lang.perl.misc:
>
> I have a base class called as Weapon  and I have derived classes 'Gun'
> and 'RocketLauncher'.  I   need to instantiate  Gun  or RocketLauncher
> based on a parameter say distance from  the target. If the distance is
> less  than 20m  I  need  a  gun  and  if it is   more I   will  need a
> RocketLauncher.
>
> This is my attempt  at a Perl code  that does this.  Is this the right
> way to do this. Any pointers will be of help.

Do what?  I see no attempt to create one or the other depending on a
parameter.

I don't see any gross errors in the class setup.  However, you should
switch on warnings as a matter of course.  Also, storing the weapon
type in the object is not really necessary, since ref() can always tell
you that.

[code left in place for reference]

Anno

> #! /usr/local/bin/perl -w
>
> package Weapon;
>
> use strict;
>
> sub new {
>   my ( $self ) = @_;
>   my $class = ref($self) || $self;
>   return  bless {  }, $class;
> }
>
> sub hitPoints {
>   my ( $self ) = @_;
>   return $self->{hitpoints};
> }
>
> sub fire {
>   my ( $self, $target ) = @_;
>   print "Destroyed the target !! ", $self->hitPoints;
>   #$target->hurt($self->hitPoints);
> }
>
> package Gun;
> use strict;
> use base 'Weapon';
>
> sub new {
>   my ( $self ) = @_;
>   my $class = ref($self) || $self;
>   $self = new Weapon();
>
>   $self->{type} = 'GUN';
>   $self->{hitpoints} = 10;
>
>   return $self;
> }
>
>
> package RocketLauncher;
> use strict;
> use base 'Weapon';
>
> sub new {
>   my ( $self ) = @_;
>   my $class = ref($self) || $self;
>   $self = new Weapon();
>
>   $self->{type} = 'ROCKET';
>   $self->{hitpoints} = 100;
>   return $self;
>
> }
>
> 1;
>
>
> --
> For this hour :
> Fools  ignore  complexity.  Pragmatists  suffer it. Some can avoid it.
> Geniuses remove it.
> Alan Perlis



Report this thread to moderator Post Follow-up to this message
Old Post
Anno Siegel
09-06-04 09:01 PM


Re: Object Oriented Perl : Query
Thens wrote:

> This is my attempt  at a Perl code  that does this.  Is this the right
> way to do this. Any pointers will be of help.

There is a subtle mistake in your code. Have a look at the following
pods for more info on Perl's OO mechanisms:

perlboot
perltoot
perlobj

Also, if you're serious about using Perl's OO, then reading Damian
Conway's "Object Oriented Perl" is a must.

> #! /usr/local/bin/perl -w
>
> package Weapon;
>
> use strict;
>
> sub new {
>   my ( $self ) = @_;
>   my $class = ref($self) || $self;
>   return  bless {  }, $class;
> }
>
> sub hitPoints {
>   my ( $self ) = @_;
>   return $self->{hitpoints};
> }
>
> sub fire {
>   my ( $self, $target ) = @_;
>   print "Destroyed the target !! ", $self->hitPoints;
>   #$target->hurt($self->hitPoints);
> }
>
> package Gun;
> use strict;
> use base 'Weapon';
>
> sub new {
>   my ( $self ) = @_;
>   my $class = ref($self) || $self;
>   $self = new Weapon();

Here, $self is an instance of the Weapon class. It is NOT a Gun object.
If you add the following:

print ref $self;

You will get Weapon, not Gun. Depending on your application, that could
not be a problem, but you're not getting true inheritance here. As long
as your Gun package does not have any distinct methods of its own (or
override any methods in Weapon, other than new()), then you are fine.
But if you require true inheritance, then you need to make $self an
instance of Gun. You do that by using SUPER:: like this:

$self = $class->SUPER::new;

This will look for the first new() method defined in the base class(es)
of Gun and will invoke it with $class as the parameter. So, it will call
the new() method in Weapon, which will return a hash ref blessed into
the Gun class.

>   $self->{type} = 'GUN';
>   $self->{hitpoints} = 10;
>
>   return $self;
> }

Ditto for RocketLauncher.

--Ala


Report this thread to moderator Post Follow-up to this message
Old Post
Ala Qumsieh
09-06-04 09:01 PM


Re: Object Oriented Perl : Query
Ala Qumsieh  <notvalid@email.com> wrote in comp.lang.perl.misc:
> Thens wrote:
> 
>
> There is a subtle mistake in your code. Have a look at the following

[snippage]
 
>
> Here, $self is an instance of the Weapon class. It is NOT a Gun object.

Ah, I hadn't noticed when I certified this code as "free of gross errors"
in another followup.  This is a gross error in classes that do inheritance.

Anno

Report this thread to moderator Post Follow-up to this message
Old Post
Anno Siegel
09-06-04 09:01 PM


Re: Object Oriented Perl : Query
*** post for FREE via your newsreader at post.newsfeed.com ***
 

Thens> sub new {
Thens>   my ( $self ) = @_;
Thens>   my $class = ref($self) || $self;
Thens>   return  bless {  }, $class;
Thens> }

Please see <http://www.stonehenge.com/merlyn/UnixReview/col52.html>
about why that ref($self) thing is bad.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training
!


-----= Posted via Newsfeed.Com, Uncensored Usenet News =-----
http://www.newsfeed.com - The #1 Newsgroup Service in the World!
-----== 100,000 Groups! - 19 Servers! - Unlimited Download! =-----


Report this thread to moderator Post Follow-up to this message
Old Post
Randal L. Schwartz
09-07-04 02:00 AM


Re: Object Oriented Perl : Query
merlyn@stonehenge.com (Randal L. Schwartz) wrote:
 
>
> Thens> sub new {
> Thens>   my ( $self ) = @_;
> Thens>   my $class = ref($self) || $self;
> Thens>   return  bless {  }, $class;
> Thens> }
>
> Please see <http://www.stonehenge.com/merlyn/UnixReview/col52.html>
> about why that ref($self) thing is bad.

You recommend not using ref($self) because some people might guess
incorrectly what new() does when it is used as an instance method.

How about this:  If people guess method behaviour rather than
reading the docs their votes don't count.  Allow $object->new(),
document the behaviour, and expect people to read it.

Peter

--
#!/local/bin/perl5 -wp -*- mode: cperl; coding: iso-8859-1; -*-
# matlab comment stripper (strips comments from Matlab m-files)
s/^((?:(?:[])}\w.]'+|[^'%])+|'[^'\n]*(?:''[^'\n]*)*')*).*/$1/x;

Report this thread to moderator Post Follow-up to this message
Old Post
Peter J. Acklam
09-08-04 08:56 AM


Re: Object Oriented Perl : Query
Peter J. Acklam <pjacklam@online.no> wrote in comp.lang.perl.misc:
> merlyn@stonehenge.com (Randal L. Schwartz) wrote:
> 
>
> You recommend not using ref($self) because some people might guess
> incorrectly what new() does when it is used as an instance method.
>
> How about this:  If people guess method behaviour rather than
> reading the docs their votes don't count.  Allow $object->new(),
> document the behaviour, and expect people to read it.

The point isn't so much that people fail to look up the definition,
but that they (specifically, readers of code that uses the class)
are forced to look it up.  When you know what "Class->new(...)" does,
you also know what "ref( $obj)->new(...)" does, but for the meaning
of "$obj->new(...)" you must go to the documentation.

The shortcut of calling ->new as an object method is inherently
unclear.  Unless there are massive advantages in allowing it (there
aren't in most classes), I think it is better to leave it out.  Its
use as a matter of course smacks of cargo cult.

Anno






Report this thread to moderator Post Follow-up to this message
Old Post
Anno Siegel
09-08-04 02:01 PM


Re: Object Oriented Perl : Query
Thens <thens@NOSPAMti.com> wrote in message news:<20040906175436.32d95abf@asiclindt001>...[
color=darkred]
> I have a base class called as Weapon  and I have derived classes 'Gun'
> and 'RocketLauncher'.  I   need to instantiate  Gun  or RocketLauncher
> based on a parameter say distance from  the target. If the distance is
> less  than 20m  I  need  a  gun  and  if it is   more I   will  need a
> RocketLauncher.
>
> This is my attempt  at a Perl code  that does this.  Is this the right
> way to do this. Any pointers will be of help.
>[/color]

I added some comments and code to your code.  There was a problem with
the new methods in your child classes, they would have actually
returned you the wrong class type.  All of the new methods would have
given you plain Weapon objects.
You don't show any code about how to create a class depending on the
conditions of distance as your statements above led me to belive the
code would try to do.  Was your question more along the lines of "Did
I create me classes properly to use inheritance?"

Or pehaps you were trying to find out how to have a class
automatically change its type in the fire method?  So when you invoke
fire it checks the target distance and then calls fire on the proper
weapon.  Here is a class below
which will act like a weapon, but delegate out to other weapons in the
fire
method depending on the distance.

package SmartWeapon;
use strict;
use base 'Weapon';

sub new {
my $self = Weapon::new(@_);
$self->{rocket} = RocketLauncher->new();
$self->{gun} = Gun->new();
}

sub fire {
my ($self, $target) = @_;
if ($target->getDistance() < 20) {
$self->{gun}->fire($target);
}
else {
$self->{rocket}->fire($target);
}
}

> #! /usr/local/bin/perl -w
>
> package Weapon;
>
> use strict;
>
> sub new {
>   my ( $self ) = @_;
>   my $class = ref($self) || $self;
>   return  bless {  }, $class;
> }
>
> sub hitPoints {
>   my ( $self ) = @_;
>   return $self->{hitpoints};
> }
>
> sub fire {
>   my ( $self, $target ) = @_;
>   print "Destroyed the target !! ", $self->hitPoints;
>   #$target->hurt($self->hitPoints);
> }
>
> package Gun;
> use strict;
> use base 'Weapon';
>
> sub new {

# you could allow your parent class to intialize everything
# it needs to like this.
my $self = Weapon::new(@_);

# Don't need this stuff
>   # my ( $self ) = @_;
>   # my $class = ref($self) || $self;
>   # $self = new Weapon();
>

# now you can initialize the variables needed for the child class
>   $self->{type} = 'GUN';
>   $self->{hitpoints} = 10;
>
>   return $self;
> }
>
>
> package RocketLauncher;
> use strict;
> use base 'Weapon';
>
> sub new {

my $self = Weapon::new(@_);

# don't need this stuff
>   #my ( $self ) = @_;
>   #my $class = ref($self) || $self;
>   #$self = new Weapon();
>
>   $self->{type} = 'ROCKET';
>   $self->{hitpoints} = 100;
>   return $self;
>
> }
>
> 1;

Report this thread to moderator Post Follow-up to this message
Old Post
Bryan Castillo
09-09-04 08:56 AM


Re: Object Oriented Perl : Query
anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote:

> The shortcut of calling ->new as an object method is
> inherently unclear.  Unless there are massive advantages
> in allowing it (there aren't in most classes), I think it
> is better to leave it out.  Its use as a matter of course
> smacks of cargo cult.

The "$class = ref($obj) || $obj;" construction is used many
places in the Perl docs and the Perl standard modules, so
its not strange that people choose to use it.

Anyway, if it's use is disallowed an appropriate error
message should be given.  Maybe something like this:

sub new {
my $class = shift;
croak "new(): not an instance method" if ref $class;
..
}

Peter

Report this thread to moderator Post Follow-up to this message
Old Post
Peter J. Acklam
09-09-04 01:56 PM


Re: Object Oriented Perl : Query
Peter J. Acklam <pjacklam@online.no> wrote in comp.lang.perl.misc:
> anno4000@lublin.zrz.tu-berlin.de (Anno Siegel) wrote:
> 
>
> The "$class = ref($obj) || $obj;" construction is used many
> places in the Perl docs and the Perl standard modules, so

Yes.  Much to the regret of some of us.  It's a pretty idiom,
and it has been propagated by well-renowned people.  (I'm
tempted to say, people who should know better :)

> its not strange that people choose to use it.

No, it isn't.  It is one of the harder design decisions *not* to
do something on behalf of the user that seems to offer itself.

If it is easy to do, and can as well be done outside the routine,
think twice before doing it inside (and forcing it upon the user).
You wouldn't sort a list result just because some users may want
it sorted and others won't care.  In this case, the performance
penalty is obvious, so experienced programmers won't do it.

The divantage of making ->new object-callable is "only" that
the reader can't guess what exactly the object call does.  That's
less visible drawback, and so the idiom had a chance to spread.

> Anyway, if it's use is disallowed an appropriate error
> message should be given.  Maybe something like this:
>
>     sub new {
>       my $class = shift;
>       croak "new(): not an instance method" if ref $class;
>       ...
>     }

Perhaps, but only because users may have come to expect it to be
callable that way.  Basically, ->new is a class method and the
user has no business calling it through an object.  If they
do, they may as well deal with the consequences.

Anno

Report this thread to moderator Post Follow-up to this message
Old Post
Anno Siegel
09-09-04 01:56 PM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

PERL Miscellaneous archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 05:04 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.