# Fetching environment variables — can I use pattern matching?

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.

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

• That's an interesting take on the pattern matching that I was looking for. Definitely seems a bit more idiomatic to me. – Onorio Catenacci Mar 7 '14 at 21:49
• 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. – Onorio Catenacci Mar 7 '14 at 22:00
• @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. – Uri Agassi Aug 14 '14 at 11:40

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