<div class="gmail_quote">2012/11/30 Dmitry Klionsky <span dir="ltr"><<a href="mailto:dm.klionsky@gmail.com" target="_blank">dm.klionsky@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi!<br>
<br>
All below comes from <a href="http://www.erlang.org/doc/programming_examples/bit_syntax.html" target="_blank">http://www.erlang.org/doc/<u></u>programming_examples/bit_<u></u>syntax.html</a><br>
<br>
...<br>
Value:Size<br>
...<br>
The Size part of the segment multiplied by the unit in the TypeSpecifierList (described below) gives the number of bits for the segment. In construction, Size is any<br>
expression that evaluates to an integer. In matching, Size must be a constant expression or a variable.<br>
...<div class="im"><br>
<br>
<br>
And (2*8) is a legal Size:<br>
<br></div><div class="im">
7> <<Length, Value:(2*8)>> = X.<br>
<<2,1,0>><br>
<br></div>
This works because (2*8) really evaluates at compile time and it equals to<br>
<br>
<<Length, Value:16>> = X.<div class="im"><br>
<br>
<br>
<br>
12> <<Length, Value:(Length*8)>> = X.<br>
* 1: illegal bit size<br>
<br></div>
The expression (Length*8) is supported when constructing a binary. This is definitely a pattern matching, so as stated above: the Size must be a constant expression or a variable. Not an expression to be evaluated at runtime.<br>
<br>
As a workaround you can do this<br>
<br>
> <<Length, Rest/binary>> = X.<br>
> ValueLen = Length*8.<br>
> <<Value:ValueLen>> = Rest.</blockquote><div><br>Or this:<br> 2> <<Length,Value:Length/unit:8>> = X.<br><<2,1,0>><br>3> {Length,Value}.<br>{2,256}<br><br></div><div>Multiplication of a length by a constant is a special case which is supported through the 'unit' qualifier.</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
<br>
76> << [49, 50, 51, 52] >>.<br>
** exception error: bad argument<br>
<br>
77> X = "1234".<br>
"1234"<br>
<br>
78> <<X>>.<br>
** exception error: bad argument<br>
<br></div>
The only way you can do this is<br>
<br>
list_to_binary([49, 50, 51, 52]).<br>
and<br>
list_to_binary("1234").<br></blockquote><div> <br>It is a common source of confusion. The types of the items in bit syntax are always determined at compile-time, not at runtime.<br>And for items without any qualifiers, the type is "8-bit integer" (i.e., a byte).<br>
The thing is that <<"ABC">> is *syntactic sugar* for <<65,66,67>>; this (literal strings) is a special case, and it is a *syntactic* special case.<br>The runtime makes no decisions based on type, in particular, it does not dynamically treat <<X>> differently depending on whether X is bound to an integer or list value.[1]<br>
<br>/Erik<br><br>[1] Well, it does - it generates a type exception in the case of non-integers, which I suppose counts as a difference... but not in the way you intended.<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
BR,<br>
Dmitry<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On 11/30/2012 09:20 AM, 7stud wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
I have a couple of questions about the bit syntax.<br>
<br>
1) I can read the first byte of a binary to get the length of the next value:<br>
<br>
1> X = <<16, 256:16>>.<br>
<<16,1,0>><br>
<br>
2> <<Length, Value:Length>> = X.<br>
<<16,1,0>><br>
<br>
3> Length.<br>
16<br>
<br>
4> Value.<br>
256<br>
<br>
<br>
<br>
And (2*8) is a legal Size:<br>
<br>
5> f().<br>
ok<br>
<br>
6> X = <<2, 256:16>>.<br>
<<2,1,0>><br>
<br>
7> <<Length, Value:(2*8)>> = X.<br>
<<2,1,0>><br>
<br>
8> Length.<br>
2<br>
<br>
9> Value.<br>
256<br>
<br>
<br>
So why does Size = Length*8 fail when Length=2?<br>
<br>
10> f(Length).<br>
ok<br>
<br>
11> f(Value).<br>
ok<br>
<br>
12> <<Length, Value:(Length*8)>> = X.<br>
* 1: illegal bit size<br>
<br>
<br>
<br>
<br>
2) What is going on here:<br>
<br>
<br>
73> f().<br>
ok<br>
<br>
74> <<"1234">>.<br>
<<"1234">><br>
<br>
75> "1234" == [49, 50, 51, 52].<br>
true<br>
<br>
76> << [49, 50, 51, 52] >>.<br>
** exception error: bad argument<br>
<br>
77> X = "1234".<br>
"1234"<br>
<br>
78> <<X>>.<br>
** exception error: bad argument<br>
<br>
In line 74, I can use a string while constructing a binary, but in 76 I can't use the equivalent list. And in line 77, when I bind the string to a variable, I can't use the variable to construct a binary.<br>
<br>
Thanks.<br>
______________________________<u></u>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/<u></u>listinfo/erlang-questions</a><br>
</blockquote>
<br>
<br></div></div><span class="HOEnZb"><font color="#888888">
-- <br>
Best regards,<br>
Dmitry Klionsky</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
______________________________<u></u>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/<u></u>listinfo/erlang-questions</a><br>
</div></div></blockquote></div><br>