2015-04-30 10:56 GMT+03:00 Olaf Dabrunz <[email protected]>:
> Example:
>
> :let d = {'a': 99, 'b': 100}
> :lockvar 1 d
> :call extend(d, {'a': 123})
> E741: Value is locked: extend() argument
> :let d.a = 123
> :let d
> d {'a': 123, 'b': 100}
>
> The dictionary is locked, but the 'a' item is not, so extend() on 'a'
> should succeed in the same way as the 'let' does. According to ':he
> lockvar', a dictionary lock protects against item deletion and addition,
> but not against changing an existing item.
>
> BTW, protection against item deletion and addition works:
>
> :call extend(d, {'x': 'new'})
> E741: Value is locked: extend() argument
>
>
> diff -r 18d84ed365a5 src/eval.c
> --- a/src/eval.c Wed Apr 22 22:18:22 2015 +0200
> +++ b/src/eval.c Thu Apr 30 09:09:37 2015 +0200
> @@ -10524,6 +10524,8 @@ dict_extend(d1, d2, action)
> }
> if (di1 == NULL)
> {
> + if (tv_check_lock(d1->dv_lock, arg_errmsg, TRUE))
> + break;
> di1 = dictitem_copy(HI2DI(hi2));
> if (di1 != NULL && dict_add(d1, di1) == FAIL)
> dictitem_free(di1);
> @@ -10601,8 +10603,7 @@ f_extend(argvars, rettv)
>
> d1 = argvars[0].vval.v_dict;
> d2 = argvars[1].vval.v_dict;
> - if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE)
> - && d2 != NULL)
> + if (d1 != NULL && d2 != NULL)
> {
> /* Check the third argument. */
> if (argvars[2].v_type != VAR_UNKNOWN)
> diff -r 18d84ed365a5 src/testdir/test55.in
> --- a/src/testdir/test55.in Wed Apr 22 22:18:22 2015 +0200
> +++ b/src/testdir/test55.in Thu Apr 30 09:09:37 2015 +0200
> @@ -408,6 +408,20 @@ let l = [0, 1, 2, 3]
> :endtry
> :$put =string(d)
> :"
> +:$put ='extend() after lock on dict (existing: yes, new: no):'
> +:unlet! d
> +:let d = {'a': 99, 'b': 100}
> +:lockvar 1 d
> +:try
> +: $put =string(extend(d, {'a': 123}))
> +: $put ='did extend() existing item'
I think :try should be here, not above.
> +: $put =string(extend(d, {'x': 'new'}))
> +: $put ='did extend() with new item'
> +:catch
> +: $put =v:exception[:14]
> +:endtry
> +:$put =string(d)
> +:"
Here some crucial tests are missing:
1. `extend(d, {'a': 456, 'x': 'new'})` without try/catch.
2. Same in a try/catch.
3. Both repeated with a second argument to `extend` where `keys(arg)`
returns `[old_key1, new_key2, old_key3]` (this is needed to make sure
that all old keys are modified).
Unless it is possible for `extend` to modify *all* old keys regardless
the internal order I would prefer the current behaviour where you at
least always know that nothing will be modified. It is a completely
useless behaviour to partially modify a dictionary depending on key
ordering which is not controlled by a plugin developer.
Test should also test the order of the `keys()` output to make sure
that it will be modified once changes that affect internal hash
ordering are pushed.
> :$put ='No remove() of write-protected scope-level variable:'
> :fun! Tfunc(this_is_a_loooooooooong_parameter_name)
> : try
> diff -r 18d84ed365a5 src/testdir/test55.ok
> --- a/src/testdir/test55.ok Wed Apr 22 22:18:22 2015 +0200
> +++ b/src/testdir/test55.ok Thu Apr 30 09:09:37 2015 +0200
> @@ -138,6 +138,10 @@ did map()
> No extend() after lock on dict item:
> Vim(put):E741:
> {'a': 99, 'b': 100}
> +extend() after lock on dict (existing: yes, new: no):
> +did extend() existing item
> +Vim(put):E741:
> +{'a': 123, 'b': 100}
> No remove() of write-protected scope-level variable:
> Vim(put):E795:
> No extend() of write-protected scope-level variable:
>
> --
> Olaf Dabrunz (oda <at> fctrace.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
>
> ---
> You received this message because you are subscribed to the Google Groups
> "vim_dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
--
--
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
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.