Hi Jesper,<br><br>Can you explain why length is a bad idea? I do not deny that matching left and right expressions is also a solution, but I see no difference. So, please, if you know a bug about length, I am interested in knowing about.<br>
<br>-------------------<br>> 7. How to use the test:<br>
> receive_function(Packet) when is_my_record(Packet) == true -><br>
> do_something_with_my_packet;<br>
> receive_function(Packet) when is_my_record(Packet) /= true -> I_do_not_care.<br>
<br>
You can't do this in Erlang. Guard expressions are limited so you can<br>
be sure they terminate.<br>
-------------------<br><br>Please, take a better look and you will notice I haven't used guarded function for recursion, but for condition. What you said is okay for recursion.<br><br>In addition, I didn't say that was the best way to do it, but just an example. Jovi needed an example and I gave. I am sorry if my code offended you so much to call it "garbage". Feel free to propose the best working idea for this case.<br>
<br>Cheers,<br>CGS<br><br><br><br><br><div class="gmail_quote">On Tue, Sep 20, 2011 at 3:45 PM, Jesper Louis Andersen <span dir="ltr"><<a href="mailto:jesper.louis.andersen@gmail.com">jesper.louis.andersen@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">On Mon, Sep 19, 2011 at 08:26, George Catalin Serbanut<br>
<<a href="mailto:cgsmcmlxxv@gmail.com">cgsmcmlxxv@gmail.com</a>> wrote:<br>
> Considering all variables integers, here is an example how to play with<br>
> records:<br>
<br>
</div>I'll move the quotes around a bit...<br>
<div class="im"><br>
> 7. How to use the test:<br>
> receive_function(Packet) when is_my_record(Packet) == true -><br>
> do_something_with_my_packet;<br>
> receive_function(Packet) when is_my_record(Packet) /= true -> I_do_not_care.<br>
<br>
</div>You can't do this in Erlang. Guard expressions are limited so you can<br>
be sure they terminate.<br>
<div class="im"><br>
> 6. Binary tester:<br>
> is_my_record(Binary) -><br>
>     L = re:split(binary_to_list(Binary),?SEPARATOR,[{return,list}]),<br>
>     if length(L) == 3 -> Result = lists:all(fun(E) -> TL =<br>
> string:join(string:tokens(E,"0123456789"),""), if length(TL) == 0 -> Result<br>
> = true; length(TL) /= 0 -> Result = false end, Result end,L),<br>
>        length(L) /= 3 -> Result = false,<br>
>     end,<br>
>     Result.<br>
<br>
</div>This part can be done much more beautifully. length is generally a bad<br>
idea when a match will do:<br>
<br>
is_my_record(B) -><br>
  case re:split(binary_to_list(B), ?SEP, [{return, list}]) of<br>
     [A, B, C] = L -><br>
       lists:all(fun(E) -> string:join(string:tokens(E,"0123456789"),<br>
"") == [] end, L);<br>
     _ -> false<br>
  end.<br>
<br>
I'd probably write (not tested, subject to infinite failure):<br>
<br>
is_digit(C) when C >= $0 andalso C =< $9 -> true<br>
is_digit(C) -> false.<br>
<br>
all_digits(B) when is_binary(B) -> all_digits(binary_to_list(B)); %<br>
Building a traverser over binaries will be faster<br>
all_digits(L) -> lists:all(fun is_digit/1, L).<br>
<br>
is_my_record(B) -><br>
  case binary:split(B, <<?SEP>>, [global]) of<br>
    [A, B, C] = L -> lists:all(fun all_digits/1, L);<br>
    _ -> false<br>
  end.<br>
<br>
all_digits/1 is inefficient. But we can write:<br>
<br>
all_digits(F, <<>>) -> true;<br>
all_digits(F, <<C:8/integer, R/binary>>) -><br>
  F(C) andalso all_digits(F, R). % I can't remember if andalso is tail<br>
recursive. It should be. If not, replace this with a case.<br>
<br>
This avoids the creation of lots and lots of garbage. It also avoids<br>
the pesky re-library which is usually a bad idea :) And I believe it<br>
is a tad more readable.<br>
<font color="#888888"><br>
--<br>
J.<br>
</font></blockquote></div><br>