是否可以在Elixir中调用Module之外的私有函数?

时间:2018-03-11 17:12:53

标签: elixir

我想在模块之外调用私有函数。在Ruby中,我可以通过#send方法完成它,但在我看来Elixir的apply不适用于私有函数。

apply(ExAws.S3, :url_to_sign, ["bucket", "file.jpg", ExAws.Config.new(:s3), true])
** (UndefinedFunctionError) function ExAws.S3.url_to_sign/4 is undefined or private

我知道调用私有函数/方法不是一个好方法,但无论如何。

3 个答案:

答案 0 :(得分:3)

未导出(Elixir术语中的私有)功能甚至根本不保证存在。编译器可能例如负责内联它。

幸运的是,ExAws.S3.url_to_sign/4非常简单。有人可能很容易复制这个功能:

defmodule ExAwsS3Helper do
  import ExAws.S3.Utils
  def url_to_sign(bucket, object, config, virtual_host) do
    port = sanitized_port_component(config)
    object = ensure_slash(object)
    case virtual_host do
      true -> "#{config[:scheme]}#{bucket}.#{config[:host]}#{port}#{object}"
      false -> "#{config[:scheme]}#{config[:host]}#{port}/#{bucket}#{object}"
    end
  end
end

并在需要获取此网址时使用它。

答案 1 :(得分:1)

不要这样做,因为某种原因它们是私有的,即使你可以调用它,你也可以将你的代码耦合到一个非常糟糕并且像它一样脆弱的实现。找另一种方式。

如果您使用的是第三方库,正如我从您的代码中所假设的那样,那么您的选择是有限的,我也没有看到好的方法。也许你可以分叉lib并进行一些更改,但随后更新lib变得更加困难。或者你可以重新实现它,但它并不总是可能而且很好,一般来说不是一个好主意。

我建议认真思考并确保没有别的办法,很可能你做的事情不应该做。

并且不要在Ruby中做到这一点。

答案 2 :(得分:0)

如果您需要从模块外部调用它,则意味着它根本不是私有功能。如果你需要它是私有的,你可以创建一个公共函数,它将调用场景下的私有函数。喜欢和api。