2009-12-27 31 views
4

我一直在学习如何使用ets,但有一件事困扰着我,偶尔*,ets:match会抛出bad argument ...而且,从他们开始,所有后续调用(即使之前调用过的调用)也会抛出bad argumentErlang/ets:在得到一个“坏论点”后重置ets表?

 
> ets:match(Tid, { [$r | '$1'] }, 1). 
% this match works... 
% Then, at some point, this comes up: 
** exception error: bad argument 
    in function ets:match/3 
     called as ets:match(24589,{[114|'$1']},1) 
% And from then on, matches stop working: 
> ets:match(Tid, { [$r | '$1'] }, 1). 
** exception error: bad argument 
    in function ets:match/3 
     called as ets:match(24589,{[114|'$1']},1) 

有什么办法来“重置” ets系统,这样我可以再次查询它(即从shell)?

*:我还没有能够重现这个问题......但是当我试图做“其他事情”时,它经常发生。

回答

10

虽然我不是100%确定,但this thread似乎回答你的问题。看起来你正在shell中观察这种行为。如果是这样,两个事实以令人困惑的方式相互作用:

  1. 一旦它的拥有进程死掉,它就会被删除。
  2. erlang外壳在接收到异常并且无提示重新启动时死亡。

因此,当您得到第一个异常时,当前shell进程死亡,导致ets表被删除,然后为您启动新的shell进程。现在,当您尝试另一个ets:match时,它将失败,因为该表不再存在。

2

戴尔已经告诉过你发生了什么事。你可以通过在shell中调用self()来确认。

作为一种快速解决方法,您可以生成另一个进程为您创建公用表。那桌子不会随着你的外壳而死。

1> self(). 
<0.32.0> % shell's Pid 

2> spawn(fun() -> ets:new(my_table, [named_table, public]), receive X -> ok end end). 
<0.35.0> % the spawned process's Pid 

3> ets:insert(my_table, {a, b}). 
true 

现在制定一个例外,并检查该表是否确实存在。

4> 1/0. 
** exception error: bad argument in an arithmetic expression 
    in operator '/'/2 
     called as 1/0 
5> self(). 
<0.38.0> % shell's reborn, with a different Pid 

6> ets:insert(my_table, {c, d}). 
true 
7> ets:tab2list(my_table). 
[{c,d},{a,b}] % table did survive the shell restart 

要删除表格,只是送东西给你生成的进程:

8> pid(0,35,0) ! bye_bye. 
bye_bye 
9> ets:info(my_table). 
undefined