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 [EMAIL PROTECTED] finger [EMAIL PROTECTED] 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_