Re: Proposal for a (small) enhancement to the value() function.

new topic     » goto parent     » topic index » view thread      » older message » newer message

Pete Lomax wrote:
> 
> 
> I've really only been skimming this thread, but a suggestion which just might
> possibly make everyone happy is instead of:
> }}}
<eucode>
>     return {s,v,c,l}
> </eucode>
{{{

> where c, l are local vars to count chars read, leading spaces, do this:
> }}}
<eucode>
>     return {s,v}
> ...
> global function Get_extra_info()
> -- retrieve extra info about the immediately preceding get()/value() call
> -- (if unsuccessful, it should indicate the exact point of error)
>     return {c,l} --{chars read, leading spaces}
> end function
> </eucode>
{{{

> Instead of c, I would re-use string_next (NB with changes below, now 0..len,
> was 1..len+1), and use leading_chars instead of l. In both value() and get(),
> initialise string_next to 0 and leading_chars to -1, and:
> }}}
<eucode>
> procedure get_ch()
>     if sequence(input_string) then
>         if string_next < length(input_string) then    -- (was <=)
> 	      string_next += 1                          -- (was after next)
>             ch = input_string[string_next]
>         else
> 	      ch = GET_EOF
>         end if
>     else    
>         string_next += 1                              -- (new)
>         ch = getc(input_file)
>     end if
> end procedure
> 
> procedure skip_blanks()
> -- skip white space
> -- ch is "live" at entry and exit
> 
>     while find(ch, " \t\n\r") do
>         get_ch()
>     end while
>     if leading_chars=-1 then                         -- (new)
>         leading_chars=string_next-1                  -- (new)
>     end if                                           -- (new)
> end procedure
> </eucode>
{{{

> At least I think that would do everything asked for. I don't think you need
> to modify/duplicate Get() at all. The above is just a suggestion, completely
> untested of course.
> 

The problem with this approach is that Get() calls both itself and
skip_blanks(). skip_blanks() should record stuff only on its very first
invocation. Total character count can be read right before the outermost instance
of Get() returns, so it is not affected. Use "{   2}" as a test case: leading
spaces should be 0, not 3.
To avoid the penalty of endlessly testing whether the current instance of Get()
is the outermost one, which is often false in the case of strings representing
sequences, I defined a modified Get2(), which value() calls and then calls the
regular Get() for any inner subobjects. If you prefer doing that in skip_blanks()
instead, no problem. leading_whitespace will become local instead of private to
Get2().

As for defining an extra get_read_characters(), which would return the extra
info, well I'd go with it, the job will get done. Could you explain, however, why
this alternative scheme is preferable? It makes one extra public function to
document, instead of extra returned values. Otherwise, it is completely
equivalent. Oh right, you must be careful to call get_read_characters(), if you
wish, before calling value() or get() again - I assume this is a minor issue. And
not to accidentally call get_read_characters() before value(). My proposal
avoided all these small issues.

> Someone needs to conjure up a decent test script for the changes though, one
> that ensures no existing functionality is damaged in any way whatsoever, bar
> an inevitable, tiny and utterly insignificant performance hit.

Rob, don't you have a test suite available for Euphoria? It would be a good
addition to the SVN repository. This solution would ensure a uniform level of
quality control. Tests could be freely added, but none modified or removed from
such a suite.

> 
> Now, does anyone have any objections to that?
> 
> Regards,
> Pete
> PS I have no quibble with adding Derek's routine at the same time.

CChris

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu