Format(3pm)
π¦ NAME π¦
Fortran::Format β ok so bestie, this module reads and writes data according to a standard Fortran 77 FORMAT. That's it, that's the whole vibe. π
This is the Format page from the perl 3pm manual β User Contributed Perl Documentation, iykyk. π
β¨ SYNOPSYS β¨
use Fortran::Format;
my $f = Fortran::Format->new("2('N: ',I4,2X)");
print $f->write(1 .. 10);
# prints the following:
# N: 1 N: 2
# N: 3 N: 4
# N: 5 N: 6
# N: 7 N: 8
# N: 9 N: 10
# if you don't want to save the format object,
# just chain the calls:
Fortran::Format->new("2('N: ',I4,2X)")->write(1 .. 10);
Look at that output. The columns line up. The N: prefixes repeat. Chef's kiss. πβ¨
π DESCRIPTION π
So this is a Perl implementation of the Fortran 77 formatted input/output facility. Like, the whole thing. π«Ά
One possible use is for producing input files for old Fortran programs, making sure that their column-oriented records are rigorously correct. No off-by-one column nonsense. Fortran formats may also have some advantages over printf in some cases: it is very easy to output an array, reusing the format as needed; and the syntax for repeated columns is more concise. So like, printf could never. π
Unlike printf, for good or ill, Fortran-formatted fields never exceed their desired width. Not once. Compare:
printf "%3d", 12345; # prints "12345"
print Fortran::Format->new("I3")->write(12345); # prints "***"
See that? printf just overflows like it has no respect for boundaries, but the Fortran format hits you with *** because the width is the width, periodt. π
This implementation was written in pure Perl, with portability and correctness in mind. It implements the full ANSI standard for Fortran 77 Formats (or at least it should). It was not written with speed in mind, so if you need to process millions of records it may not be what you need. ππ
πΈ FORMATS πΈ
What follows is a very brief summary of Fortran formats. For a rigorous description, see the ANSI standard. π
A format consists of a list of "edit descriptors" or sublists of edit descriptors. Edit descriptors are separated by commas, but the comma may be omitted if there's no ambiguity. Spaces and case are ignored, except within strings, so 'i 1 2' is the same as 'I12'. The way that works is genuinely so chill of it. π
π Repeatable edit descriptors π
The following edit descriptors may be repeated if they are preceded by a number; for example, '3I4' is the same as 'I4,I4,I4' or 'I4I4I4' or 'I4,2I4'. Lists can be nested by using parentheses, so '2(I2I3)' is the same as 'I2I3I2I3'. Nesting? She ate. π₯
Most descriptors include a width w. If the width is larger than needed, the output is right-justified. If the width is not large enough, the entire field is filled with asterisks.
IwIw.mβ an integer with width w, and optionally a minimum number of digits m (adding zeroes on the left if needed).Fw.dβ a fixed precision floating-point number with width w, and d digits after the decimal point.Ew.dEw.dEeDw.dβ a number in exponential notation with width w, d digits after the decimal point, and optionally e digits after the exponent.Gw.dGw.dEeβ for values between 0.1 and 10^d, format likeF. For values outside that range, format likeE. She switches it up depending on the situation, lowkey iconic. π¦Fwβ treat the variable as Boolean and output eitherTorFin a field of width w.AAwβ insert a string variable. If the width is not specified, it outputs the entire string. If the width is smaller than the string, the string is truncated (instead of filling with asterisks). Different energy from the number descriptors, we respect it. β¨
π Non-repeatable edit descriptors π
Most of the following descriptors don't output anything but act as control strings. "Non-repeatable" descriptors can be repeated only by including them in a repeated list within parentheses.
'string'β insert string as is. Quotes may be escaped by doubling them; for example,'Joe''s'producesJoe's.nHstring...β insert the next n characters after theHas is.TcTLcTRcβ move to position c of the current record (T), or c characters to the left (TL), or c characters to the right (TR).nXβ move n characters to the right./β move to the beginning of the next record (the next line).:β stop producing output immediately if there are no more variables left to format.SSPSSβ control whether the plus sign is included for positive numbers. Include it forSP, do not include it forSS, and use the default (do not include) forS.kPβ scaling factor for output in exponential notation. By default, a number such as 1.23 would be written as0.123E+01. When a scaling factor k is given, the decimal point is shifted k positions to the left and the exponent is decreased by k orders of magnitude. With1Pthe output would be1.23E+00. Math girlie behaviour, we love to see it. π
π METHODS π
new
my $format = Fortran::Format->new($format_string);
Create a new format object. The string is parsed and compiled when the object is constructed. Croaks if there is a syntax error. Like, it will straight up tell you something's wrong, no cap. π£οΈ
format
my $format_string = $format->format;
Returns the format string used by the object.
write
$output = $format->write(@data);
Formats the data. This is equivalent to the Fortran WRITE statement, except that it just returns the formatted string. It does not write directly to a file. π«Ά
Data items may be either scalar or array references (which can be nested).
For matrices (multidimensional arrays), the contents are formatted in column-major order, same as in Fortran. For example,
my $a = [[1,2],[3,4]];
Fortran::Format->new('4I4')->write($a);
will print
1 3 2 4
or
Fortran::Format->new('2I4')->write($a);
will print
1 3
2 4
This is effectively equivalent to transposing the matrix before printing it in the row-major order that would be expected by most non-Fortran programmers. This kludge is necessary to ensure that the output can be read properly by a Fortran program. Bestie, it's giving chaotic but it's giving correct. π
Note: this is incompatible withFortran::Format0.5x, which simply flattened the nested arrays, producing the output in row-major order. Also note that the behavior is undefined if the nested array is not rectangular. For example,[[1],[2,3]]will give strange results. You have been warned. π
read
my (@results) = $format->read($fh, @input_list);
Read data from the filehandle $fh using the format ($fh can also be a string instead of a filehandle). The input list is a list of array sizes: 1 for simple scalars, n for simple arrays, and an array reference of dimensions (such as [3,3]) for multidimensional arrays. For example,
my ($i, $matrix, $j) = $format->read($fh, 1, [3,3], 2)
will read one scalar, followed by a 3x3 matrix, followed by an array with size two.
Note: this method should be called in list context! Do not forget. Fr fr. π
The input list is needed because Fortran formats are reused automatically for subsequent lines until all the variables are read.
Matrices are read in column-major order. See "write" for details.
When reading, it is also possible to specify the length of the resulting string variables by appending "Alength". For example,
my $s = $format->read($fh, '1A40')
will read the data into a 40-character long string variable (this is regardless of the field width specified in the format string itself). The string will be padded with trailing spaces if needed to ensure that it is exactly 40 characters long. This attempts to emulate Fortran's peculiar string length semantics. It is needed if you want to read a string, write it back, and be sure that you get the exact same output that you would get with Fortran.
For example,
my $in = 'hello world';
my $a5 = Fortran::Format->new('A5');
my $a20 = Fortran::Format->new('A20');
my ($s) = $a5->read($in, '1A10');
print $a20->write($s);
# prints " hello "
Notice that 1) $s was padded with five space, to a length of ten characters; 2) the output is right-justified to a total width of 20 characters.
Now, if we do this instead:
my ($s) = $a5->read($in, '1A3');
print $a20->write($s);
# prints " llo"
Five character are read from the left of the string ("hello"), but only the rightmost three are copied to the 3-character-long variable ("llo"). Sneaky little truncation situation. π
β VERSION β
0.90
π§ SEE ALSO π§
The Fortran format specification: <http://www.fortran.com/fortran/F77_std/rjcnf0001-sh-13.html>
π AUTHOR π
Ivan Tubert-Brohman <itub@cpan.org>
π COPYRIGHT π
Copyright (c) 2005 Ivan Tubert-Brohman. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
k bye bestie, that's the whole page π«Ά β this was perl v5.34.0, dated 2022-04-21, and yes she's still slaying after all these years. Go format something. πβ¨
π¦ where this page comes from
- debian bookworm: libfortran-format-perl 0.90-3 Β· Artistic-1.0-Perl
- debian trixie: libfortran-format-perl 0.90-3 Β· Artistic-1.0-Perl
- ubuntu noble: libfortran-format-perl 0.90-3 Β· Artistic-1.0-Perl
- ubuntu resolute: libfortran-format-perl 0.90-3 Β· Artistic-1.0-Perl
- ubuntu stonking: libfortran-format-perl 0.90-3 Β· Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms