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

So I've got a config file, with something like this in it:

ip_address: 10.0.1.17 user: me

Config file is used by a Server object:

package Server; use Carp; use Moose; use Modern::Perl; use Config::Simple; has 'cfg' => (is => 'ro', isa => 'HashRef', required => 1, writer => ' +_set_cfg' ); sub get { validate_pos( @_, {isa => 'Server', optional => 0},{type => SCALAR, +optional => 0} ); my $self = shift; my $key = shift; my $properties = $self->cfg; return $properties->{$key}; } around BUILDARGS => sub { # Load cfg file and set cfg attribute here }

So I create a Server object and access the cfg file values like so:

my $server = Server->new('config_file_name'); $server->get('ip_address');

This all works, but I want to get some practice doing some more advanced stuff with Moose. So I added use MooseX::SingletonMethod and the following BUILD method:

sub BUILD { my $self = shift; my $properties = $self->cfg; foreach my $prop (keys %$properties) { # check that the property doesn't already exist as a method croak "Server config file property '$prop' clashes with existing m +ethod. Aborting." if ($self->can($prop)); # create new method $self->add_singleton_method( $prop => sub { $properties->{$prop}; +} ); } }

Now I can get the ip address with $server->ip_address. Cool. But I'm wondering if there might be some unintended consequences of something like this might be (aside from security concerns of loading data from a config file).

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Singleton method wrappers for config file properties: Bad idea?
by haukex (Archbishop) on Apr 01, 2017 at 11:46 UTC

    Personally, I would write a class representing the configuration, give it the ability to load its properties from a file, and then give the server object an instance of this config object. This allows the normal subclassing etc. mechanisms, for example one could overload the methods to allow the config to be loaded from a database instead of a file. I don't really see the advantage of "singleton methods" here. If you want to avoid writing $server->config->ip_address, then you could give the server class some convenience methods, e.g. $server->ip_address just calls the aforementioned method.

      Yeah, good idea on turning it into a class. I've come to slowly learn that turning just about everything into a class is the way to go. Regarding the singleton methods, I think one big advantage is that every time I add a new property to the config file (I expect to have a couple dozen), I don't have to manually write a new accessor method.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        I don't have to manually write a new accessor method

        For a (mildly amusing) way to access values from a singleton config via methods, see using AUTOLOAD to access read-only data structures. But at the end, the core module Config.pm has all that is needed for a read-only config. Not everything has to be moosish.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
        I don't have to manually write a new accessor method.

        I don't think you necessarily do, either of these should work (untested):

        my @props = qw/ foo bar quz /; for my $name (@props) { has $name => ( is => 'ro', ... ); } # - or - has [@props] => ( is => 'ro', ... );

        Of course, if your config elements are different, then yeah, you'll have to account for those differences by adding new and different properties to your class for each one. That's part of the price you pay for using OO over a hashref, but you do gain some things (subclassing, argument checking, etc.).