Elixir v1.6.0-rc.0 released

@josevalim: I’m trying defguard now

My current version

Here is my version of guard for rgb(a) check:

defmodule Example do
  defguard is_rgb(rgb)
           when is_tuple(rgb) and elem(rgb, 0) in 0..255 and elem(rgb, 1) in 0..255 and
                  elem(rgb, 2) in 0..255 and
                  (tuple_size(rgb) == 3 or
                     (tuple_size(rgb) == 4 and elem(rgb, 3) >= 0 and elem(rgb, 3) <= 1))

  def sample(rgb) when is_rgb(rgb), do: :ok
  # Let's do not remove comment line for now
  # def sample(_rgb), do: :error
end

Extra

With call like:

Example.sample(5)

as expected returns error:

** (FunctionClauseError) no function clause matching in Example.sample/1    
     
    The following arguments were given to Example.sample/1:
    
        # 1
        5
    
    iex:8: Example.sample/1

but … is it possible to describe which guard part fails like in normal function guards?

My question

Is it possible to write it somehow nicer? I would like to separate:
a) rgb check (in 0..255) of all elements
b) rgba check

I would like to have it looks like:

# Note: this example is only to show what I want to achieve in much more cleaner - not working way
defmodule Example do
  # strict 3-element tuple check
  defguard is_rgb_strict({red, green, blue}) when red in 0..255 and green in 0..255 and blue in 0..255
  # alpha check
  defguard is_css_alpha(alpha) when alpha >= 0 and alpha <= 1

  # rgba
  defguard is_rgba({red, green, blue, alpha}) when is_rgb_strict({red, green, blue}) and is_css_alpha(alpha)
  # 3-element tuple guard for is_rgb
  defguard is_rgb(rgb = {red, green, blue}) when is_rgb_strict(rgb)
  # 4-element tuple guard for is_rgb
  defguard is_rgb(rgba) when is_rgba(rgba)
end

Any ideas?
Note: Of course I know that defguard does not work like I invented it and I don’t ask to change it. I just want to ask for better (if any) version than my original.

1 Like