2011-09-29 9 views
8

He oído que especificar registros a través de tuplas en el código es una mala práctica: siempre debo usar campos de registro (#record_name{record_field = something}) en lugar de tuplas simples {record_name, value1, value2, something}.Cómo hacer coincidir ets: partido contra un registro en Erlang?

Pero, ¿cómo puedo unir el registro con una tabla ETS? Si tengo una tabla con los registros, sólo puedo coincidir con lo siguiente:

ets:match(Table, {$1,$2,$3,something} 

Es obvio que una vez que agrego algunos nuevos campos para la definición de registro este partido patrón dejará de funcionar.

En su lugar, me gustaría usar algo como esto:

ets:match(Table, #record_name{record_field=something}) 

Desafortunadamente, devuelve una lista vacía.

Respuesta

16

La causa de su problema es que los campos no especificados están configurados cuando hace un #record_name{record_field=something}. Esta es la sintaxis para creando un registro, aquí está creando un registro/tupla que ETS interpretará como un patrón. Cuando crea un registro, todos los campos no especificados obtendrán sus valores predeterminados, ya sean los definidos en la definición del registro o el valor predeterminado predeterminado undefined.

Por lo tanto, si desea dar a los campos valores específicos, debe hacerlo explícitamente en el registro, por ejemplo, #record_name{f1='$1',f2='$2',record_field=something}. A menudo, al usar registros y ets desea configurar todos los campos no especificados en '_', la variable "no importa" para ets matching. Hay una sintaxis especial para esto usando el nombre de campo especial, y por lo demás ilegal, _. Por ejemplo #record_name{record_field=something,_='_'}.

Tenga en cuenta que en su ejemplo ha establecido elemento de nombre de registro en la tupla en '$ 1'. La tupla que representa un registro siempre tiene el nombre del registro como primer elemento. Esto significa que cuando crea la tabla ets, debe establecer la posición de la clave con {keypos,Pos} en un valor diferente al predeterminado 1; de lo contrario, no habrá indexación y, lo que es peor, si tiene una tabla del tipo 'set' o 'ordered_set' solo obtén 1 elemento en la tabla. Para obtener el índice de un campo de registro, puede usar la sintaxis #Record.Field, en su ejemplo #record_name.record_field.

9

Intente utilizar

ets:match(Table, #record_name{record_field=something, _='_'}) 

Ver this para la explicación.

Cuestiones relacionadas