Skip to content

Commit 689bce1

Browse files
author
José Valim
committed
Inspect should represent non valid terms with #
1 parent 2297fc1 commit 689bce1

File tree

6 files changed

+49
-43
lines changed

6 files changed

+49
-43
lines changed

lib/elixir/lib/binary/inspect.ex

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defprotocol Binary.Inspect do
1111
printing.
1212
"""
1313

14-
@only [BitString, List, Tuple, Atom, Number, Function, Any]
14+
@only [BitString, List, Tuple, Atom, Number, Function, PID, Port, Reference]
1515

1616
def inspect(thing, opts)
1717
end
@@ -419,32 +419,41 @@ end
419419

420420
defimpl Binary.Inspect, for: Function do
421421
@moduledoc """
422-
Represents functions, in a literal form, when possible
422+
Inspect functions, when possible, in a literal form.
423423
"""
424424

425-
def inspect(thing, _opts) do
426-
fun_info = :erlang.fun_info(thing)
427-
if fun_info[:type] == :external and
428-
fun_info[:env] == [] do
425+
def inspect(function, _opts) do
426+
fun_info = :erlang.fun_info(function)
427+
if fun_info[:type] == :external and fun_info[:env] == [] do
429428
"function(#{Kernel.inspect(fun_info[:module])}.#{fun_info[:name]}/#{fun_info[:arity]})"
430429
else
431-
iolist_to_binary :io_lib.format('~p', [thing])
430+
'#Fun' ++ rest = :erlang.fun_to_list(function)
431+
"#Function" <> list_to_binary(rest)
432432
end
433433
end
434434
end
435435

436-
defimpl Binary.Inspect, for: Any do
437-
@moduledoc """
438-
For all other terms not implemented, we use the default
439-
Erlang representation.
436+
defimpl Binary.Inspect, for: PID do
437+
@moduledoc "Inspect PIDs"
440438

441-
## Examples
439+
def inspect(pid, _) do
440+
"#PID" <> list_to_binary pid_to_list(pid)
441+
end
442+
end
442443

443-
inspect Process.self #=> "<0.35.0>"
444+
defimpl Binary.Inspect, for: Port do
445+
@moduledoc "Inspect ports"
444446

445-
"""
447+
def inspect(port, _) do
448+
list_to_binary :erlang.port_to_list(port)
449+
end
450+
end
446451

447-
def inspect(thing, _) do
448-
iolist_to_binary :io_lib.format('~p', [thing])
452+
defimpl Binary.Inspect, for: Reference do
453+
@moduledoc "Inspect references"
454+
455+
def inspect(ref, _) do
456+
'#Ref' ++ rest = :erlang.ref_to_list(ref)
457+
"#Reference" <> list_to_binary(rest)
449458
end
450-
end
459+
end

lib/elixir/lib/hash_dict.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,6 @@ defimpl Binary.Inspect, for: HashDict do
489489
import Kernel, except: [inspect: 2]
490490

491491
def inspect(dict, opts) do
492-
"HashDict" <> Binary.Inspect.inspect(HashDict.to_list(dict), opts)
492+
"#HashDict<" <> Binary.Inspect.inspect(HashDict.to_list(dict), opts) <> ">"
493493
end
494494
end

lib/elixir/lib/kernel.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1798,7 +1798,7 @@ defmodule Kernel do
17981798
end
17991799
18001800
@doc """
1801-
Inspect the given arguments according to the Binary.Inspect protocol.
1801+
Inspect the given arguments according to the `Binary.Inspect` protocol.
18021802
18031803
## Options
18041804
@@ -1815,6 +1815,13 @@ defmodule Kernel do
18151815
inspect(:foo)
18161816
#=> ":foo"
18171817
1818+
Notice the inspect protocol does not necessarily return a valid Elixir
1819+
terms representation. In such cases, the inspected result must start
1820+
with `#`. For example, inspecting a function will return:
1821+
1822+
inspect &1 + &2
1823+
#=> #Function<...>
1824+
18181825
"""
18191826
defmacro inspect(arg, opts // []) do
18201827
quote do: Binary.Inspect.inspect(unquote(arg), unquote(opts))

lib/elixir/lib/tuple.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
defmodule Tuple do
2+
@moduledoc false
23
end

lib/elixir/test/elixir/binary/inspect_test.exs

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -185,46 +185,35 @@ defmodule Binary.Inspect.ListTest do
185185
end
186186
end
187187

188-
defmodule Binary.Inspect.FunctionTest do
188+
defmodule Binary.Inspect.OthersTest do
189189
use ExUnit.Case, async: true
190190

191191
def f do
192192
fn() -> :ok end
193193
end
194194

195-
test :funs do
196-
bin = inspect(fn(x) -> x + 1 end)
197-
assert '#Fun<' ++ _ = binary_to_list(bin)
198-
end
199-
200-
test :external_elixir do
195+
test :external_elixir_funs do
201196
bin = inspect(function(Enum.map/2))
202197
assert bin == "function(Enum.map/2)"
203198
end
204199

205-
test :external_elixir_fun do
206-
bin = inspect(f)
207-
assert '#Fun<' ++ _ = binary_to_list(bin)
208-
end
209-
210-
test :external_erlang do
200+
test :external_erlang_funs do
211201
bin = inspect(function(:lists.map/2))
212202
assert bin == "function(:lists.map/2)"
213203
end
214204

215-
end
216-
217-
defmodule Binary.Inspect.AnyTest do
218-
use ExUnit.Case, async: true
205+
test :other_funs do
206+
assert "#Function<" <> _ = inspect(fn(x) -> x + 1 end)
207+
assert "#Function<" <> _ = inspect(f)
208+
end
219209

220-
test :funs do
221-
bin = inspect(fn(x) -> x + 1 end)
222-
assert '#Fun<' ++ _ = binary_to_list(bin)
210+
test :pids do
211+
assert "#PID<" <> _ = inspect(self)
223212
end
224-
end
225213

226-
defmodule Binary.Inspect.RegexTest do
227-
use ExUnit.Case, async: true
214+
test :references do
215+
assert "#Reference<" <> _ = inspect(make_ref)
216+
end
228217

229218
test :regex do
230219
"%r\"foo\"m" = inspect(%r(foo)m)

lib/elixir/test/elixir/hash_dict_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ defmodule HashDictTest do
132132
end
133133

134134
test :inspect do
135-
assert inspect(filled_dict(8)) =~ %r"HashDict\["
135+
assert inspect(filled_dict(8)) =~ %r"#HashDict<"
136136
end
137137

138138
test :small_range_merge do

0 commit comments

Comments
 (0)