diff --git a/NEWS.rst b/NEWS.rst index 689dae5..beb22ed 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -7,6 +7,14 @@ Bug Fixes ------------------------------ * Fix `(return)` so it works correctly to exit a Python 2 generator +Other Breaking Changes +----------------------------- +* `hy-repr` uses registered functions instead of methods + +Misc. Improvements +---------------------------- +* `hy-repr` supports more standard types + 0.14.0 ============================== diff --git a/docs/contrib/hy_repr.rst b/docs/contrib/hy_repr.rst index 51d8842..fae2625 100644 --- a/docs/contrib/hy_repr.rst +++ b/docs/contrib/hy_repr.rst @@ -4,10 +4,10 @@ Hy representations .. versionadded:: 0.13.0 -``hy.contrib.hy-repr`` is a module containing a single function. -To import it, say:: +``hy.contrib.hy-repr`` is a module containing two functions. +To import them, say:: - (import [hy.contrib.hy-repr [hy-repr]]) + (import [hy.contrib.hy-repr [hy-repr hy-repr-register]]) To make the Hy REPL use it for output, invoke Hy like so:: @@ -30,19 +30,47 @@ It returns a string representing the input object in Hy syntax. => (repr [1 2 3]) '[1, 2, 3]' -If the input object has a method ``__hy-repr__``, it will be called -instead of doing anything else. - -.. code-block:: hy - - => (defclass C [list] [__hy-repr__ (fn [self] "cuddles")]) - => (hy-repr (C)) - 'cuddles' - -When ``hy-repr`` doesn't know how to handle its input, it falls back -on ``repr``. - Like ``repr`` in Python, ``hy-repr`` can round-trip many kinds of values. Round-tripping implies that given an object ``x``, ``(eval (read-str (hy-repr x)))`` returns ``x``, or at least a value that's equal to ``x``. + +.. _hy-repr-register-fn: + +hy-repr-register +---------------- + +Usage: ``(hy-repr-register the-type fun)`` + +``hy-repr-register`` lets you set the function that ``hy-repr`` calls to +represent a type. + +.. code-block:: hy + + => (defclass C) + => (hy-repr-register C (fn [x] "cuddles")) + => (hy-repr [1 (C) 2]) + '[1 cuddles 2]' + +If the type of an object passed to ``hy-repr`` doesn't have a registered +function, ``hy-repr`` will search the type's method resolution order +(its ``__mro__`` attribute) for the first type that does. If ``hy-repr`` +doesn't find a candidate, it falls back on ``repr``. + +Registered functions often call ``hy-repr`` themselves. ``hy-repr`` will +automatically detect self-references, even deeply nested ones, and +output ``"..."`` for them instead of calling the usual registered +function. To use a placeholder other than ``"..."``, pass a string of +your choice to the keyword argument ``:placeholder`` of +``hy-repr-register``. + +.. code-block:: hy + + (defclass Container [object] + [__init__ (fn [self value] + (setv self.value value))]) + (hy-repr-register Container :placeholder "HY THERE" (fn [x] + (+ "(Container " (hy-repr x.value) ")"))) + (setv container (Container 5)) + (setv container.value container) + (print (hy-repr container)) ; Prints "(Container HY THERE)"