Not every time we want to pull data out of an erlang ETS table is it as straightfoward as the previous example. Sometimes we want to get all values that are greater than zero, rather than just constants. We’ll need to use the ets:select function, which has support for guards.
Here’s a basic setup.
Tmp = ets:new(tmp, []).
ets:insert(Tmp, {bob, 0}).
ets:insert(Tmp, {jim, 1}).
ets:insert(Tmp, {jon, 2}).% Returns all results
ets:select(Tmp,[{{'$1','$2'},[],['$$']}]).% Returns results where $2 > 0 (jim and jon)
ets:select(Tmp,[{ {'$1','$2'}, [ { '>', '$2', 0 } ],['$$'] }]).
What’s going on in the select? There’s a LOT of syntax for something that’s so simple, but once we break it up a bit it starts to be easier to look at.
First off, lets take a look at the original spec.
MatchSpec = [MatchFunction]
MatchFunction = {MatchHead, [Guard], [Result]}
MatchHead = “Pattern as in ets:match”
Guard = {“Guardtest name”, …}
Result = “Term construct”
Pretty important stuff in here. The basic building block of the MatchSpec is a list. Inside the list, is a “matchfunction”.
[MatchFunction]
Next, we break the MatchFunction up a little bit more. MatchHead = Pattern. We’ve seen this before.
MatchSpec = [ {Pattern, [Guard], [Result] } ]
Now, lets write our basic pattern. We want the rows where the 2nd item is > 0. So, since we can’t put that in the pattern yet, we’ll just give it a reference.
MatchSpec = [ { {$1, $2}, [Guard], [Result] } ]
OK, cool. That’s not so bad anymore! Next step – lets use our guard. There’s a funky syntax for guards in the matchspec, so here we go. You’re looking at a list, right? So it can have many items. Each item is a record. They can nest. We’ll ignore that for now. What we need to know here is that in a pattern matching guard, we put the operation first. It would normally read $2 > 0.
[ { '>', '$2', 0} ]
That’ll give us the pattern we want. What about the Result? Feel free to just use ‘$$’ in there. It’ll just kick back what you specified in your pattern. If you don’t believe me,
8> ets:select(Tmp,[{ {'_','$2'},[ { '>', '$2', 0 } ],['$$']}]).
[[1],[2]]
Put it all together!
ets:select(Tmp,[{ {'$1','$2'}, [ { '>', '$2', 0 } ], ['$$'] }]).
Not so bad anymore.
For testing purposes, you can use this bad boy.
test_ms(Tuple, MatchSpec)
You can also use this handy function to transform functions to selects:
fun2ms(LiteralFun) -> MatchSpec
One Response to Erlang: ETS Matching with Guards (select/2)
Leave a Reply Cancel reply
Recent Comments
- pratibha on MySQL Triggers Tutorial
- pratibha on MySQL Triggers Tutorial
- MySQL Tutorials on MySQL Triggers Tutorial
- jon on The Lack of Flexibility of Stored Procedures in MySQL
- Nithya on The Lack of Flexibility of Stored Procedures in MySQL
- vietnam travel guide on MySQL Triggers Tutorial
- Phil Freo on Making Better Use of your .ackrc file
- PHP Examples on MySQL Triggers Tutorial
- jon on Drizzle Differences from MySQL
- Will on Drizzle Differences from MySQL
Recent Posts
- Vim: Use !make: to avoid auto jumping to files
- Weird Disutils Error When Running Python Scripts within MacVim
- Installing vim-ipython with MacVim
- Applescripting A Remote X-Windows Session for Virt-Manager
- Drizzle Differences from MySQL
- Great Article by the Varnish Architect
- Making Better Use of your .ackrc file
- Nginx pub/sub module
- Coffeescript, Bootstrap, and Less are amazing
- Splitmytab ready for the public!
Categories
- ack (1)
- amazon (1)
- answerbag (6)
- apache (9)
- apple (9)
- awk (2)
- bbedit (2)
- bootstrap (1)
- c++ (3)
- chrome (2)
- cluster (1)
- cocoa (1)
- coffeescript (2)
- collective intelligence (1)
- css (1)
- curl (3)
- db2 (1)
- demand media (1)
- drizzle (1)
- ebay (1)
- eclipse (4)
- erlang (13)
- facebook (1)
- fortran (1)
- gen_server (1)
- git (5)
- google (4)
- haddad (1)
- hdf5 (1)
- html (1)
- innodb (1)
- itunes (1)
- java (2)
- jester (2)
- kvm (2)
- launchbar (1)
- leex (1)
- less (1)
- letsgetnuts.com (1)
- libvirt (1)
- links (6)
- linux (28)
- lucene (1)
- mac (16)
- memcached (1)
- misconception (1)
- mobile (1)
- mono (1)
- mssql (1)
- munin (1)
- mysql (34)
- nginx (1)
- numpy (1)
- oracle (1)
- php (23)
- puppet (4)
- pyparsing (1)
- pytables (1)
- python (13)
- q&a (1)
- quicksilver (1)
- rant (6)
- readynas (1)
- redis (2)
- regex (1)
- replication (1)
- search (1)
- shitty code (1)
- solr (3)
- spaces (1)
- splitmytab (2)
- sshfs (1)
- stored procedure (1)
- svn (5)
- textmate (2)
- tips (25)
- tornado (1)
- trac (1)
- tutorial (4)
- ubuntu (3)
- Uncategorized (5)
- unix (1)
- vim (6)
- virtual box (6)
- vmware (1)
- weird (3)
- wikipedia (1)
- windows (1)
- xcode (1)








Also check out the man page for ms_transform (in stdlib), here.
It allows you to write select patterns in a much nicer syntax. For your example:
Eshell V5.6.4 (abort with ^G)
1> ets:fun2ms(fun({_,X}=Obj) when X > 0 -> Obj end).
[{{'_','$1'},[{'>','$1',0}],['$_']}]