2012-10-27 112 views
4

我在elang中有一个奇怪的行为与ets:select。erlang ets选择奇怪的行为

我实现了一个正确的select语句(下面的4和5),然后我在我的语句(下面6)中犯了一个错误,然后再次尝试与4和5中相同的语句,但它不起作用更长的时间。

发生了什么事?任何想法 ?

Erlang R14B01 (erts-5.8.2) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false] 

Eshell V5.8.2 (abort with ^G) 
1> Tab = ets:new(x, [private]). 
16400 
2> ets:insert(Tab, {c, "rhino"}). 
true 
3> ets:insert(Tab, {a, "lion"}). 
true 
4> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2']}]).  
["rhino","lion"]  
5> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2']}]).  
["rhino","lion"] 
6> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2', '$3']}]). 
** exception error: bad argument 
in function ets:select/2 
    called as ets:select(16400,[{{'$1','$2'},[],['$1','$2','$3']}]) 
7> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2']}]).  
** exception error: bad argument 
in function ets:select/2 
    called as ets:select(16400,[{{'$1','$2'},[],['$1','$2']}]) 

我的ets表已被销毁?它会成为ets的错误吗?

谢谢。

回答

6

shell进程创建了ETS表,并且它是所有者。当拥有者进程死亡时,ETS表将被自动删除。

因此,当您在6发生异常时,shell进程将死亡,因此ETS表将被删除。

使它private也意味着没有其他进程可以访问它(因此即使表被保留,新的shell将无法访问它),但在这种情况下,它更糟,因为表已经删除。

3

(过大留下来thanosQR的正确答案评论)

,如果你想表生存在壳体中的异常,可以送人到另一个进程。例如:

1> Pid = spawn(fun() -> receive foo -> ok end end). % sit and wait for 'foo' message 
<0.62.0> 
2> Tab = ets:new(x, [public]).       % Tab must be public if you plan to give it away and still have access 
24593 
3> ets:give_away(Tab, Pid, []). 
true 
4> ets:insert(Tab, {a,1}). 
true 
5> ets:tab2list(Tab). 
[{a,1}] 
6> 3=4. 
** exception error: no match of right hand side value 4 
7> ets:tab2list(Tab).         % Tab survives exception 
[{a,1}] 
8> Pid ! foo.           % cause owning process to exit 
foo 
9> ets:tab2list(Tab).         % Tab is now gone 
** exception error: bad argument 
    in function ets:match_object/2 
     called as ets:match_object(24593,'_') 
    in call from ets:tab2list/1 (ets.erl, line 323)