A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Showing posts with label oo. Show all posts
Showing posts with label oo. Show all posts

Manual automatic accessors in Perl

If you don't have Moose, Mo* or Class::Accessor:

package Foo;

=head1 SYNOPSIS

    my $f = Foo->new(
        bar => 'rab',
        qux => 'xuq',
    );

=cut

use constant ACCESSOR_MAP => {
    'get_bar' => 'bar',
    'get_qux' => 'qux',
};

use constant ACCESSOR_ITEM => qw(ping ting zing);

sub new {
    my ( $c, %args ) = @_;
    my $class = ref $c || $c;
    bless {%args}, $class;
}

sub __mk_accessor {
    my ( $c, $name, $key ) = @_;
    $key ||= $name;
    my $pkg = ref $c || $c;
    my $sym = join( '::', $pkg, $name );
    no strict 'refs';
    *{$sym} = sub {
        my ($self) = @_;
        $self->{$key};
    };
}

# set up ping(), ting(), zing()
__PACKAGE__->__mk_accessor($_) foreach __PACKAGE__->ACCESSOR_ITEM;

# set up get_bar(), get_qux()
for my $k ( keys %{ __PACKAGE__->ACCESSOR_MAP } ) {
    my $v = __PACKAGE__->ACCESSOR_MAP->{$k};
    __PACKAGE__->__mk_accessor( $k, $v );
}

# not tested

Perl: Fix DBI::db->disconnect invalidates 1 active statement handle

Add this subroutine to the module:

sub DESTROY {
    my ($self) = @_;
    # Finish off our statement handle, so we don't get warnings like:
    # DBI::db->disconnect invalidates 1 active statement handle
    my $sth = $self->{data_handle};
    if (blessed($sth) && $sth->can('finish')) {
        $sth->finish;
    }
}

Making a Perl module

Object oriented convention in Perl:

sub new
{  
    my ($class, %params) = @_;
    my $self = \%params;
    bless $self => $class;
    return $self;
}

Perl OO

our @ISA = ('MyParent');

sub new {
        my $proto = shift;
        my $class = ref($proto) || $proto;
        my $self  = {};
        $self->{NAME}   = undef;
        $self->{AGE}    = undef;
        $self->{PEERS}  = [];
        bless ($self, $class);
        return $self;
}