5
\$\begingroup\$

I've got the following Elixir code:

defmodule Envvar do
    def exists?(env) do :os.getenv(env) != false end

    def get(env) do 
        if exists?(env) do
            {env, :os.getenv(env)}
        else 
            {env, nil}
        end 
    end
end

Two things:

  1. Am I using the ? correctly here? I'm assuming that any predicate function should have the ? on the end of the name by convention.
  2. Is there a way to code the get function as a pattern match rather than a if/else? I'm asking here because I'm guessing that a pattern match would be more idiomatic Elixir code.
\$\endgroup\$
6
\$\begingroup\$

Using the ? for a boolean predicate is fine. At least it is what I would do in Ruby and Elixir.

You won't be able to call exists?(env) in a guard clause so pattern matching does not win you much here.

You are calling :os.getenv() twice unneccessarily. I'm not sure why you just want to convert 'false' to 'nil', here is a way:

defmodule Envvar do
  def get(env)
    do_get(:os.getenv(env))
  end

  defp do_get(false)
    {:env, nil}
  end

  defp do_get(result)
    {:env,result}
  end
end
\$\endgroup\$
  • \$\begingroup\$ That's an interesting take on the pattern matching that I was looking for. Definitely seems a bit more idiomatic to me. \$\endgroup\$ – Onorio Catenacci Mar 7 '14 at 21:49
  • \$\begingroup\$ By the way, I want the exists? function as a separate function--I would have done a defp if I didn't want to expose it outside of the module. So I'm not really calling :os.getenv() twice unnecessarily. \$\endgroup\$ – Onorio Catenacci Mar 7 '14 at 22:00
  • \$\begingroup\$ @OnorioCatenacci - actually in this solution calling get without calling exists? will call :os.getenv() less than with calling exists?. No matter if env exists or not - :os.getenv() is called exactly once. \$\endgroup\$ – Uri Agassi Aug 14 '14 at 11:40
3
\$\begingroup\$

Is it necessary to return nil or is false enough? They both evaluate to false when using boolean operators.

If false is good enough:

defmodule Envvar do
  def get(env) do
    {:env, :os.getenv(env)}
  end
end

If the return value has to be nil, I would just convert the second element and leave the first one intact.

defmodule Envvar do
  def get(env) do
    {:env, false_to_nil(:os.getenv(env)) }
  end

  defp false_to_nil(false) do
    nil
  end

  defp false_to_nil(v) do
    v
  end
end
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.