Skip to content

Weird and inconsistent ABCSize behaviour when using guard, quote and unquote #1193

@Eiji7

Description

@Eiji7

Hi, I would like to describe it as best as I can, but I'm completely lost in what have happened, so I've written a simple script with comments so maybe someone can describe what's going wrong.

Mix.install([:credo])

sources = [
  # 3.0
  # (argument + guard + body - makes sense)
  """
  def sample(id) when is_atom(id) do
    quote bind_quoted: [id: id] do
      id
    end
  end
  """,
  # 2.23606797749979
  # (extra assign decreases size ?!)
  """
  def sample(id) when is_atom(id) do
    quote bind_quoted: [id: id] do
      id = id
      id
    end
  end
  """,
  # 1.0
  # (removing guard decreases size by 2 ?!)
  """
  def sample(id) do
    quote bind_quoted: [id: id] do
      id
    end
  end
  """,
  # 1.4142135623730951
  # (with extra assign removing guard decreases size by less than one ?!)
  """
  def sample(id) do
    quote bind_quoted: [id: id] do
      id = id
      id
    end
  end
  """,
  # 3.0
  # (argument + guard + unquote - again makes sense)
  """
  def sample(id) when is_atom(id) do
    quote do
      unquote(id)
    end
  end
  """,
  # 2.23606797749979
  # (again why the extra assign is decreasing size?)
  """
  def sample(id) when is_atom(id) do
    quote do
      id = unquote(id)
      id
    end
  end
  """,
  # 2.0
  # (in this case removing guard decreases size by 1 - makes sense)
  """
  def sample(id) do
    quote do
      unquote(id)
    end
  end
  """,
  # 2.23606797749979
  # (makes sense standalone, but in context why without guard it's increasing size now?)
  """
  def sample(id) do
    quote do
      id = unquote(id)
      id
    end
  end
  """
]

for source <- sources,
    {:ok, ast} = Credo.Code.ast(source),
    size = Credo.Check.Refactor.ABCSize.abc_size_for(ast, []) do
  IO.inspect({size, source})
end

In a real code just adding an extra variable assignment could add many points I figured out that just because of this false positive I can reduce size from 39 to 32 by … adding more code (variable assignment for each bind quoted variable)?

The more macros and the bigger quote do … end block you have the more problematic this rule is. Sometimes it's easier to just ignore the warning than changing the code. Yeah, I understand it's not designed for Elixir language, but it's not a matter of it, but a false positive it gives as without them it's really a good hint for me.

Anyway, hope it helps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions