MikeC
MikeC

Reputation: 255

How to have default and optional arguments?

I have this function

    def start(data, opts \\ [pages: 17, depth: 3]) do
        maxPages = opts[:pages]
        maxDepth = opts[:depth]
        IO.puts maxPages
        IO.puts maxDepth
    end

When I do Program.start("data", pages: 8) then I want it to print 8 and 3 but it only prints 8

Upvotes: 7

Views: 3709

Answers (2)

PeptideChain
PeptideChain

Reputation: 563

With map instead of keyword list is in my opinion more compact / nicer:

defmodule U2 do
  def format(value, opts \\ %{}) do
    opts = %{unit: "kg", decimals: 2} |> Map.merge(opts)
    "#{Float.to_string(value, [decimals: opts.decimals])} #{opts.unit}"
  end
end
IO.inspect U2.format 3.1415                            # "3.14 kg"
IO.inspect U2.format 3.1415, %{decimals: 3}            # "3.142 kg"
IO.inspect U2.format 3.1415, %{decimals: 3, unit: "m"} # "3.142 m"
IO.inspect U2.format 3.1415, %{unit: "Pa"}             # "3.14 Pa"

Upvotes: 0

Paweł Dawczak
Paweł Dawczak

Reputation: 9639

You could go with Keyword#get/3 instead, like:

def start(data, opts \\ []) do
    maxPages = Keyword.get(opts, :pages, 17)
    maxDepth = Keyword.get(opts, :depth, 3)
    IO.puts maxPages
    IO.puts maxDepth
end

Or alternatively, Keyword#merge/2 pass in opts with some defaults:

def start(data, opts \\ []) do
    finalOpts = Keyword.merge([pages: 17, depth: 3], opts)
    maxPages = finalOpts[:pages]
    maxDepth = finalOpts[:depth]
    IO.puts maxPages
    IO.puts maxDepth
end

Hope it helps!

Upvotes: 16

Related Questions