> But I'm wondering if there is another way
> (like the Java "private variable") to say
> "all class variables declared here are unique
> to each instance"? 

It sounds like you are trying to link how OO-Perl works with OO-Java... and
that is only going to make your head spin.  What you really need to do is
understand what bless really does, and that OO-Perl isn't really OO in the
usual sense (but it works like it is).

In Perl an "object" is really just a scalar variable that has been blessed.
Blessing adds an attribute to the scalar variable which is supposed to
represent the "type" of scalar.  The only requirement is that the bless
scalar must be a reference.

my $x = "foo";
my $y = bless \$x, "bar";
print $y;
# PRINTS: bar=SCALAR(0xa01ed1c)

Here $y is a reference to a scalar (hence the "SCALAR(0xa01ed1c)"), and it
has been tagged as type "bar".

That is all bless does.

Now the next part is the magic that Perl does...

$x->do_stuff;

Here $x does what looks like a method call.  Perl will look at the "type" of
$x, which is "foo", then try to execute do_stuff() in the "foo" package.
The first argument of this call will always be $x, like this:

foo:do_stuff($x);

This call does exactly the same thing as above.

Now when you talk about instance variables, realize that there is no true
object instance in Perl.  It is just a reference tagged with a "type"... the
rest is all smoke and mirrors.

So to emmulate instance variables you can use a hash reference instead of a
scalar reference, like this:

my %x = (field1 => 'val1', field2 => 'val2');
my $y = bless \%x, "bar";

Now $y is just a hash reference, so this stuff still works:

print $y->{field1};
print $y->{field2};

...And $y is also blessed, meaning you can emulate calling methods like I
did earlier.

Now you can still emulate private variables, but again, it's more smoke and
mirrors.  Without getting into the details (look at 'tie' for more info) you
can just use the Tie::SecureHash module.  It emulated public, protected, and
private variables.

http://search.cpan.org/author/DCONWAY/Tie-SecureHash-1.03/SecureHash.pm

I hope that helps a little.

Rob



-----Original Message-----
From: Kevin Pfeiffer [mailto:[EMAIL PROTECTED]
Sent: Thursday, September 18, 2003 1:32 PM
To: [EMAIL PROTECTED]
Subject: instance variables?


Hi all,

I stumbled across something called BlueJ which provides a user-friendly
graphical environment in which to learn OO-programming, Java-style. I think
this is a great "parallel universe" to go along with the Perl Objects book.

I started re-writing one of the first exercises as a Perl package:
[question follows below]

package TicketMachine;
# etc.

=head1 DESCRIPTION
TicketMachine models a naive ticket machine that issues
flat-fare tickets.

The price of a ticket is specified via the constructor.

[Based on an exercise from "Objects First With Java:
A Practical Introduction Using BlueJ.]
=cut

# my $price;        # Price of a ticket from this machine.
# my $balance;      # Amount of money entered by customer
# my $total;        # Total amount of money collected by machine


# Create a machine that issues tickets of the given price.
# Price must be greater than zero (but no checks done).
sub new {
    my $class = shift;

    # In the BlueJ environment instances are automatically
    # named "behind the scenes" (so far)...
    my $instance = "tm" . int(rand(25));

    my $self = { Name => $instance, Price => shift };
    bless $self, $class;
}

sub getPrice {
    my $self = shift;
    return $self->{Price};
}

# more methods to come...

1;

__END__

In the Java version, the three variables are declared in the class first:
    private int price;
    private int balance;
    private int total;

So in Perl I tried declaring these in the package using my, but they seemed
to remain class variables, so if I would do something like:

for (@ticket_machines) {
  print "A ticket costs ", $_->getPrice(), " cents.\n";
} 

I would then get (for two machines):

A ticket costs 100 cents.
A ticket costs 100 cents.


Then I tried this with Perl...

In the "new" constructor:

   my $class = shift;
   my $price = shift;
   my $self = $instance;
   bless \$self, $class, $price;

...I was told "too many arguments to bless". The Perl Objects book says the
easiest way to use more data with an instance is with a blessed hash
reference, and that did work fine (and maybe that's the best way).

But I'm wondering if there is another way (like the Java "private variable")
to say "all class variables declared here are unique to each instance"? 

It occurs to me that perhaps the difference is that in Perl you can call
methods on a class (i.e. the "an unnamed horse" from the Perl Objects book)
but not in Java (other than the contructor method)?

(If anyone is interested in BlueJ -> www.bluej.org)

-K

-- 
Kevin Pfeiffer
International University Bremen



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to