Re: multiple packages/classes in one file

From: Todd W (toddrw69_at_excite.com)
Date: 01/03/05


Date: Mon, 03 Jan 2005 14:26:35 GMT


<ioneabu@yahoo.com> wrote in message
news:1104641417.763140.93440@c13g2000cwb.googlegroups.com...
>
> > The Cookbook or not, since strictures are enabled, you need to either
>
> > declare variables or use their fully qualified names:
> >
> > our $name = "first";
> >
> > > package Omega;
> > > $name = "last";
> >
> > our $name = "last";
> >
> > --
> > Gunnar Hjalmarsson
> > Email: http://www.gunnar.cc/cgi-bin/contact.pl
>
> Thanks! I did some reading on 'our' and it makes sense. It makes it
> so you can use globals under strict and not just lexicals. By global,
> this means global to the package that our is used in. I fixed up my OO
> example:
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
>
> my $a = one->new;
> my $b = two->new;
>
> $a->set_member(11);
> $b->set_member(21);
> print $a->get_member,"\n";
> print $b->get_member,"\n";
>
> #class one
> package one;
> our $member;
> sub new
> {
> my $class = shift;
> my $self = {};
> $member = 10;
> bless($self, $class);
> return $self;
> }
> sub set_member
> {
> my $self = shift;
> $member = shift;
> }
> sub get_member
> {
> return $member;
> }
>
> #class two
> package two;
> our $member;
> sub new
> {
> my $class = shift;
> my $self = {};
> $member = 20;
> bless($self, $class);
> return $self;
> }
> sub set_member
> {
> my $self = shift;
> $member = shift;
> }
> sub get_member
> {
> return $member;
> }
>

Please remember that your $member vaiable is class data and not instance
data, So technically, your code is not object oriented at all. note:

[trwww@waveright misc]$ cat oo.pl
use warnings;
use strict;

package one;

# this is fine, dont know why you had trouble
our $member = 10;

sub new {
  my $class = shift;
  my $self = bless( { }, $class );
  return $self;
}

sub get_member { $member }

sub set_member {
  my $self = shift; # heres your object
  $member = $_[0] if ( @_ );
}

package main;

print('access via package [', $one::member, "]\n");
my $first_one = one->new;
print('access via $first_one [', $first_one->get_member, "]\n");
my $second_one = one->new;
print("changing class data via \$second_one...\n");
$second_one->set_member( 55 );
print('access via $first_one [', $first_one->get_member, "]\n");

[trwww@waveright misc]$ perl oo.pl
access via package [10]
access via $first_one [10]
changing class data via $second_one...
access via $first_one [55]

To be object oriented, you want each object to maintain seperate data for
member. You accomplish that by using your bless()ed variable. This variable
is automatically set as the first argument in your subroutine's argument
list:

[trwww@waveright misc]$ cat oo.pl
use warnings;
use strict;

package one;

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

sub get_member {
  my $self = shift; # heres your object
  $self->{member};
}

sub set_member {
  my $self = shift; # heres your object
  $self->{member} = $_[0] if ( @_ );
}

package main;

my $first = one->new( member => 22 );
my $second = one->new( member => 55 );

print( 'member in $first [', $first->get_member, "]\n" );
print( 'member is $second [', $second->get_member, "]\n" );
print( "changing data in \$first\n" );
$first->set_member( 20 );
print( 'member in $first [', $first->get_member, "]\n" );
print( 'member is $second [', $second->get_member, "]\n" );
[trwww@waveright misc]$ perl oo.pl
member in $first [22]
member is $second [55]
changing data in $first
member in $first [20]
member is $second [55]

In languages like C++ and VB.NET, variable names are usually assumed to be
instance data unless explicitly declared otherwise, for example:

oVar = new Object
means the same thing as
this.oVar = new Object

>
> I found that if I set the value for the $member variable where it is
> declared, I got an error for trying to print an uninitialized value.
> When I set the default value in the constructor (assuming I don't use
> set_member to change it) it works fine. I was wondering why it didn't
> work, although I do see the sense in setting an object's default values
> in the constructor. Here is the erroneous code I had before:
>

To reiterate, you havent as yet set any object's value. If perl said you
were trying to print an uninitialized value, I'd probably take any bet you'd
be willing to make that you are. As I showed above, what you are trying to
do below is perfectly legal.

> ...
> #class one
> package one;
> our $member = 10; #Perl didn't accept me setting my default value here.
> sub new
> {
> my $class = shift;
> my $self = {};
> bless($self, $class);
> return $self;
> }
> ...

Have fun,

Todd W.



Relevant Pages