Question: I would like to construct a match spec to select the first element from a tuple when a match is found on the second element, or the second element when the first element matches. Rather than calling ets:match twice, can this be done in one match specification?

Answer: 
Yes.

In [documentation](http://www.erlang.org/doc/man/ets.html#select-2) there is example of `is_integer(X), is_integer(Y), X + Y < 4711`, or `[{is_integer, '$1'}, {is_integer, '$2'}, {'<', {'+', '$1', '$2'}, 4711}]`. 

If you are using `fun2ms` just write funciton with two clauses.

```
fun({X, Y}) when in_integer(X)
                 andalso X > 5 ->
       Y;

   ({X, Y}) when is_integer(Y)
                 andalso Y > 5 ->
       X.

```

But you could also create two `MatchFunctions`. Each consist `{MatchHead, [Guard], Return}`. 

Match head basically tells you how your data looks (is it a tuple, how many elements ...) and assigns to each element match variable `$N` where `N` will be some number. Lets say are using two-element tuples, so your match head would be `{'$1', '$2'}`. 

Now lets create guards: For first function we will assume something simple, like first argument is integer greater than 10. So first guard will be `{is_integer, '$2'}`, and second `{'>', '$2', 5}`. In both we use firs element of our match head `'$2'`. Second match function would have same guards, but with use of `'$1'`.

And at last the return. Since we would like to just return one element, for first function it will be `'$1'`, and for second `'$2'` (returning tuple is little more complicated, since you would have to wrap it in additional on-element tuple).

So finally, when put together it gives us

```
[ _FirstMatchFunction = {_Head1 = {'$1', '$2'},
                         _Guard1 = [{is_integer, '$2},
                                    {'>', '$2', 5}],     % second element matches
                         _Return1 = [ '$1']},            % return first element             
  _SecondMatchFunction = {_Head2 = {'$1', '$2'},
                          _Guard2 = [{is_integer, '$1},
                                     {'>', '$1', 5}],      % second element matches
                          _Return2 = [ '$2']} ]            % return first element

```

Havent had too much time to test it all, but it should work (maybe with minor tweaks).
```
-export([main/0]).
-include_lib("stdlib/include/ms_transform.hrl").
main() ->
    ets:new(test, [named_table, set]),
    ets:insert(test, {1, a, 3}),
    ets:insert(test, {b, 2, false}),
    ets:insert(test, {3, 3, true}),
    ets:insert(test, {4, 4, "oops"}),

    io:format("~p~n", [ets:fun2ms(fun({1, Y, _Z}) -> Y;
                     ({X, 2, _Z}) -> X end)]),

    ets:select(test, ets:fun2ms(fun({1, Y, _Z}) -> {first_match, Y};
                   ({X, 2, _Z}) -> {second_match, X}
                end)).

```

The output is:

```
[{{1,'$1','$2'},[],['$1']},{{'$1',2,'$2'},[],['$1']}]
[{first_match,a},{second_match,b}]

```