Yasuhiro Matsumoto wrote:
> My friends found weird behavior of vimscript.
> Try following code.
> ---------------------------------------------------------
> let dict = {}
> function! dict.func()
> echo "fooooo"
> return self
> endfunction
>
> echo "=========== test1"
> if 1 | echo dict.func().func() | endif
> echo "=========== test2"
> if 1 | let a = dict.func().func() | endif
> echo "=========== test3"
> if 1 | call dict.func().func() | endif
> echo "=========== test4"
> if 0 | call dict.func().func() | endif
> ---------------------------------------------------------
>
> You'll get following errors.
> ---------------------------------------------------------
> =========== test1
> fooooo
> fooooo
> {'func': function('18')}
> =========== test2
> fooooo
> fooooo
> =========== test3
> fooooo
> fooooo
> =========== test4
> Error detected while processing C:\temp\test.vim:
> line 14:
> E488: Trailing characters
> line 15:
> E171: Missing :endif
> Press ENTER or type command to continue
> ---------------------------------------------------------
>
> Vimscript is treating letter '.' as two meanings.
> One of them is 'concat string'. Another is 'reference dictionary
> item'.
> Vim don't know that '.' is either one without evaluating script.
>
> Thus, CURRENTLY, vim is evaluating subscript gracefully and doing no-
> performs.
> For example, When the code that blocked like 'if 0 | call dict.foo() |
> endif',
> 'foo()' return 1 instead of 'self'.
> i.e. Second time of calling func() is treating 'concat string'.
> If it is broked in 'if 1', then the result should be 'self' of course.
>
> And, this problem happen only by 'call' command.
> This dont happend by 'echo', 'let'.
>
> I think that 'if 0 / endif block' can be possible to skip until eol or
> '|'.
> Below is a patch to skip until that. And success to run above test
> code.
> Please check this way.
> If you accept this way, vim may have another commands turn of this
> case.
>
> Thanks.
> - Yasuhiro Matsumoto
>
> diff -r 94694351f592 src/eval.c
> --- a/src/eval.c Fri Oct 15 20:20:05 2010 +0200
> +++ b/src/eval.c Wed Oct 20 21:12:58 2010 +0900
> @@ -3337,6 +3337,11 @@
> int failed = FALSE;
> funcdict_T fudi;
>
> + if (eap->skip) {
> + eap->nextcmd = find_nextcmd(eap->arg);
> + return;
> + }
> +
> tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
> if (fudi.fd_newkey != NULL)
> {
Quickly skipping over the :call argument appears to work. However,
find_nextcmd() does not understand expressions, it may fail. E.g. for
this:
let dict = {}
function! dict.func(a)
echo "fooooo"
return self
endfunction
if 0 | call dict.func('|').func('|') | endif
--
Luxury. We used to have to get out of the lake at three o'clock in the
morning, clean the lake, eat a handful of hot gravel, go to work at the
mill every day for tuppence a month, come home, and Dad would beat us
around the head and neck with a broken bottle, if we were LUCKY!
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php