我在Erlang中有一个奇怪的行为: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桌子是否被摧毁了?这是ET的错误吗?
谢谢。
shell进程创建了ETS表,是它的所有者。当所有者进程删除ETS表时,将自动删除ETS表。
因此,当您在6
上获得异常时,外壳过程死亡,以便删除ETS表。
使其private
也意味着没有其他进程可以访问它(因此,即使表格持续存在,新的外壳也无法访问它),但是在这种情况下,由于删除了表已被删除,因此更糟。
(太大而无法作为对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)