---
name: "Badger::Prototype"
section: "3pm"
platform: "linux"
package: "libbadger-perl"
version: "0.16-3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Badger::Prototype"
---

# Badger::Prototype(3pm)

base class for creating prototype classes

## NAME

Badger::Prototype - base class for creating prototype classes

## SYNOPSIS

```
    package Badger::Example;
    use base 'Badger::Prototype';

    sub greeting {
        my $self = shift;

        # get prototype object if called as a class method
        $self = $self->prototype() unless ref $self;

        # continue as normal, now $self is an object
        if (@_) {
            # set greeting if called with args
            return ($self->{ greeting } = shift);
        }
        else {
            # otherwise get greeting
            return $self->{ greeting };
        }
    }
```

## DESCRIPTION

This module is a subclass of Badger::Base that additionally provides the **prototype()** method.  It is used as a base class for modules that have methods that can be called as either class or object methods.

```
    # object method
    my $object = Badger::Example->new();
    $object->greeting('Hello World');
    # class method
    Badger::Example->greeting('Hello World');
```

The **prototype()** method returns a singleton object instance which can be  used as a default object by methods that have been called as class methods.

Here's an example of a `"greeting()"` method that can be called with an argument  to set a greeting message:

```
    $object->greeting('Hello World');
```

Or without any arguments to get the current message:

```
    print $object->greeting;            # Hello World
```

As well as being called as an object method, we want to be able to call it as a class method:

```
    Badger::Example->greeting('Hello World');
    print Badger::Example->greeting();  # Hello World
```

Here's what the `"greeting()"` method looks like.

```
    package Badger::Example;
    use base 'Badger::Prototype';

    sub greeting {
        my $self = shift;

        # get prototype object if called as a class method
        $self = $self->prototype() unless ref $self;

        # continue as normal, now $self is an object
        if (@_) {
            # set greeting if called with args
            return ($self->{ greeting } = shift);
        }
        else {
            # otherwise get greeting
            return $self->{ greeting };
        }
    }
```

We use `"ref $self"` to determine if `"greeting()"` has been called as an object method (`$self` contains an object reference) or as a class method (`$self` contains the class name, in this case `"Badger::Example"`). In the latter case, we call **prototype()** as a class method (remember, `$self` contains the `"Badger::Example"` class name at this point) to return a prototype  object instance which we then store back into `$self`.

```
        # get prototype object if called as a class method
        $self = $self->prototype() unless ref $self;
```

For the rest of the method we can continue as if called as an object  method because `$self` now contains a `"Badger::Example"` object either way.

Note that the prototype object reference is stored in the `$PROTOTYPE` variable in the package of the calling object's class.  So if you call prototype on a `"Badger::Example::One"` object that is subclassed from  `"Badger::Prototype"` then the prototype object will be stored in the  `$Badger::Example::One::PROTOTYPE` package variable.

## METHODS

### prototype(@args)

Constructor method to create a prototype object and cache it in the `$PROTOTYPE` package variable for subsequent use.  This is usually  called from inside methods that can operate as class or object methods,  as shown in the earlier example.

```
    sub example {
        my $self = shift;

        # upgrade $self to an object when called as a class method
        $self = $self->prototype() unless ref $self;

        # ...code follows...
    }
```

If you prefer a more succinct idiom and aren't too worried about calling the prototype method unnecessarily, then you can write it like this:

```
    sub greeting {
        my $self = shift->prototype;
        # ...code follows...
    }
```

If any arguments are passed to the `"prototype()"` method then it forces a new prototype object to be created, replacing any existing one cached in the `$PROTOTYPE` package variable.  The arguments are forwarded to the `"new()"` constructor method called to create the object.

If a single undefined value is passed as an argument then any existing prototype is released by setting the `$PROTOTYPE` package variable to  `"undef"`.  The existing prototype is then returned, or undef if there was no prototype defined.

### has\_prototype()

Returns true or false to indicate if a prototype is defined for a class. It can be called as a class or object method.

## AUTHOR

Andy Wardley \<http://wardley.org/\>

## COPYRIGHT

Copyright (C) 2006-2009 Andy Wardley.  All Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
