develooper Front page | perl.perl6.language | Postings from January 2002

Re: fixed-sized output records

Thread Previous | Thread Next
From:
Aaron Sherman
Date:
January 2, 2002 11:47
Subject:
Re: fixed-sized output records
Message ID:
20020102144712.B16474@ajs.com
On Wed, Jan 02, 2002 at 12:41:47PM -0500, Tzadik Vanderhoof wrote:

> There is a (relatively) new feature of the $/ variable which allows you to
> set it to a numeric reference, i.e:
>  
> $/ = \80;

This is good and useful because the semantics of <> are inherently
record-oriented. In the past, those records have been delimited, not
fixed-length. This just adds a new mode, not a new semantic.

[...]
> but it always bothered me that it was not symmetrically applied to $\.  In
> other words, you can't say:
>  
> $\ = \80;
>  
> to make your *output* records (i.e. "print") fixed-length. 

Ah, here's the rub. Output is different beast. When you stop at 
80 characters of input, the rest just sits there waiting for the next
read. For output, I see too many ways that you might want to respond
to:

	require 5.0;
	$io = IO::File->new(">foo") or die "foo: $!";
	IO::File::output_record_separator(\01);
	$io->print("12");

One result is to truncate the input and return the length of what you
printed. This is in keeping with write()'s behavior in the face
of a partial write. On the other hand, you might expect the extra
data to be buffered for the next write (this is in keeping with stdio's
behavior on sockets and other fixed-message-length handles).
A third expectation would be a run-time error, which could be
trapped with eval.

Your feature is interesting, but I would expect it to have a new
name, e.g.:

	require 6.0;
	my $io is IO::File(">foo") or die "foo: $!";
	$io.output_record_length(2);
	$io.output_record_separator("\0"); # Pad with nuls
	$io.output_record_mode(IO_MODE_TRUNCATE);
	$io.print("12");

> It just seems logical that if there is direct support for *reading* fixed
> length records, there should be analogous support for *writing* them as
> well.

Analogous, yes. Identical, no.

Then again, you could accomplish this today, simply by sub-classing
IO::File, e.g.:

	package IO::File::Fixed;
	require 5.0;
	require Exporter;
	use IO::File;
	@ISA=qw(Exporter IO::File);
	@EXPORT=qw(IO_MODE_TRUNCATED IO_MODE_NONE);@EXPORT_OK=();
	use constant IO_MODE_NONE => 0;
	use constant IO_MODE_TRUNCATED => 1;
	my $reclen = undef;
	my $mode = IO_MODE_NONE;
	sub output_record_length(;$) {
	  my $old = $reclen;
	  if (@_) {
	    $reclen = shift;
	    $mode = IO_MODE_NONE unless defined $reclen;
	  }
	  $reclen = shift if @_;
	  return $old;
	}
	sub output_record_mode($) {
	  my $old = $mode;
	  $mode = shift;
	  return $old;
	}
	sub print {
	  my $self = shift;
	  if ($mode == IO_MODE_NONE) {
	    return $self->SUPER::print(@_);
	  } elsif ($mode eq IO_MODE_TRUNCATE) {
	    # ... concat params, truncate or pad with sep, and call SUPER::print
	  } else {
	    croak "Unsupported mode";
	  }
	}
	1;

This might be the better solution, since there are many sorts of
structured data that one might want to support, and that means that the
right thing to do would be to create a class that was generic enough
to, in turn, be sub-classed for all sorts of specialized structured
data.


-- 
Aaron Sherman
ajs@ajs.com		finger ajskey@b5.ajs.com for GPG info. Fingerprint:
www.ajs.com/~ajs	6DC1 F67A B9FB 2FBA D04C  619E FC35 5713 2676 CEAF
  "Write your letters in the sand for the day I'll take your hand
   In the land that our grandchildren knew." -Queen/_'39_

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About