Mike Andrianov
Mike Andrianov

Reputation: 3085

Is it possible to call private function outside of Module in the Elixir?

I want to call private function outside of module. In Ruby I can do it via #send method, but it's seems to me Elixir's apply doesn't work with private functions.

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

I know that calling a private functions/methods isn't a good approach, but anyway.

Upvotes: 0

Views: 1494

Answers (3)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Not exported (private in Elixir terminology) functions are even not guaranteed to exist at all. The compiler might e.g. take a responsibility to inline it.

Luckily enough, ExAws.S3.url_to_sign/4 is pretty straightforward. One might easily replicate this functionality:

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

And use it whenever you need to get this url.

Upvotes: 3

NoDisplayName
NoDisplayName

Reputation: 15736

Don't do it, they are private for a reason, even if you could call it, you'd couple your code to an implementation which is terrible and is as fragile as it gets. Find another way.

If you are using a third party library, as I assume from your code, then your options are limited and I don't see a good way out of it. Maybe you could fork the lib and make some changes but then it gets harder to keep the lib updated. Or you could reimplement it, but it's not always possible and well, not a good idea in general.

I'd suggest to think hard and make sure that there is no other way around it, most likely you're doing something you shouldn't.

And do don't do that in Ruby either.

Upvotes: 1

Eduardo Aguilera
Eduardo Aguilera

Reputation: 1

If you need to call it from outside the module, means that it is not a private function at all. If you need it to be private though, you could make a public function which will call the private function under the scenes. Like and api.

Upvotes: 0

Related Questions