ETS tuple in body

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

ETS tuple in body

Roberto Ostinelli-5
Dear list,
Something I probably should know better of. In ETS, if one of your MatchBody is a tuple, it needs to be wrapped as a tuple:

    MatchBody = case is_tuple(Name) of
        true -> {{{Name}, '$2', '$3', '$4'}};
        _ -> {{Name, '$2', '$3', '$4'}}
    end,
    case ets:select(my_table, [{
        {Name, '$2', '$3', '$4', '_', '_'},
        [],
        [MatchBody]
    }])


I need to do this because to make it work for Name values of both test and {test}.
Is there a better way?

Thank you,
r.
Reply | Threaded
Open this post in threaded view
|

Re: ETS tuple in body

Jacob-2
Hi,

On 1/10/20 4:37 PM, Roberto Ostinelli wrote:

>     MatchBody = case is_tuple(Name) of
>         true -> {{{Name}, '$2', '$3', '$4'}};
>         _ -> {{Name, '$2', '$3', '$4'}}
>     end,
>     case ets:select(my_table, [{
>         {Name, '$2', '$3', '$4', '_', '_'},
>         [],
>         [MatchBody]
>     }])
>
> I need to do this because to make it work for Name values of both test
> and {test}.
> Is there a better way?

yes, by using a 'const' expression that will prevent variable substition
and function (tuple) evaluation in the sub-expression (here Name):

    case ets:select(my_table, [{
        {Name, '$2', '$3', '$4', '_', '_'},
        [],
        [{{const, Name}, '$2', '$3', '$4'}]
    }])

I assume there aren't nested tuples in Name, but just using {Name} like
above would only prevent the outmost tuple from being interpreted as a
"function" or variable. The 'const' expression is much safer here, since
it just says: "include as is". See the ms_transform manpage for details.

Jacob
Reply | Threaded
Open this post in threaded view
|

Re: ETS tuple in body

Roberto Ostinelli-5
Thank you Jacob,
I already tried a couple of combinations with const but I always got an error message. For instance:

([hidden email])2> Name = test.
test
([hidden email])3> ets:select(my_table, [{
([hidden email])3>         {Name, '$2', '$3', '$4', '_', '_'},
([hidden email])3>         [],
([hidden email])3>         [{{const, Name}, '$2', '$3', '$4'}]
([hidden email])3>     }]).
** exception error: bad argument
     in function  ets:select/2
        called as ets:select(my_table,
                             [{{test,'$2','$3','$4','_','_'},
                               [],
                               [{{const,test},'$2','$3','$4'}]}])



On Fri, Jan 10, 2020 at 5:05 PM Jacob <[hidden email]> wrote:
Hi,

On 1/10/20 4:37 PM, Roberto Ostinelli wrote:
>     MatchBody = case is_tuple(Name) of
>         true -> {{{Name}, '$2', '$3', '$4'}};
>         _ -> {{Name, '$2', '$3', '$4'}}
>     end,
>     case ets:select(my_table, [{
>         {Name, '$2', '$3', '$4', '_', '_'},
>         [],
>         [MatchBody]
>     }])
>
> I need to do this because to make it work for Name values of both test
> and {test}.
> Is there a better way?

yes, by using a 'const' expression that will prevent variable substition
and function (tuple) evaluation in the sub-expression (here Name):

    case ets:select(my_table, [{
        {Name, '$2', '$3', '$4', '_', '_'},
        [],
        [{{const, Name}, '$2', '$3', '$4'}]
    }])

I assume there aren't nested tuples in Name, but just using {Name} like
above would only prevent the outmost tuple from being interpreted as a
"function" or variable. The 'const' expression is much safer here, since
it just says: "include as is". See the ms_transform manpage for details.

Jacob
Reply | Threaded
Open this post in threaded view
|

Re: ETS tuple in body

Roberto Ostinelli-5
Ok I got it, your example was missing an external tuple:

ets:select(my_table, [{
    {Name, '$2', '$3', '$4', '_', '_'},
    [],
    [{{{const, Name}, '$2', '$3', '$4'}}]
}]).


Thank you,
r.

On Fri, Jan 10, 2020 at 5:17 PM Roberto Ostinelli <[hidden email]> wrote:
Thank you Jacob,
I already tried a couple of combinations with const but I always got an error message. For instance:

([hidden email])2> Name = test.
test
([hidden email])3> ets:select(my_table, [{
([hidden email])3>         {Name, '$2', '$3', '$4', '_', '_'},
([hidden email])3>         [],
([hidden email])3>         [{{const, Name}, '$2', '$3', '$4'}]
([hidden email])3>     }]).
** exception error: bad argument
     in function  ets:select/2
        called as ets:select(my_table,
                             [{{test,'$2','$3','$4','_','_'},
                               [],
                               [{{const,test},'$2','$3','$4'}]}])



On Fri, Jan 10, 2020 at 5:05 PM Jacob <[hidden email]> wrote:
Hi,

On 1/10/20 4:37 PM, Roberto Ostinelli wrote:
>     MatchBody = case is_tuple(Name) of
>         true -> {{{Name}, '$2', '$3', '$4'}};
>         _ -> {{Name, '$2', '$3', '$4'}}
>     end,
>     case ets:select(my_table, [{
>         {Name, '$2', '$3', '$4', '_', '_'},
>         [],
>         [MatchBody]
>     }])
>
> I need to do this because to make it work for Name values of both test
> and {test}.
> Is there a better way?

yes, by using a 'const' expression that will prevent variable substition
and function (tuple) evaluation in the sub-expression (here Name):

    case ets:select(my_table, [{
        {Name, '$2', '$3', '$4', '_', '_'},
        [],
        [{{const, Name}, '$2', '$3', '$4'}]
    }])

I assume there aren't nested tuples in Name, but just using {Name} like
above would only prevent the outmost tuple from being interpreted as a
"function" or variable. The 'const' expression is much safer here, since
it just says: "include as is". See the ms_transform manpage for details.

Jacob
Reply | Threaded
Open this post in threaded view
|

Re: ETS tuple in body

Jacob-2
Yep, you're right. I've forgotten to add the enclosing tuple while
copying and pasting.

Jacob

On 1/10/20 5:24 PM, Roberto Ostinelli wrote:

> Ok I got it, your example was missing an external tuple:
>
> ets:select(my_table, [{
>     {Name, '$2', '$3', '$4', '_', '_'},
>     [],
>     [{{{const, Name}, '$2', '$3', '$4'}}]
> }]).
>
> Thank you,
> r.