2023-11-14 09:39:10 +03:00
|
|
|
= Format Specifications
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Several Ruby core classes have instance method +printf+ or +sprintf+:
|
|
|
|
|
|
|
|
- ARGF#printf
|
|
|
|
- IO#printf
|
|
|
|
- Kernel#printf
|
|
|
|
- Kernel#sprintf
|
|
|
|
|
|
|
|
Each of these methods takes:
|
|
|
|
|
|
|
|
- Argument +format_string+, which has zero or more
|
|
|
|
embedded _format_ _specifications_ (see below).
|
|
|
|
- Arguments <tt>*arguments</tt>, which are zero or more objects to be formatted.
|
|
|
|
|
|
|
|
Each of these methods prints or returns the string
|
|
|
|
resulting from replacing each
|
|
|
|
format specification embedded in +format_string+ with a string form
|
|
|
|
of the corresponding argument among +arguments+.
|
|
|
|
|
|
|
|
A simple example:
|
|
|
|
|
|
|
|
sprintf('Name: %s; value: %d', 'Foo', 0) # => "Name: Foo; value: 0"
|
|
|
|
|
|
|
|
A format specification has the form:
|
|
|
|
|
|
|
|
%[flags][width][.precision]type
|
|
|
|
|
|
|
|
It consists of:
|
|
|
|
|
|
|
|
- A leading percent character.
|
|
|
|
- Zero or more _flags_ (each is a character).
|
|
|
|
- An optional _width_ _specifier_ (an integer).
|
|
|
|
- An optional _precision_ _specifier_ (a period followed by a non-negative integer).
|
|
|
|
- A _type_ _specifier_ (a character).
|
|
|
|
|
|
|
|
Except for the leading percent character,
|
|
|
|
the only required part is the type specifier, so we begin with that.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
== Type Specifiers
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
This section provides a brief explanation of each type specifier.
|
|
|
|
The links lead to the details and examples.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== \Integer Type Specifiers
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-01 20:26:42 +03:00
|
|
|
- +b+ or +B+: Format +argument+ as a binary integer.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifiers b and B}[rdoc-ref:format_specifications.rdoc@Specifiers+b+and+B].
|
2022-04-30 01:04:05 +03:00
|
|
|
- +d+, +i+, or +u+ (all are identical):
|
2022-05-01 20:26:42 +03:00
|
|
|
Format +argument+ as a decimal integer.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifier d}[rdoc-ref:format_specifications.rdoc@Specifier+d].
|
2022-05-01 20:26:42 +03:00
|
|
|
- +o+: Format +argument+ as an octal integer.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifier o}[rdoc-ref:format_specifications.rdoc@Specifier+o].
|
2022-05-01 20:26:42 +03:00
|
|
|
- +x+ or +X+: Format +argument+ as a hexadecimal integer.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifiers x and X}[rdoc-ref:format_specifications.rdoc@Specifiers+x+and+X].
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Floating-Point Type Specifiers
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-01 20:26:42 +03:00
|
|
|
- +a+ or +A+: Format +argument+ as hexadecimal floating-point number.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifiers a and A}[rdoc-ref:format_specifications.rdoc@Specifiers+a+and+A].
|
2022-05-04 23:04:36 +03:00
|
|
|
- +e+ or +E+: Format +argument+ in scientific notation.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifiers e and E}[rdoc-ref:format_specifications.rdoc@Specifiers+e+and+E].
|
2022-05-01 20:26:42 +03:00
|
|
|
- +f+: Format +argument+ as a decimal floating-point number.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifier f}[rdoc-ref:format_specifications.rdoc@Specifier+f].
|
2022-05-01 20:26:42 +03:00
|
|
|
- +g+ or +G+: Format +argument+ in a "general" format.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifiers g and G}[rdoc-ref:format_specifications.rdoc@Specifiers+g+and+G].
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Other Type Specifiers
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-01 20:26:42 +03:00
|
|
|
- +c+: Format +argument+ as a character.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifier c}[rdoc-ref:format_specifications.rdoc@Specifier+c].
|
2022-05-01 20:26:42 +03:00
|
|
|
- +p+: Format +argument+ as a string via <tt>argument.inspect</tt>.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifier p}[rdoc-ref:format_specifications.rdoc@Specifier+p].
|
2022-05-01 20:26:42 +03:00
|
|
|
- +s+: Format +argument+ as a string via <tt>argument.to_s</tt>.
|
2022-05-02 20:37:52 +03:00
|
|
|
See {Specifier s}[rdoc-ref:format_specifications.rdoc@Specifier+s].
|
2022-05-01 20:26:42 +03:00
|
|
|
- <tt>%</tt>: Format +argument+ (<tt>'%'</tt>) as a single percent character.
|
2022-05-04 23:04:36 +03:00
|
|
|
See {Specifier %}[rdoc-ref:format_specifications.rdoc@Specifier+-25].
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
== Flags
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
The effect of a flag may vary greatly among type specifiers.
|
|
|
|
These remarks are general in nature.
|
2022-05-04 23:04:36 +03:00
|
|
|
See {type-specific details}[rdoc-ref:format_specifications.rdoc@Type+Specifier+Details+and+Examples].
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Multiple flags may be given with single type specifier;
|
|
|
|
order does not matter.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>' '</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Insert a space before a non-negative number:
|
|
|
|
|
|
|
|
sprintf('%d', 10) # => "10"
|
|
|
|
sprintf('% d', 10) # => " 10"
|
|
|
|
|
|
|
|
Insert a minus sign for negative value:
|
|
|
|
|
|
|
|
sprintf('%d', -10) # => "-10"
|
|
|
|
sprintf('% d', -10) # => "-10"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>'#'</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Use an alternate format; varies among types:
|
|
|
|
|
|
|
|
sprintf('%x', 100) # => "64"
|
|
|
|
sprintf('%#x', 100) # => "0x64"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>'+'</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Add a leading plus sign for a non-negative number:
|
|
|
|
|
|
|
|
sprintf('%x', 100) # => "64"
|
|
|
|
sprintf('%+x', 100) # => "+64"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>'-'</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Left justify the value in its field:
|
|
|
|
|
|
|
|
sprintf('%6d', 100) # => " 100"
|
|
|
|
sprintf('%-6d', 100) # => "100 "
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>'0'</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Left-pad with zeros instead of spaces:
|
|
|
|
|
|
|
|
sprintf('%6d', 100) # => " 100"
|
|
|
|
sprintf('%06d', 100) # => "000100"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>'*'</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
Use the next argument as the field width:
|
|
|
|
|
|
|
|
sprintf('%d', 20, 14) # => "20"
|
|
|
|
sprintf('%*d', 20, 14) # => " 14"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== <tt>'n$'</tt> Flag
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-01 20:26:42 +03:00
|
|
|
Format the (1-based) <tt>n</tt>th argument into this field:
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
sprintf("%s %s", 'world', 'hello') # => "world hello"
|
|
|
|
sprintf("%2$s %1$s", 'world', 'hello') # => "hello world"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
== Width Specifier
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
In general, a width specifier determines the minimum width (in characters)
|
|
|
|
of the formatted field:
|
|
|
|
|
|
|
|
sprintf('%10d', 100) # => " 100"
|
2022-05-04 23:04:36 +03:00
|
|
|
|
2022-04-30 01:04:05 +03:00
|
|
|
# Left-justify if negative.
|
|
|
|
sprintf('%-10d', 100) # => "100 "
|
2022-05-04 23:04:36 +03:00
|
|
|
|
2022-04-30 01:04:05 +03:00
|
|
|
# Ignore if too small.
|
|
|
|
sprintf('%1d', 100) # => "100"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
== Precision Specifier
|
2022-05-04 23:04:36 +03:00
|
|
|
|
|
|
|
A precision specifier is a decimal point followed by zero or more
|
|
|
|
decimal digits.
|
|
|
|
|
|
|
|
For integer type specifiers, the precision specifies the minimum number of
|
|
|
|
digits to be written. If the precision is shorter than the integer, the result is
|
|
|
|
padded with leading zeros. There is no modification or truncation of the result
|
|
|
|
if the integer is longer than the precision:
|
|
|
|
|
|
|
|
sprintf('%.3d', 1) # => "001"
|
|
|
|
sprintf('%.3d', 1000) # => "1000"
|
2022-05-04 23:05:04 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
# If the precision is 0 and the value is 0, nothing is written
|
|
|
|
sprintf('%.d', 0) # => ""
|
|
|
|
sprintf('%.0d', 0) # => ""
|
|
|
|
|
|
|
|
For the +a+/+A+, +e+/+E+, +f+/+F+ specifiers, the precision specifies
|
|
|
|
the number of digits after the decimal point to be written:
|
|
|
|
|
|
|
|
sprintf('%.2f', 3.14159) # => "3.14"
|
|
|
|
sprintf('%.10f', 3.14159) # => "3.1415900000"
|
|
|
|
|
|
|
|
# With no precision specifier, defaults to 6-digit precision.
|
|
|
|
sprintf('%f', 3.14159) # => "3.141590"
|
|
|
|
|
|
|
|
For the +g+/+G+ specifiers, the precision specifies
|
|
|
|
the number of significant digits to be written:
|
|
|
|
|
|
|
|
sprintf('%.2g', 123.45) # => "1.2e+02"
|
|
|
|
sprintf('%.3g', 123.45) # => "123"
|
|
|
|
sprintf('%.10g', 123.45) # => "123.45"
|
2022-05-04 23:05:04 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
# With no precision specifier, defaults to 6 significant digits.
|
|
|
|
sprintf('%g', 123.456789) # => "123.457"
|
2022-05-04 23:05:04 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
For the +s+, +p+ specifiers, the precision specifies
|
|
|
|
the number of characters to write:
|
|
|
|
|
|
|
|
sprintf('%s', Time.now) # => "2022-05-04 11:59:16 -0400"
|
|
|
|
sprintf('%.10s', Time.now) # => "2022-05-04"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
== Type Specifier Details and Examples
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifiers +a+ and +A+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as hexadecimal floating-point number:
|
|
|
|
|
|
|
|
sprintf('%a', 3.14159) # => "0x1.921f9f01b866ep+1"
|
|
|
|
sprintf('%a', -3.14159) # => "-0x1.921f9f01b866ep+1"
|
|
|
|
sprintf('%a', 4096) # => "0x1p+12"
|
|
|
|
sprintf('%a', -4096) # => "-0x1p+12"
|
|
|
|
|
|
|
|
# Capital 'A' means that alphabetical characters are printed in upper case.
|
|
|
|
sprintf('%A', 4096) # => "0X1P+12"
|
|
|
|
sprintf('%A', -4096) # => "-0X1P+12"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifiers +b+ and +B+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
The two specifiers +b+ and +B+ behave identically
|
|
|
|
except when flag <tt>'#'</tt>+ is used.
|
|
|
|
|
2022-05-01 20:26:42 +03:00
|
|
|
Format +argument+ as a binary integer:
|
2022-04-30 01:04:05 +03:00
|
|
|
|
|
|
|
sprintf('%b', 1) # => "1"
|
|
|
|
sprintf('%b', 4) # => "100"
|
2022-05-04 23:04:36 +03:00
|
|
|
|
2022-04-30 01:04:05 +03:00
|
|
|
# Prefix '..' for negative value.
|
|
|
|
sprintf('%b', -4) # => "..100"
|
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
# Alternate format.
|
|
|
|
sprintf('%#b', 4) # => "0b100"
|
|
|
|
sprintf('%#B', 4) # => "0B100"
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier +c+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as a single character:
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
sprintf('%c', 'A') # => "A"
|
|
|
|
sprintf('%c', 65) # => "A"
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2024-06-09 04:11:06 +03:00
|
|
|
This behaves like String#<<, except for raising ArgumentError instead of RangeError.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier +d+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as a decimal integer:
|
|
|
|
|
|
|
|
sprintf('%d', 100) # => "100"
|
|
|
|
sprintf('%d', -100) # => "-100"
|
|
|
|
|
|
|
|
Flag <tt>'#'</tt> does not apply.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifiers +e+ and +E+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ in
|
|
|
|
{scientific notation}[https://en.wikipedia.org/wiki/Scientific_notation]:
|
|
|
|
|
|
|
|
sprintf('%e', 3.14159) # => "3.141590e+00"
|
|
|
|
sprintf('%E', -3.14159) # => "-3.141590E+00"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier +f+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as a floating-point number:
|
|
|
|
|
|
|
|
sprintf('%f', 3.14159) # => "3.141590"
|
|
|
|
sprintf('%f', -3.14159) # => "-3.141590"
|
|
|
|
|
|
|
|
Flag <tt>'#'</tt> does not apply.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifiers +g+ and +G+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ using exponential form (+e+/+E+ specifier)
|
|
|
|
if the exponent is less than -4 or greater than or equal to the precision.
|
|
|
|
Otherwise format +argument+ using floating-point form (+f+ specifier):
|
|
|
|
|
|
|
|
sprintf('%g', 100) # => "100"
|
|
|
|
sprintf('%g', 100.0) # => "100"
|
|
|
|
sprintf('%g', 3.14159) # => "3.14159"
|
|
|
|
sprintf('%g', 100000000000) # => "1e+11"
|
|
|
|
sprintf('%g', 0.000000000001) # => "1e-12"
|
|
|
|
|
|
|
|
# Capital 'G' means use capital 'E'.
|
|
|
|
sprintf('%G', 100000000000) # => "1E+11"
|
|
|
|
sprintf('%G', 0.000000000001) # => "1E-12"
|
|
|
|
|
|
|
|
# Alternate format.
|
|
|
|
sprintf('%#g', 100000000000) # => "1.00000e+11"
|
|
|
|
sprintf('%#g', 0.000000000001) # => "1.00000e-12"
|
|
|
|
sprintf('%#G', 100000000000) # => "1.00000E+11"
|
|
|
|
sprintf('%#G', 0.000000000001) # => "1.00000E-12"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier +o+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as an octal integer.
|
|
|
|
If +argument+ is negative, it will be formatted as a two's complement
|
|
|
|
prefixed with +..7+:
|
|
|
|
|
|
|
|
sprintf('%o', 16) # => "20"
|
|
|
|
|
|
|
|
# Prefix '..7' for negative value.
|
|
|
|
sprintf('%o', -16) # => "..760"
|
|
|
|
|
|
|
|
# Prefix zero for alternate format if positive.
|
|
|
|
sprintf('%#o', 16) # => "020"
|
|
|
|
sprintf('%#o', -16) # => "..760"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier +p+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as a string via <tt>argument.inspect</tt>:
|
|
|
|
|
|
|
|
t = Time.now
|
|
|
|
sprintf('%p', t) # => "2022-05-01 13:42:07.1645683 -0500"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier +s+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as a string via <tt>argument.to_s</tt>:
|
|
|
|
|
|
|
|
t = Time.now
|
|
|
|
sprintf('%s', t) # => "2022-05-01 13:42:07 -0500"
|
|
|
|
|
|
|
|
Flag <tt>'#'</tt> does not apply.
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifiers +x+ and +X+
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ as a hexadecimal integer.
|
|
|
|
If +argument+ is negative, it will be formatted as a two's complement
|
|
|
|
prefixed with +..f+:
|
|
|
|
|
|
|
|
sprintf('%x', 100) # => "64"
|
|
|
|
|
|
|
|
# Prefix '..f' for negative value.
|
|
|
|
sprintf('%x', -100) # => "..f9c"
|
|
|
|
|
|
|
|
# Use alternate format.
|
|
|
|
sprintf('%#x', 100) # => "0x64"
|
|
|
|
|
|
|
|
# Alternate format for negative value.
|
|
|
|
sprintf('%#x', -100) # => "0x..f9c"
|
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
=== Specifier <tt>%</tt>
|
2022-04-30 01:04:05 +03:00
|
|
|
|
2022-05-04 23:04:36 +03:00
|
|
|
Format +argument+ (<tt>'%'</tt>) as a single percent character:
|
|
|
|
|
|
|
|
sprintf('%d %%', 100) # => "100 %"
|
|
|
|
|
|
|
|
Flags do not apply.
|
2022-05-05 17:01:12 +03:00
|
|
|
|
2023-11-14 09:39:10 +03:00
|
|
|
== Reference by Name
|
2022-05-05 17:01:12 +03:00
|
|
|
|
|
|
|
For more complex formatting, Ruby supports a reference by name.
|
|
|
|
%<name>s style uses format style, but %{name} style doesn't.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 }) # => 1 : 2.000000
|
|
|
|
sprintf("%{foo}f", { :foo => 1 }) # => "1f"
|