sub new { my ($class, %args) = @_; $self->_foo($args{foo}); $self->_bar($args{bar}); ... ... ... ... } sub _foo { # essentially these methods are setter/getters with # a bit of sanity checking on the param } sub bar { ... } sub ... #### BEGIN { $param_map = { channel => \%mux, queue => \%queue, polarity => \%polarity, rate => \%rate, mode => \%mode, gain => \%gain, }; no strict 'refs'; for my $sub (keys %$param_map) { *$sub = sub { my ($self, $opt) = @_; if (defined $opt) { if (! exists $param_map->{$sub}{$opt}) { die "$sub param requires an integer\n"; } $self->{$sub} = $param_map->{$sub}{$opt}; } my $default = "DEFAULT_" . uc $sub; my $max = "MAX_" . uc $sub; $self->{$sub} = __PACKAGE__->$default if ! defined $self->{$sub}; $self->_bit_set($self->{$sub}, __PACKAGE__->$max); return $self->{$sub}; } } }