Skip to content

Commit

Permalink
Added a section to the Mojo "Traits" documentation to describe the
Browse files Browse the repository at this point in the history
Formattable trait, with an example of implementing both it and the
Stringable and Representable traits.

MODULAR_ORIG_COMMIT_REV_ID: e242bfc10b627374961d195ba27ac6d0618afb2e
  • Loading branch information
KenJones-Modular authored and modularbot committed Sep 13, 2024
1 parent abb89f7 commit 1b689ba
Showing 1 changed file with 108 additions and 20 deletions.
128 changes: 108 additions & 20 deletions docs/manual/traits.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -451,10 +451,11 @@
" - [`ComparableCollectionElement`](/mojo/stdlib/builtin/value/ComparableCollectionElement)\n",
" - [`Copyable`](/mojo/stdlib/builtin/value/Copyable)\n",
" - [`Defaultable`](/mojo/stdlib/builtin/value/Defaultable)\n",
" - [`Formattable`](/mojo/stdlib/utils/_format/Formattable)\n",
" - [`Formattable`](/mojo/stdlib/utils/format/Formattable)\n",
" - [`Hashable`](/mojo/stdlib/builtin/hash/Hashable)\n",
" - [`Indexer`](/mojo/stdlib/builtin/int/Indexer)\n",
" - [`Intable`](/mojo/stdlib/builtin/int/Intable)\n",
" - [`IntableRaising`](/mojo/stdlib/builtin/int/IntableRaising)\n",
" - [`KeyElement`](/mojo/stdlib/collections/dict/KeyElement)\n",
" - [`Movable`](/mojo/stdlib/builtin/value/Movable)\n",
" - [`PathLike`](/mojo/stdlib/os/pathlike/PathLike)\n",
Expand All @@ -465,6 +466,8 @@
" - [`Sized`](/mojo/stdlib/builtin/len/Sized)\n",
" - [`Stringable`](/mojo/stdlib/builtin/str/Stringable)\n",
" - [`StringableCollectionElement`](/mojo/stdlib/builtin/value/StringableCollectionElement)\n",
" - [`StringableRaising`](/mojo/stdlib/builtin/str/StringableRaising)\n",
" - [`StringRepresentable`](/mojo/stdlib/collections/string/StringRepresentable)\n",
" - [`Roundable`](/mojo/stdlib/builtin/math/Roundable)\n",
" - [`ToFormatter`](/mojo/stdlib/utils/_format/ToFormatter)\n",
" - [`Truncable`](/mojo/stdlib/builtin/_math/Truncable)\n",
Expand Down Expand Up @@ -514,50 +517,135 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### The `Intable` and `Stringable` traits\n",
"### The `Intable` and `IntableRaising` traits\n",
"\n",
"The [`Intable`](/mojo/stdlib/builtin/int/Intable) and \n",
"[`Stringable`](/mojo/stdlib/builtin/str/Stringable) traits identify types\n",
"that can be implicitly converted to `Int` and `String`, respectively. \n",
"The [`Intable`](/mojo/stdlib/builtin/int/Intable) trait identifies a type that\n",
"can be implicitly converted to `Int`. The\n",
"[`IntableRaising`](/mojo/stdlib/builtin/int/IntableRaising) trait describes a\n",
"type can be converted to an `Int`, but the conversion might raise an error.\n",
"\n",
"Any type that conforms to `Stringable` works with the built-in\n",
"[`print()`](/mojo/stdlib/builtin/io/print) and \n",
"[`str()`](/mojo/stdlib/builtin/str/str) functions:"
"Both of these traits require the type to implement the `__int__()` method. For\n",
"example:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This is a dog named Spot\n"
"True\n"
]
}
],
"source": [
"@value\n",
"struct Pet(Stringable):\n",
" var name: String\n",
" var type: String\n",
"struct Foo(Intable):\n",
" var i: Int\n",
"\n",
" fn __str__(self) -> String:\n",
" return \"This is a \" + self.type + \" named \" + self.name\n",
" fn __int__(self) -> Int:\n",
" return self.i\n",
"\n",
"var spot = Pet(\"Spot\", \"dog\")\n",
"print(spot)"
"var foo = Foo(42)\n",
"print(int(foo) == 42)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similarly, an `Intable` type works with the built-in \n",
"[`int`](/mojo/stdlib/builtin/int/int-function) function. You can find an example\n",
"in the [`Intable` API reference](/mojo/stdlib/builtin/int/Intable)."
"### The `Stringable`, `Representable`, and `Formattable` traits\n",
"\n",
"The [`Stringable`](/mojo/stdlib/builtin/str/Stringable) trait identifies a type\n",
"that can be implicitly converted to\n",
"[`String`](/mojo/stdlib/collections/string/String). The\n",
"[`StringableRaising`](/mojo/stdlib/builtin/str/StringableRaising) trait\n",
"describes a type that can be converted to a `String`, but the conversion might\n",
"raise an error. Any type that conforms to `Stringable` or `StringableRaising`\n",
"also works with the built-in [`str()`](/mojo/stdlib/builtin/str/str) function to\n",
"explicitly return a `String`. These traits also mean that the type can support\n",
"both the `{!s}` and `{}` format specifiers of the `String` class'\n",
"[`format()`](/mojo/stdlib/collections/string/String#format) method. These traits\n",
"require the type to define the\n",
"[`__str__()`](/mojo/stdlib/builtin/str/Stringable#__str__) method.\n",
"\n",
"In contrast, the [`Representable`](/mojo/stdlib/builtin/repr/Representable)\n",
"trait that defines a type that can be used with the built-in\n",
"[`repr()`](/mojo/stdlib/builtin/repr/repr) function, as well as the `{!r}`\n",
"format specifier of the `format()` method. This trait requires the type to\n",
"define the [`__repr__()`](/mojo/stdlib/builtin/repr/Representable#__repr__)\n",
"method, which should compute the \"official\" string representation of a type. If\n",
"at all possible, this should look like a valid Mojo expression that could be\n",
"used to recreate a struct instance with the same value.\n",
"\n",
"The [`StringRepresentable`](/mojo/stdlib/collections/string/StringRepresentable)\n",
"trait denotes a trait composition of the `Stringable` and `Representable`\n",
"traits. It requires a type to implement both a `__str__()` and a `__repr__()`\n",
"method.\n",
"\n",
"The [`Formattable`](/mojo/stdlib/utils/format/Formattable) trait describes a\n",
"type that can be converted to a stream of UTF-8 encoded data by writing to a\n",
"formatter object. The [`print()`](/mojo/stdlib/builtin/io/print) function\n",
"requires that its arguments conform to the `Formattable` trait. This enables\n",
"efficient stream-based writing by default, avoiding unnecessary intermediate\n",
"String heap allocations.\n",
"\n",
"The `Formattable` trait requires a type to implement a\n",
"[`format_to()`](/mojo/stdlib/utils/format/Formattable#format_to) method, which\n",
"is provided with an instance of\n",
"[`Formatter`](/mojo/stdlib/utils/format/Formatter) as an argument. You then\n",
"invoke the `Formatter` instance's\n",
"[`write()`](/mojo/stdlib/utils/format/Formatter#write) method to write a\n",
"sequence of `Formattable` arguments constituting the `String` representation of\n",
"your type.\n",
"\n",
"While this might sound complex at first, in practice you can minimize\n",
"boilerplate and duplicated code by using the [`String.format_sequence()`](/mojo/stdlib/collections/string/String#format_sequence) static function to\n",
"implement the type's `Stringable` implementation in terms of its `Formattable`\n",
"implementation. Here is a simple example of a type that implements all of the\n",
"`Stringable`, `Representable`, and `Formattable` traits:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dog(name='Rex', age=5)\n",
"Dog(Rex, 5)\n",
"String: Dog(Rex, 5)\n",
"Representation: Dog(name='Rex', age=5)\n"
]
}
],
"source": [
"@value\n",
"struct Dog(Stringable, Representable, Formattable):\n",
" var name: String\n",
" var age: Int\n",
"\n",
" fn __repr__(self) -> String:\n",
" return \"Dog(name=\" + repr(self.name) + \", age=\" + repr(self.age) + \")\"\n",
"\n",
" fn __str__(self) -> String:\n",
" return String.format_sequence(self)\n",
"\n",
" fn format_to(self, inout writer: Formatter) -> None:\n",
" writer.write(\"Dog(\", self.name, \", \", self.age, \")\")\n",
"\n",
"var dog = Dog(\"Rex\", 5)\n",
"print(repr(dog))\n",
"print(dog)\n",
"\n",
"var dog_info = String(\"String: {!s}\\nRepresentation: {!r}\").format(dog, dog)\n",
"print(dog_info)"
]
},
{
Expand Down

0 comments on commit 1b689ba

Please sign in to comment.