Hide nil values when inspecting structs in iex

Please is there a way to hide nil fields when inspecting a struct in iex?

Is there a switch we can add to inspect for this?

2 Likes

You can implement the Inspect protocol for the structs where you’d like this behaviour. As far as I’m aware, there’s nothing built-in to do this.

2 Likes

Would be a good feature to have on Inspect.Opts
That would make it available to turn off or on

1 Like

This does not work so well:

data
  |> Map.from_struct
  |> Enum.filter(fn {_, v} -> v != nil end)
  |> Enum.into(%{})

http://stackoverflow.com/a/29363087/44080

Your struct becomes a map…

1 Like

Structs are maps, just with a special :__struct__ field that points to a module. :slight_smile:

1 Like

@OvermindDL1, @michalmuskala

You get my point …

%Person{name: "Charles", height: nil, age: nil, sex: nil, country: nil, address: nil, mobile: nil, human: true ...}

After Applying:

data
  |> Map.from_struct
  |> Enum.filter(fn {_, v} -> v != nil end)
  |> Enum.into(%{})

gives: %{__STRUCT__: Person, name: "Charles", human: true}

Would be great if Inspect.Opts [:hide_nil] could simply give:

%Person{name: "Charles", human: true}

Would be useful for inspecting structs with several null fields, helps highlight the actual data

1 Like

Often the nils are useful data. :slight_smile:

I’d personally be partially against such a :hide_nil option, it seems special casing…

2 Likes

I do not like this approach at all. Ordering of keys in the inspected representation of a struct should be deterministic, which we can’t guarantee by transforming into a map.

Why not do a proper defimpl? Then one can actually actively decide if nil is valid and important data or if nil means something like “unspecified” (but then I am wondering, why we do not use :unspecified and also show it in the inspect, since elixir is very explicit in general).

If you really have to, I’d go for something like this;

# This is untested!
defimpl Inspect, for: Person do
  import Inspect.Algebra

  def inspect(person, opts) do
    concat [
      "%Person{",
      (if person.name, do: ["name:", person.name]),
      ...
      "}",
    ]
  end
end

Perhaps you can even wrap it into a Macro or function as you like it more, But if I really had to, I’d prefer this way due to its expliciteness

1 Like