views:

80

answers:

3

Hi Everyone,

I have a variable:

Data = [[<<>>, 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]] 

I am trying to pattern match for two specific cases..

One where anything that resembles the outside structure - simply [] Anything inside goes I have tried [ _ ] but no go?

The Second, for a specific pattern inside, like when I see a <<"10">> or <<"112">> or <<"52">> then I am going to take the right side which is the actual data into an atom. Basically the <<"10">> or <<"112">> or <<"52">> are the fields, the right side the data.

I have tried statements like [<<"10">>, _ ] still no go

Here is the rest of the code:

dataReceived(Message) ->
    receive
        {start} -> 
            ok;

        [ _ ] ->   %%No go
            io:format("Reply 1 = ~p~n", [Message]);

                [<<"10">>, _ ] ->   %%No go
            io:format("Reply 1 = ~p~n", [Message])


    end.

As a note the Message is not sent as a tuple it is exactly like Data =

Can anyone lead me in the right direction?

Thanks and Goodnight! -B

UPDATE

Ok now I think Im getting warmer, I have to pattern match whatever comes in.

So if I had say

Message = = [[<<>>], 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]]

And I was looking to pattern match the field <<"112">>

Such as the 112 is always going to say 112, but the Gen2067 can change whenever to whatever.. its the data, it will be stored in a variable.

loop() ->
receive
    [_,[<<"112">>, Data], _] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

I feel im close, but not 100%

-B

+1  A: 

Update OP is trying to pass an argument to the function and not send messages.

As the name indicates the receive block is used to receive and process messages sent to a process. When you call dataReceived with an argument it proceeds to wait for messages. As no messages are sent it will continue to wait endlessly. Given the current code if you want it to do something then you'll have to spawn the function, get the process ID and then send a message to the process ID.

You probably need a function where the argument is pattern matched and not messages.

Something like this:

dataReceived([Message]) when is_list(Message) ->
    io:format("Got a list as arg ~p~n", [Message]);
dataReceived(_Other) ->
    io:format("Unknown arg ~p~n", [_Other]).

On a side note your third pattern [X] when is_list(X) will never match as the second pattern is a superset of the third. Anything that matches [X] when is_list(X) will always match [X] and therefore your third match clause will never get triggered.

Original Answer

I am not sure I understand your question. Are you trying to send a message to the function or are you passing it an argument?

This is a partial answer about how to match a list of lists in case you are sending a message.

-module(mtest).
-export([run/0]).

-ifdef(debug).
-define(DEBUG(Format, Args), io:format(Format, Args)).
-else.
-define(DEBUG(Format, Args), void).
-endif.

loop() ->
receive
    [X] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

Take a look at the first clause in the receive block. [X] when is_list(X) will bind the inner list to the name X. I tested it with the value of Data you provided and it worked.

%% From the shell.
1> c(mtest, {d, debug}).
{ok,mtest}
2> Pid = mtest:run().
<0.40.0>
3> Data = [[<<>>, [<<"10">>,<<"171">>], [<<"112">>,<<"Gen20267">>], [<<"52">>,<<"20100812-06:32:30.687">>]]].
[[<<>>,
  [<<"10">>,<<"171">>],
  [<<"112">>,<<"Gen20267">>],
  [<<"52">>,<<"20100812-06:32:30.687">>]]]
4> Pid ! Data.
[[<<>>,
  [<<"10">>,<<"171">>],
  [<<"112">>,<<"Gen20267">>],
  [<<"52">>,<<"20100812-06:32:30.687">>]]]
Got a list [<<>>,
            [<<"10">>,<<"171">>],
            [<<"112">>,<<"Gen20267">>],
            [<<"52">>,<<"20100812-06:32:30.687">>]]
5> 
Manoj Govindan
A: 

To clarify I am sending a Message as an argument to the function.

Message = = [[<<>>, 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]] 

I must have done a little something wrong, still nogo. (Thanks for the first help anyway!)

Take a look:

dataReceived(Message) ->
    receive
        {start} -> 
            ok;
        [X]  ->
            io:format("Reply 1 = ~p~n", [X]);

        [X] when is_list(X) -> 
            io:format("Reply 1 = ~p~n", [Message])



    end.

Neither one will output at all after I call this func with Message.

A: 

Ok now I think Im getting warmer, I have to pattern match whatever comes in.

So if I had say

Message = = [[<<>>], 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]] 

And I was looking to pattern match the field <<"112">>

Such as the 112 is always going to say 112, but the Gen2067 can change whenever to whatever.. its the data, it will be stored in a variable.

loop() ->
receive
    [_,[<<"112">>, Data], _] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

I feel im close, but not 100%

-B