develooper Front page | perl.perl5.porters | Postings from March 2013

Is there a module that provides an abstract record class?

Thread Next
Tom Christiansen
March 29, 2013 11:18
Is there a module that provides an abstract record class?
Message ID:
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,


Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About