type_info = IEx.Helpers.i(foo)
Error:
Function IEx.Helpers.i/1 does not exist.
How do I resolve this issue?
type_info = IEx.Helpers.i(foo)
Error:
Function IEx.Helpers.i/1 does not exist.
How do I resolve this issue?
The IEx.Helpers
are only available in IEx
. Can you elaborate on the problem you’re trying to solve?
I’m trying to get precise type information in order to quickly construct a pattern match against the results of a function call rather than trying to figure it out by trial and error. (inspect()
isn’t always accurate.)
inspect(value, structs: false)
should be pretty unambiguous about what the value is. What output do you see?
If you want just type then you can write such function quite easily on your own:
def type(%struct{}), do: {:struct, struct}
def type(input) do
cond do
is_atom(input) -> :atom
is_list(intput) -> :list
is_binary(input) -> :binary
is_integer(input) -> :integer
is_float(input) -> :float
is_pid(input) -> :pid
is_tuple(input) -> :tuple
is_map(input) -> :map
is_ref(input) -> :ref
is_port(input) -> :port
is_bitstring(input) -> :bitstring
is_function(input) -> :function
end
end
I think I have covered all possible types there
Maybe only missing:
def type(input) do
import Record
cond do
is_atom(input) -> :atom
is_list(intput) -> :list
is_record(input) -> :record
...
end
end
This question gets asked every-so-often so I’m going to be That Guy ™ and ask you for the whole context of your problem if you’re willing to share. In 3+ years of writing Elixir, I’ve never once found myself wanting such a function. Perhaps we could help you refactor into something more idiomatic, if you’re willing. If not, that’s also cool
is_record/1
could result with weird results in many cases, so I would avoid that there. For example it would return :record
for {:ok, 1}
.
The first element of a keyword list of arbitrary length was proving difficult for me to pattern match against.
Ex:
iex(1)> foo = [ok: :one, ok: :two, ok: :three]
iex(2)> inspect(foo, structs: false)
"[ok: :one, ok: :two, ok: :three]"
It seems like this is just a list, but:
iex(3)> [ok: _ | bosh] = foo
** (CompileError) iex:3: misplaced operator |/2
i/1
revealed that it’s really a list of two element tuples:
iex(4)> i(foo)
Term
[ok: :one, ok: :two, ok: :three]
Data type
List
Description
This is what is referred to as a "keyword list". A keyword list is a list
of two-element tuples where the first element of each tuple is an atom.
Reference modules
Keyword, List
Implemented protocols
Collectable, Enumerable, IEx.Info, Inspect, List.Chars, String.Chars
With this crucial clarification:
iex(5)> [{:ok, _} | bosh] = foo
[ok: :one, ok: :two, ok: :three]
iex(6)> bosh
[ok: :two, ok: :three]
Which brings us full circle by to my original query:
Thanks for chiming in
Please see my reply to @benwilson512 here above.
Maybe a keyword list is not the appropriate structure for what You want to do.
I don’t remember having to match on the first element of a keyword list… I use keyword list as function parameters, or in config file.
Unless You don’t own the code, You might help yourself by writing spec.
I can’t reproduce this behavior, even with a file passed to plain elixir
:
# in the file bar.exs
IEx.Helpers.i({:ok, nil}) |> IO.inspect()
$ elixir bar.exs
Term
{:ok, nil}
Data type
Tuple
Reference modules
Tuple
Implemented protocols
IEx.Info, Inspect
:"do not show this result in output"
(This is 1.14.0 / OTP 25, if that makes a difference)