programmatically matching erlang terms

7 views
Skip to first unread message

stefo

unread,
Feb 20, 2011, 7:54:52 AM2/20/11
to erlangcamp
Hi, greetings from Switzerland

my diameter protocol parser transforms billing request variables into
lists of tuples with a builtin hierarchy.
an example for one such element in the list:

{'Subscription-Id', [
{'Subscription-Id-Type',0}
,{'Subscription-Id-Data',"41793952345"}
]
}

how can I have a match function on these tuples, similar to what
ets:match/2 uses but on a given term instead of an ets table? It would
have to support the '_' placeholder for any erlang term.

in other words: has anyone a good and fast implementation for my
function avps_match() in the test case below?

Thanks alot

Stefan

avps_match(Pattern, Tuple) ->
%% implemetation of match function similar
%% to ets:match needed here on single term Tuple
false.

avps_match_test() ->
%% success matchings without placeholders
?assert(avps_match({a,17}, {a,17}) =:= true),
?assert(avps_match({a,"45"}, {a,"45"}) =:= true),
?assert(avps_match({a,[{b,0},{c,"45"}]}, {a,[{b,0},{c,"45"}]}) =:=
true),
%% failed matchings without placeholders
?assert(avps_match({a,17}, {a,18}) =:= false),
?assert(avps_match({a,"45"}, {a,"46"}) =:= false),
?assert(avps_match({a,"45"}, {a,17}) =:= false),
?assert(avps_match({a,"45"}, {b,"45"}) =:= false),
?assert(avps_match({a,[{b,0},{c,"45"}]}, {a,[{b,0},{c,"46"}]}) =:=
false),
?assert(avps_match({a,[{b,0},{c,"45"}]}, {a,[{b,1},{c,"45"}]}) =:=
false),
?assert(avps_match({a,[{b,0},{c,"45"}]}, {a,[{x,0},{c,"45"}]}) =:=
false),
?assert(avps_match({a,[{b,0},{c,"45"}]}, {x,[{b,0},{c,"45"}]}) =:=
false),
%% success matchings with '_' placeholders
?assert(avps_match({a,'_'}, {a,"45"}) =:= true),
?assert(avps_match({a,[{b,0},{c,'_'}]}, {a,[{b,0},{c,"45"}]}) =:=
true),
?assert(avps_match({a,'_'}, {a,[{b,0},{c,"45"}]}) =:= true),
?assert(avps_match({a,[{b,'_'},{c,"45"}]}, {a,[{b,0},{c,"45"}]}) =:=
true),
?assert(avps_match({a,[{b,'_'},{c,'_'}]}, {a,[{b,0},{c,"45"}]}) =:=
true),
%% failed matchings with '_' placeholders
?assert(avps_match({a,[{b,0},{c,'_'}]}, {a,[{b,0},{x,"45"}]}) =:=
false),
?assert(avps_match({a,[{b,0},{c,'_'}]}, {a,[{b,1},{c,"45"}]}) =:=
false),
?assert(avps_match({a,[{b,0},{c,'_'}]}, {x,[{b,0},{c,"45"}]}) =:=
false),
?assert(avps_match({a,[{b,'_'},{c,"45"}]}, {x,[{b,0},{c,"45"}]}) =:=
false),
ok.

Eric Merritt

unread,
Feb 21, 2011, 9:21:25 AM2/21/11
to erlan...@googlegroups.com, stefo
Stefo,


I think that eunit has an assertMatch macro that does very nearly what
you want it to do. I would probably start by taking a look at that.

Eric

stefo

unread,
Feb 28, 2011, 11:50:10 AM2/28/11
to erlangcamp
Thanks Eric

I'm trying to use this match function within a number of other
functions which manipulate the hierarchical data structure.
I would still prefer a plain function as opposed to using macros.
Without macros, it seems impossible to pass guard expressions as
parameters, hence the escape to the '_' placeholder (and others) in
ets:match.
I cannnot find the ets:match implementation, probably because it is
buried in C. Using that one would probably be fun, we have to be fast
anyways.

Can anyone find a pattern match function which works on plain erlang
term and which supports the '_' operator as a minimum?

Stefan
> >        ok.- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -
Reply all
Reply to author
Forward
0 new messages