defmodule StringFormatting do
defmodule Point do
defstruct x: 0, y: 0
end
def run do
# Elixir offers several ways to format general values.
# For example, this prints an instance of our Point struct.
p = %Point{x: 1, y: 2}
IO.puts("struct1: #{inspect(p)}")
# If the value is a struct, the inspect function will
# include the struct's field names by default.
IO.puts("struct2: #{inspect(p, pretty: true)}")
# The :structs option can be used to control how structs are printed.
IO.puts("struct3: #{inspect(p, structs: false)}")
# To print the type of a value, use the __struct__ attribute for structs,
# or the built-in is_* functions for primitives.
IO.puts("type: #{p.__struct__}")
# Formatting booleans is straightforward.
IO.puts("bool: #{true}")
# There are many options for formatting integers.
# Use to_string for standard base-10 formatting.
IO.puts("int: #{to_string(123)}")
# This prints a binary representation.
IO.puts("bin: #{Integer.to_string(14, 2)}")
# This prints the character corresponding to the given integer.
IO.puts("char: #{<<33>>}")
# Base.encode16 provides hex encoding.
IO.puts("hex: #{Base.encode16(<<456::16>>, case: :lower)}")
# There are also several formatting options for floats.
# For basic decimal formatting use to_string.
IO.puts("float1: #{to_string(78.9)}")
# :erlang.float_to_binary can be used for more control over float formatting.
IO.puts("float2: #{:erlang.float_to_binary(123400000.0, [:scientific, decimals: 6])}")
IO.puts("float3: #{:erlang.float_to_binary(123400000.0, [:scientific, decimals: 6])}")
# For basic string printing, just use string interpolation.
IO.puts("str1: #{"\"string\""}")
# To include quotes, you can use the inspect function.
IO.puts("str2: #{inspect("string")}")
# Base.encode16 can be used to render the string in base-16.
IO.puts("str3: #{Base.encode16("hex this", case: :lower)}")
# To print a representation of a reference, use inspect.
IO.puts("reference: #{inspect(make_ref())}")
# When formatting numbers you will often want to control the width and precision.
# You can use String.pad_leading for this.
IO.puts("width1: |#{String.pad_leading(to_string(12), 6)}|#{String.pad_leading(to_string(345), 6)}|")
# For floats, you can use :erlang.float_to_binary and then pad the result.
IO.puts("width2: |#{String.pad_leading(:erlang.float_to_binary(1.2, decimals: 2), 6)}|#{String.pad_leading(:erlang.float_to_binary(3.45, decimals: 2), 6)}|")
# To left-justify, use String.pad_trailing instead.
IO.puts("width3: |#{String.pad_trailing(:erlang.float_to_binary(1.2, decimals: 2), 6)}|#{String.pad_trailing(:erlang.float_to_binary(3.45, decimals: 2), 6)}|")
# You can also control width when formatting strings.
IO.puts("width4: |#{String.pad_leading("foo", 6)}|#{String.pad_leading("b", 6)}|")
# To left-justify strings, use String.pad_trailing.
IO.puts("width5: |#{String.pad_trailing("foo", 6)}|#{String.pad_trailing("b", 6)}|")
# So far we've seen IO.puts, which prints the formatted string.
# You can use string interpolation or Kernel.to_string to format without printing.
s = "sprintf: a #{to_string("string")}"
IO.puts(s)
# You can format+print to IO devices other than :stdio using IO.write.
IO.write(:stderr, "io: an #{to_string("error")}\n")
end
end
StringFormatting.run()