Reputation: 13521
Is it a bad practice to pattern match against record as tuples in Erlang (or Elixir)?
Sample code: Assume we have defined this module:
defmodule Ween do
defrecord TimeSpot, at: nil, tag: nil
def proper?({ _, _, "home"} = v), do: { true, "succeeded with: #{inspect v}" }
def proper?(other), do: { false, "failed with: #{inspect other}" }
def sample, do: TimeSpot.new(tag: "home")
end
If we define a test as follow:
defmodule WeenTest do
use ExUnit.Case
require Ween
test "records are tuples" do
case Ween.proper?(Ween.sample) do
{ true, v } -> IO.puts v
assert(true)
{ false, v } -> IO.puts v
assert(false)
end
end
end
It will succeed.
Edit 1: @parroty The reason that here pattern matching against tuples tested is to simulate some "sort of" duck typing for records; the ultimate thing I wished for, should look like this:
defmodule Ween do
defrecord TimeSpot, at: nil, tag: nil
def proper?([tag: "home"] = v), do: { true, "succeeded with: #{inspect v}" }
def proper?([tag: "1234"] = v), do: { true, "succeeded with: #{inspect v}" }
def proper?(other), do: { false, "failed with: #{inspect other}" }
def sample, do: TimeSpot.new(tag: "home")
end
So every record with a 'tag' field baring a "home" value would match the first clause. Of-course it seems there would be some performance penalties there.
Upvotes: 3
Views: 2457
Reputation: 11
Just for completeness (as this question is still very high on the Elixir tagged questions list): as of Elixir 0.13, records are deprecated (other than for interacting with Erlang code) and the question is now best implemented using Structs. These also conveniently give you the polymorphism that you desire (Structs are a form of Map)
http://elixir-lang.org/getting_started/15.html
Upvotes: 1
Reputation: 1375
I think the record can be directly used for pattern matching (this would be better than using tuple structure).
defmodule Ween do
defrecord TimeSpot, at: nil, tag: nil
def proper?(TimeSpot[tag: "home"] = v), do: { true, "succeeded with: #{inspect v}" }
def proper?(other), do: { false, "failed with: #{inspect other}" }
def sample, do: TimeSpot.new(tag: "home")
end
Upvotes: 4
Reputation: 13707
Cesarini and Thompson say in their book Erlang Programming to never rely on the fact that records are implemented as tuples, since that implementation could change. See the accepted answer to this question.
Upvotes: 4