[erlang-questions] erlang-questions Digest, Vol 15, Issue 86
John Hughes
john.hughes@REDACTED
Tue Aug 26 09:01:18 CEST 2008
>
> Ok, based on your suggestions, here is what I have.
>
> Eshell V5.5.5 (abort with ^G)
> 1> Q1 = queue:new().
> {[],[]}
> 2> Q2 = queue:in("foo", Q1).
> {["foo"],[]}
> 3> Q3 = queue:in("bar", Q2).
> {["bar"],["foo"]}
> 4> Q4 = queue:in("blah", Q3).
> {["blah","bar"],["foo"]}
> 5> Q5 = queue:in("stuff", Q4).
> {["stuff","blah","bar"],["foo"]}
> 6> Q6 = queue:out(Q5).
> {{value,"foo"},{["stuff","blah"],["bar"]}}
If you look at the value of Q6, you'll see it's different in structure from
the previous queues you created. And indeed, it's not a queue. The
documentation says:
out(Q1) -> Result
Types:
Result = {{value, Item}, Q2} | {empty, Q1}
Q1 = Q2 = queue()
Removes the head item from the queue Q1. Returns the tuple {{value,
Item}, Q2}, where Item is the item removed and Q2 is the new queue. If Q1 is
empty, the tuple {empty, Q1} is returned.
queue:out(Q) removes an element from the queue, but because it cannot
*modify* the original queue (no side-effects, remember?), then it must
return *both* the element it removed, and the remainder of the queue, as its
result. That's what happened above: you removed "foo" (in the first
component of the result), and the remaining queue contains "stuff", "blah"
and "bar" (in the second component).
The reason that the first component is {value,"foo"} and not just "foo" is
that the queue might have been empty, in which case no element can be
removed. queue:out returns empty as the element in that case. Of course, the
queue might actually contain the atom empty as one of its elements. To
ensure that this case can't be confused with an empty queue, queue:out tags
real queue elements with the value tag, as you see above--so if we did
remove an element empty from a queue, then the first component of the result
would be {value,empty}, not empty.
So, if you want to remove an element from a queue (and you know for sure
that the queue is not empty), then instead of
Q6 = queue:out(Q5).
you should write
{{value,X},Q6} = queue:out(Q5).
Then X will be bound to the element ("foo" in this case), and the code below
will work. What the error report means, by the way, is that you passed a bad
argument to queue:in--and it was the pair {{value,"foo"}...}, which was
expected to be a queue, but wasn't.
> 7> Q7 = queue:in("stuff1", Q6).
>
> =ERROR REPORT==== 25-Aug-2008::20:23:40 ===
> Error in process <0.31.0> with exit value: {badarg,[{queue,in,
> ["stuff1",{{value,"foo"},{["stuff","blah"],["bar"]}}]},
> {erl_eval,do_apply,5},{erl_eval,expr,5},{shell,exprs,6},
> {shell,eval_loop,3}]}
>
> ** exited: {badarg,[{queue,in,
> ["stuff1",
> {{value,"foo"},{["stuff","blah"],
> ["bar"]}}]},
> {erl_eval,do_apply,5},
> {erl_eval,expr,5},
> {shell,exprs,6},
> {shell,eval_loop,3}]} **
>
By the way, the queue representations used by the queue module are always
pairs of lists of elements, so if you see something different, you know it's
not a queue.
John
More information about the erlang-questions
mailing list