Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

oop, variable that counts the number of objects created

by Anonymous Monk
on Jul 30, 2020 at 03:21 UTC ( [id://11120047]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a package car. What i need is a variable that counts the number of objects derived from this class. Say i have a car rental company and want to keep track of the number of cars being rented, each time a car object is being created means 1 car has been rented. I have been looking on the internet but can't find anything. How can i do this(if possible at all)? Here is the car.pm file:

use strict; use warnings; package car; sub new { my $class = shift; my $self = { name => shift, price => shift, speed => 0 }; print "Object car being created:\n"; print "Name: $self->{name}\n"; print "price: $self->{price}\n\n"; bless $self, $class; return $self; } sub speed_up{ my $self = shift; my $acc = shift; $self->{speed} += $acc; return $self->{speed}; } sub slow_down{ my $self = shift; my $acc = shift; $self->{speed} -= $acc; return $self->{speed}; } 1;

Here is an example of a belonging .pl file:

use strict; use warnings; use car; my $speed; my $auto = new car("Opel Vectra",50000); $speed = $auto->speed_up(25); print "Speed is: $speed km\n"; $speed = $auto->speed_up(10); print "Speed is: $speed km\n"; $speed = $auto->slow_down(20); print "Speed is: $speed km\n";

Replies are listed 'Best First'.
Re: oop, variable that counts the number of objects created
by choroba (Cardinal) on Jul 30, 2020 at 07:25 UTC
    You can create a lexical variable in the class that gets incremented in the constructor and decremented in the destructor. A class closure method makes this value accessible from outside. Don't forget to call SUPER::new in child classes.

    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { package Car; my $count; sub new { my ($class, $name, $price) = @_; my $self = {name => $name, price => $price, speed => 0}; say 'Object car being created:'; say "Name: $name"; say "Price: $price\n"; ++$count; return bless $self, $class } sub speed_up { my ($self, $acc) = @_; return $self->{speed} += $acc } sub slow_down { my ($self, $acc) = @_; return $self->{speed} -= $acc } sub DESTROY { say 'Scrap!'; --$count } sub count { return $count } } { package Car::GeneralMotors::Firebird; use parent -norequire => 'Car'; sub new { my ($class, $price) = @_; $class->SUPER::new('General Motors Firebird', $price); } } my @cars; for (1 .. 10) { push @cars, 'Car'->new('Peel P50', 176_000); } splice @cars, 0, 5; say 'Car'->count; say 'It works for subclasses, too:'; my $f = 'Car::GeneralMotors::Firebird'->new(200_000); say 'Car'->count; undef $f; say 'Car'->count;

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      the only problem I see with this (and the other similar) is that it associates the count decrement with DESTROY which assumes "car-life" and "object-life" are the same but may not be.

Re: oop, variable that counts the number of objects created
by tobyink (Canon) on Jul 30, 2020 at 09:40 UTC

    Just a random example using Zydeco...

    use Zydeco prefix => 'App'; class Car { has name ( type => Str ); has price ( type => Num ); has speed ( type => Num, default => 0, handles_via => 'Number', handles => { speed_up => 'add', slow_down => 'sub', }, ); my $count; method BUILD { ++$count } method DEMOLISH { --$count } method count { $count } } my $red_car = App->new_car( name => 'Red' ); my $blue_car = App->new_car( name => 'Blue' ); $red_car->speed_up( 25 ); $red_car->speed_up( 10 ); say $red_car->speed; say App::Car->count;
      not germane to OP but generally relevant

      Nice to see this example. I should probably ask this in another thread, but what's the obsession with has? Can't we (everyone not just your modules) just have blocks all the way down or superficially support something that's familiar to JAVA programmers? At this point we're just cargo culting a failed declarative approach (IMO). What are we getting beyond classic Perl OO? (sincerely want to break this down for the benefit of the overall discussion):

      • protected methods
      • strong types/checking
      • strong data encapsulation
      What else? If this has been hashed out before (a true breakdown), I'd be satisfied with a link. TY!

        Why would declaring object member variables with blocks be familiar to Java programmers?

        # Java class Car { public String name; public int price; public int speed; } # Zydeco class Car { has name ( type => Str ); has price ( type => Int ); has speed ( type => Int ); }

        Where would you add blocks to the Zydeco example to make it more like Java?

Re: oop, variable that counts the number of objects created
by perlfan (Vicar) on Jul 30, 2020 at 03:35 UTC
    my $auto = new car("Opel Vectra",50000);
    Do:
    my $auto = car->new("Opel Vectra",50000);
    Create a container class that provides methods meant for groups of cars. Add a license plate (UUID) field to the Car class. You can even support sub classes of Car (package names should start with an upper case letter) using polymorphism.

    Code not tested or fully complete but you get the gist. Note: it requires you pass it Car instances. You could get fancy and roll that up in it, but I wouldn't personally.

    use strict; use warnings; package Garage; sub new { my $pkg = shift; my $self = { all_cars => {}, # store cars key'd by license plate (uuid) } blese $self, $pkg; return $self; } sub add_car { my ($self, $car) = $@; #... add car key'ed by license plate or uuid } sub del_car { my ($self, $uuid) = $@ delete $self->get_cars->{$uuid}; } sub get_cars { my $self = shift; return $self->{all_cars}; } sub get_car { my ($self, $uuid) = $@; my $cars = $self->get_cars; die "Car with plate $uuid is not in the garage!\n\n" if not $cars->{ +$uuid}; # die can throw a reference also, so there you can do the exc +eption thing in the caller return $cars->{$uuid}; } sub count_cars { my $self = shift; my $cars_ref = $self->get_cars; my $count = @{keys %$cars_ref}; return $count; } # add other "collective" methods 1;
    PS: nice you're not using an OOP framework, because you don't need one xD

    PPS: So I suggested the opposite of what you asked. But you can do the same with a "OutRented" container class. The point is to use a container class the has some knowledge of the class it's containing.

Re: oop, variable that counts the number of objects created
by jcb (Parson) on Jul 31, 2020 at 01:46 UTC

    A technique I used to allow testing code to verify correct object destruction of some classes that use weak references to break cycles was something like:

    package Whatever; sub new { my $class = shift; my $ob = {}; # ... { our $_total_constructed; $_total_constructed++ } bless $ob, $class } sub DESTROY { our $_total_destroyed; $_total_destroyed++ }

    The test scripts can then access those package variables and verify that $Whatever::_total_constructed and $Whatever::_total_destroyed are equal at the end of a test run after the last lexical holding an object has gone out of scope.

Re: oop, variable that counts the number of objects created
by Anonymous Monk on Jul 30, 2020 at 10:33 UTC

    Thank you all for replying, you've made me a little bit wiser.

Re: oop, variable that counts the number of objects created
by karlgoethebier (Abbot) on Jul 30, 2020 at 10:39 UTC

    Possibly overkill but MCE::Shared::Scalar might be an option. And yes, I would use a framework. You may take a look at Class::Tiny and Role::Tiny. Regards, Karl P.S.: Consider a Porsche instead of a Firebird.

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11120047]
Approved by Marshall
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-03-28 14:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found