Perl read_config sub, oop o no?
Domanda
Ho un pacchetto (in realtà solo una subroutine) che uso spesso per file di configurazione parse ecc Fondamentalmente sembra che questo:
sub get_settings {
my %config;
my $config = 'path...';
unless(-r $config) {
die("Couldn't read config");
}
open CONFIG, '<', $config or die $!;
while(<CONFIG>) {
next if (($_ eq "\n") or /^\;/);
chomp;
my($setting, $value) = split(/=/, $_);
$config{$setting} = $value;
}
return %config;
}
piuttosto semplice, ma mi chiedevo come (e se) questo potrebbe / dovrebbe essere riscritta a OOP ? In realtà solo per l'apprendimento, non è mai abbastanza visto quando e perché utilizzare benedire . =)
Grazie!
Soluzione
La risposta alla domanda ha più a che fare con i programmi che si sta utilizzando il pacchetto in che con il pacchetto stesso.
Se questo è un abbastanza grande OOP basato apps / script allora ha sicuramente senso per OOP, perché questo è ciò che le aspetta clienti (le applicazioni e le persone che scrivono queste apps / script). Anche avere librerie di stili imperativi sporgono come un pollice dolente e creano la complessità.
Al contrario, se il pacchetto viene utilizzato in più brevi script imperative, quindi un'interfaccia OOP in conflitto con le aspettative del cliente (vale a dire gli script + gente li via di sviluppo).
Forse si sta eseguendo la migrazione tra gli approcci (ad esempio, lo script di diventare grande e poco maneggevole e bisogno di essere meglio organizzati, magari con OOP) in quel caso un impostazioni / config tipo di classe è un buon posto per iniziare in quanto tendono ad essere ben separati e hanno chiare linee di responsabilità.
In breve:. Fare quello che ha più senso in cui viene utilizzato il pacchetto
Altri suggerimenti
Ecco (si spera!) Un semplice esempio di OO basato config astrazione utilizzando:
NB. È possibile utilizzare altri moduli o anche rotolare il proprio. Qui di seguito serve solo come esempio generale.
RoomConfig.pm
package RoomConfig;
use Moose;
with 'MooseX::SimpleConfig';
has doors => (is => 'rw', isa => 'Int', required => 1);
has windows => (is => 'rw', isa => 'Int', default => sub {0});
1;
di cui sopra è la nostra classe OO config. Tutto è perfettamente dichiarato in modo da sapere con chiarezza che sono disponibili e valide opzioni di configurazione, vale a dire. la sua auto documentazione.
Quindi, per creare un room
da un file di configurazione potrebbe essere:
use RoomConfig;
my $box_room = RoomConfig->new_with_config( configfile => 'box_room.yaml' );
Perché la sua una classe Posso anche un'istanza di un room
senza un file di configurazione:
my $cupboard = RoomConfig->new( doors => 1 );
my $utility_room = RoomConfig->new( doors => 2 );
my $master_bedroom = RoomConfig->new(
doors => 1,
windows => 2, # dual aspect
);
E con questi moduli particolari otteniamo funzioni extra, come questo:
# below throws exception because room must have a door!
my $room_with_no_door_or_window = RoomConfig->new;
Così la mia configurazione può facilmente venire da un file di configurazione o impostando attributi.
E possiamo andare oltre, estendendo la nostra configurazione per i diversi tipi di rooms
:
BathRoomConfig.pm
package BathRoomConfig;
use Moose;
extends 'RoomConfig';
has loos => (is => 'rw', isa => 'Int', default => sub {0});
has sinks => (is => 'rw', isa => 'Int', default => sub {0});
has baths => (is => 'rw', isa => 'Int', default => sub {1});
1;
E se abbiamo usato questo config (bathroom.yaml):
doors: 1
windows: 1
bath: 1
loos: 1
sinks: 2
Poi si potrebbe fare questo:
use BathRoomConfig;
my $upstairs_bathroom = BathRoomConfig->new_with_config(
configfile => 'bathroom.yaml'
);
my $closet_room = BathRoomConfig->new_with_config(
configfile => 'bathroom.yaml',
baths => 0,
sinks => 1,
windows => 0,
);
Si noti che le marche $closet_room
uso di entrambi i file di configurazione e gli attributi di impostazione.
Si noti inoltre che se il mio file di configurazione non ha avuto doors
(es. Proprietà richiesto) allora avrebbe gettato un errore su new_with_config
.
E infine possiamo trovare introspezione nostra classe di configurazione definita a portata di mano:
use RoomConfig;
say "RoomConfig provides the following options:";
for my $attr (RoomConfig->meta->get_attribute_list) {
next if $attr eq 'configfile';
say '-> ', $attr;
}
Ora non v'è nulla che possa impedire che si implementare la maggior parte di questo in un pacchetto di configurazione standard in modo, alla fine della giornata i suoi soli cavalli per i corsi!
Tuttavia la facilità di gestione di tutto questo è molto più facile con OO e le caratteristiche che questi moduli già scritto forniscono è grande vantaggio specialmente in progetti più grandi.
E 'possibile dare un'occhiata al codice sorgente da moduli su CPAN. Per esempio Config :: Generale dovrebbe rispondere alle vostre domande ...