[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: best DRY solution for this task

Ball, Donald A Jr (Library)

6/6/2007 8:13:00 PM

> so how can I do this check and outputting better? Because
> there are many
> bytes with many different meanings and as said sometimes I
> need to read
> in 4 bytes then just one then again 2 bytes... is this at all
> possible
> to do dry-like?

Without knowing the details of the file you're trying to parse it's hard
to say, but you might be well-served to write a simple finite state
machine. E.g. something like:

mode = :expect_header
while !(mode == :done || mode == :fail)
case mode
when :expect_header
if target.read(3) == $startflag
mode = :expect_debug
else
mode = :fail
end
when :expect_debug
case target.read(1)
when "\x1"
debug = true
mode = :expect_body
when "\x255"
debug = nil
mode = :expect_body
else
mode = :fail
end
end
end

- donald

1 Answer

Robert Klemme

6/7/2007 4:47:00 PM

0

On 06.06.2007 22:12, Ball, Donald A Jr (Library) wrote:
>> so how can I do this check and outputting better? Because
>> there are many
>> bytes with many different meanings and as said sometimes I
>> need to read
>> in 4 bytes then just one then again 2 bytes... is this at all
>> possible
>> to do dry-like?
>
> Without knowing the details of the file you're trying to parse it's hard
> to say, but you might be well-served to write a simple finite state
> machine. E.g. something like:
>
> mode = :expect_header
> while !(mode == :done || mode == :fail)
> case mode
> when :expect_header
> if target.read(3) == $startflag
> mode = :expect_debug
> else
> mode = :fail
> end
> when :expect_debug
> case target.read(1)
> when "\x1"
> debug = true
> mode = :expect_body
> when "\x255"
> debug = nil
> mode = :expect_body
> else
> mode = :fail
> end
> end
> end

You can even nest cases

mode = :expect_header
while !(mode == :done || mode == :fail)
case mode
when :expect_header
mode = case target.read(3)
when "\x1\x3d\x0"
:expect_debug
else
:fail
end
when :expect_debug
mode = case target.read(1)
when "\x1"
debug = true
:expect_body
when "\xff"
debug = nil
:expect_body
else
:fail
end
end
end
end

If you use nil as :fail then it becomes even simpler because you can
omit "else" branches in "case". Another alternative is to throw
immediately when an error occurs.

Just some more food for experimening.

Kind regards

robert