Domanda

What is the way to find fields info(i.e field names) for ets table in erlang ?

I have tried ets:info(TableName), ets:i(TableName). First one gives the detail about the table like memory,owner,size,named_table,keypos,protection etc. Second one gives the details about the entries present in the table.

È stato utile?

Soluzione

The problem is that ETS works on tuples not records so there are no field names as such. Even if you do use records ETS only sees the tuples.

Mnesia uses and knows about records.

EDIT: A longer comment to @niting112's comment.

Records are, of course, just syntactic sugar for tuples providing, amongst other things, named fields. They are purely compile-time constructions and at an early stage in the compiler all record operations are transformed in corresponding tuple operations. Internally there are just tuples. The record name becomes the first element in the tuple and the fields are the other elements.

Seeing ETS works on tuples we can use records for defining the tuples which are in a table. So if we have:

-define(foo, {a,b=0,c}).

then we can add objects to a table using:

ets:insert(Table, #foo{a="Joe",c=1}),
ets:insert(Table, #foo{a="Robert,c=2}),
ets:insert(Table, #foo{a="Mike",c=3}),

and we have added three tuples of 4 elements each. It is important to remember that if we are using records to define the table elements then we should make sure to set the key position to the index of the record field we wish to use as index. By default the key position is 1 which is just the record name which is generally not what we want.

We can use "patterns" to retrieve objects from a table. Remember that there is no pattern datatype in Erlang and what we are really doing is constructing tuples which are interpreted as patterns. In these "patterns" the atoms '$1', '$2', '$3', ... are interpreted as variables and the atom '_' is interpreted as the don't care variable. So we could use the tuple {foo,'$1','_','$2'} as a pattern and the variables '$1' and '$2' will be "bound" the records fields a and c respectively. This is what is done with the functions ets:match, ets:match_object and ets:match_object and also in an extended form in ets:select.

We can also use the record definitions to generate these "patterns" to retrieve elements from a table. We just use the record constructor syntax, so #foo{a='$1',b='_',c='$2'} generates the same tuple "pattern" as the example in the previous paragraph. There is some special syntax for records which is VERY useful for generating these "patterns": the special (and normally illegal) field name _ is used to define a default value for all fields which aren't explicitly given in the constructor. So in these cases we can use _='_' to set all unspecified fields to the "don't care variable" '_'. Perfect for patterns in ets matching. So the "pattern" #foo{b=49,_='_'} becomes the tuple {foo,'_',49,'_'}.

N.B. These are the not normal patterns used in normal pattern matching but data interpreted as pattern by ETS. Very different things.

Sorry for going a bit overboard here, I got carried away.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top