| Author |
Message |
< Advanced Erlang/OTP ~ Processing records extracted from Mnesia problem |
| brett hallett |
Posted: Wed Sep 19, 2007 5:15 am |
|
|
|
User
Joined: 21 Aug 2007
Posts: 21
|
Playing with Joe Armstrong's 'Bank' example, I am trying to develop a function the returns all the account records
so I can print a report.
When I execute the folowing :
========== function in bank.erl ===========================
accounts() -> %% returns :{atomic,{atomic,[[{account,"joe",0}],
%% [{account,"richard",19800}],
%% [{account,"brett",4000}]]}}
fun() ->
M = fun() ->
[mnesia:dirty_read(account, Key) || Key <- mnesia:dirty_all_keys(account)]
end,
mnesia:transaction(M)
end.
===================================
4> bank_client:accounts().
{atomic,{atomic,[[{account,"joe",0}],
[{account,"richard",19800}],
[{account,"brett",4000}]]}}
===================================
Which is correct, , but how do I process the returned result ??
If I set up K ( in the erl shell) , thus :
K = {atomic,{atomic,[[{account,"joe",0}],[{account,"richard",19800}],[{account,"brett",4000}]]}}.
it takes two tuple element extractions to 'get to' the List of accounts for printing purposes,
this seems a bit clumsy !
==================================
eg:
Eshell V5.5 (abort with ^G)
1> K = {atomic,{atomic,[[{account,"joe",0}],[{account,"richard",19800}],[{account,"brett",4000}]]}}.
{atomic,{atomic,[[{account,"joe",0}],
[{account,"richard",19800}],
[{account,"brett",4000}]]}}
2> K1 = element(2,K).
{atomic,[[{account,"joe",0}],
[{account,"richard",19800}],
[{account,"brett",4000}]]}
3> K2 = element(2,K1).
[[{account,"joe",0}],[{account,"richard",19800}],[{account,"brett",4000}]]
What is the appropriate technique to use ???
Thanks. |
|
|
| Back to top |
|
| Mazen |
Posted: Wed Sep 19, 2007 8:17 am |
|
|
|
User
Joined: 20 Jul 2006
Posts: 164
Location: London
|
I would suggest patternmatching...
If you know that the value will look like this:
then you would use the following to get the Value:
Code:
{_,{_,Val}} = function_that_returns_that_structure();
If you wan return different structures, use a case clause and patternmatch directly on that. Eg.
Code:
case function_that_returns_different_structures() of
{_,{_,V}} -> V;
{_, V} -> V
end.
On a side note: Are you sure you are getting a list of {atomic, {atomic, ...}} ? Because you are using dirty_reads and you shouldn't get {atomic, _} on a dirty read. Second, if you are using dirty read, why doing so in a transaction? It defeats the purpose doesn't it?
GL,
/Mazen |
|
|
| Back to top |
|
| brett hallett |
Posted: Wed Sep 19, 2007 10:11 pm |
|
|
|
User
Joined: 21 Aug 2007
Posts: 21
|
Thanks for your reply,
1) yes I do get the data returned in the format show,
I had tried a number of variations of what you suggest -- without success !
2) I did not know that ditry_reads could operate
'outside' the mnesia:transaction framework. Thanks fror that very useful info.
I'm still feeling my way with Erlang , a very interesting language indeed. |
|
|
| Back to top |
|
| brett hallett |
Posted: Sat Sep 22, 2007 4:51 am |
|
|
|
User
Joined: 21 Aug 2007
Posts: 21
|
Following mazen's information I changed my dirty_reads as per accounts() below, and then started expirementing
with possible printing options -- now some confusion beging !.
======================================
accounts() -> %% returns :{atomic,{atomic,[[{account,"joe",0}],
%% [{account,"richard",19800}],
%% [{account,"brett",4000}]]}}
M2 = [mnesia:dirty_read(account, Key)
|| Key <- mnesia:dirty_all_keys(account)],
print(M2),
print2(M2).
%%% ============
print( [L1 | L ]) -> %% {account,"joe",0}
io:fwrite("print1:",[]),
io:fwrite('~p ~n', L1),
print(L);
print([]) ->
io:fwrite("** end accounts list 1 ***~n", []),
ok.
%%% ============
print2( [L1 | L ]) ->
io:fwrite("print2:",[]),
io:fwrite('~p ~n', L1),
print2(L);
print2([]) ->
io:fwrite("** end accounts list 2 ***~n", []),
ok.
=======================================
shell output is:
c(bank).
{ok,bank}
53> bank_client:accounts().
print1:{account,"joe",0}
print1:{account,"richard",19800}
print1:{account,"brett",4000}
** end accounts list 1 ***
print2:{account,"joe",0}
print2:{account,"richard",19800}
print2:{account,"brett",4000}
** end accounts list 2 ***
{aborted,{badarg,ok,[],infinity,mnesia}}
print & print2 output is the same, as expected, however when I change print2 thus :
%%% ============
print2( [L1 | L ]) ->
io:fwrite("print2:",[]),
{A,B,C} = L1, %%%% new
io:fwrite('~p ~n', L1),
io:fwrite("Account : ~s Name: ~s Balance: ~s ~n", [A, B, C]), %%%% new
print2(L);
print2([]) ->
io:fwrite("** end accounts list 2 ***~n", []),
ok.
===============================
the fwrite(s) just stuff up and abort !
I've tried MANY different formats ( ~p, ~s, ~w etc ) without sucess, but the most annoying thing
is that a previously working fwrite
io:fwrite('~p ~n', L1),
does not work now ???
I should get
print2:{account,"joe",0}
, but only 'print2:' appears.
I assume the 'badmatch' below is something to do with my format statement, but I'm
not really sure about that at all !!!
===============================
c(bank).
{ok,bank}
55> bank_client:accounts().
print1:{account,"joe",0}
print1:{account,"richard",19800}
print1:{account,"brett",4000}
** end accounts list 1 ***
print2:
=ERROR REPORT==== 22-Sep-2007::14:23:40 ===
Error in process <0.429.0> with exit value: {{badmatch,[{account,"joe",0}]},[{bank,print2,1},{bank_server,do_call,1},{bank_server,input_handler,1}]}
true
===============================
Any ideas appreciated. |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|