我想在模块之外调用私有函数。在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
我知道调用私有函数/方法不是一个好方法,但无论如何。
答案 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。