带有函数头和默认值的 Elixir 装饰器

Elixir decorators with function headers and defaults

我遇到一个问题,我需要将匹配案例添加到同时具有装饰器和默认值的函数:

@decorate print()
def foo(a, b \ "b") ...

使用 Decorators 包中的示例,此示例发出警告:

defmodule PrintDecorator do
  use Decorator.Define, [print: 0]

  def print(body, context) do
    quote do
      IO.puts("Function called: " <> Atom.to_string(unquote(context.name)))
      unquote(body)
    end
  end
end

defmodule Foo do
  use PrintDecorator

  @decorate print()
  def bar(a, b \ "b")
  def bar("foo", b) do
    "a is foo" <> b
  end
  def bar(a, b) do
    a <> b
  end
end

警告:

warning: variable "a" is unused
  iex:64

warning: variable "b" is unused
  iex:64

warning: def bar/2 has multiple clauses and also declares default values. In such cases, the default values should be defined in a header. Instead of:

    def foo(:first_clause, b \ :default) do ... end
    def foo(:second_clause, b) do ... end

one should write:

    def foo(a, b \ :default)
    def foo(:first_clause, b) do ... end
    def foo(:second_clause, b) do ... end

  iex:60

warning: this clause cannot match because a previous clause at line 60 always matches
  iex:60

无论装饰器放在哪里都会发出警告,但如果我删除装饰器,模块会按预期运行。

有人对此有解决方案吗?

FWIW,使用的包是 decorator。在问题本身中引用第三方包是有意义的。

问题是由其他原因引起的。您提供的代码完美运行,但它无法发出引用第 64 行的警告。这是我已证明有效的示例。

defmodule PD do
  use Decorator.Define, print: 0

  def print(body, context) do
    quote do
      IO.puts("Called: #{unquote(context.name)}")
      unquote(body)
    end
  end
end

defmodule Test do
  use PD

  @decorate print()
  def f(a, b \ "b")
  def f("foo", b), do: "a is foo | " <> b
  def f(a, b), do: a <> " | " <> b
end

#⇒ Test.f "bar"
#  Called: f
#  "bar | b"

开始新的 iex 会话或将代码放入项目并从那里进行测试。