Front page | perl.perl5.porters |
Postings from March 2013
Is there a module that provides an abstract record class?
Thread Next
From:
Tom Christiansen
Date:
March 29, 2013 11:18
Subject:
Is there a module that provides an abstract record class?
Message ID:
9859.1364555878@chthon
Hey guys,
My CPAN search-fu seems to be flagging, because I cannot find something
that surely must exist, and it seems a shame to re-implement a perfectly
functioning wheel if it already exists and I just don't know about it.
I wondered whether you knew of a somewhat generic, plug-in-able frameworky
class that allows you to read structured records from files of various
formats in a uniform fashion, and treat those records the same way using
some common interface. I'm betting it must already exist, but I could
find nothing on CPAN that seemed at all like what I am thinking of.
Ring any bells?
Details follow. . . .
The idea is that you would have to associate some other class with the
handle/file, one that knew the actual guts, and then call some special
record reading method:
$rec_obj = read_record($handle)
or even convert an existing string into one of these objects:
$rec_obj = string2record(RAW => $string, RECTYPE => "some type");
Just to use simple, at-hand examples:
1. open(my $handle, "<", "/etc/passwd");
my$fmt_obj = fetch_format("passwd"); # maybe type IO::Record::passwd
while (my $r = $fmt_obj->read_record($handle)) {
printf "%s uses %s\n", $r->{user}, $r->{shell};
print "pwent is $r\n";
}
2. open(my $handle, "< :raw :bytes", "/var/run/utmp");
my $fmt_obj = fetch_format("utmp"); # maybe type IO::Record::utmp
while (my $r = $fmt_obj->read_record($handle)) {
printf "%s is from %s\n", $r->{name}, $r->{user};
print "utmp entry is $r\n";
}
3. open(my $handle, "<", "/etc/termcap");
my $fmt_obj = fetch_format("termcap"); # maybe type IO::Record::termcap
while (my $r = $fmt_obj->read_record($handle)) {
printf "tcap ent %s uses %s and %s for stand-out pairs\n",
$r->{name}, $r->{so}, $r->{se};
my @fieldnames = $f->fields(); # this is ordered, and might have dups
printf "tcap ent %s has fields %s\n",
$r->{name}, join("," => @fieldnames);
}
The point is that once you can identify the *type* of the file's records,
there can be some dedicated subclass that knows how to get that particular
record format into some generic interface so that you can work with it
in a reasonably uniform way.
The reason I would like this is because I have already written a working
prototype of a program that essentially works this way:
% pwgrep '$gcos !~ /daemon/i && $shell !~ /sh\b/' /etc/passwd
which is really nothing more than this sort of thing:
% recgrep --rectype=passwd -e '$gcos !~ /daemon/i && $shell !~ /sh\b/' /etc/passwd
And I would like a nice generic approach to adding new record types. The
existing program has a hardcoded list of types, and that isn't how I want
to go with this. I want to be able to provide little, extensible
per-record subclasses that inherit from a common class that provides the
defined interface. The idea is to write as little new as possible when
defining a new record type.
This isn't actually for sysadmin files, but rather for a bunch of different
kinds of record types, some binary, some not, some multiline, some not,
some splittable and some unpackable, some with duplicate field names, some
not, &c &c &c.
Do you happen to know any existing module that addresses this sort
of record-based activity in some sort of a generic way?
Note that I am *not* asking about the namespace games and eval/precompile
bit of the recgrepper. I certainly know how to do that, and it works
just fine right now (there are @foo for dup fieldnames, BTW). Rather,
it is this sort of thing:
my $fmt_obj = fetch_format("arbitrary name");
my $rec_obj = $fmt_obj->read_record($handle);
that I am looking to piggy-back on existing work for. But I know of
none such out there. Anybody heard of anything like this?
thanks very much,
--tom
Thread Next
-
Is there a module that provides an abstract record class?
by Tom Christiansen