Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add :const for safer scripting #4541

Closed
wants to merge 4 commits into from

Conversation

@rhysd
Copy link

rhysd commented Jun 15, 2019

Hi all,

This PR has proposed adding :const command to Vim.

Problem

Scope of variables in Vim script function is very dynamic.

let i = 0
if some_condition
    " In heavily nested or big statements...
    let i = 1 " Unexpectedly using the same name variable
endif
echo i " => 1

This sometimes causes a bug by modifying variables unexpectedly. To prevent this, (if i is intended not to be modified,) :lockvar is effective:

let i = 0
lockvar i
if some_condition
    let i = 1  " Error
endif
echo i

However, using :let and :lockvar has following downsides:

  • it is hard to give :lockvar at everywhere it is required
  • using :let and :lockvar may not be efficient because it introduces overhead of one more command.

Solution

In JavaScript, const is provided for defining a variable.

const number = 42;
number = 99;  // TypeError: invalid assignment to const `number'

:const does the similar thing in Vim script. With it, above example can be written as follows:

const i = 0
if some_condition
    let i = 1  " E995
endif
echo i " => 1

Here :const is used instead of :let. :const internally locks the variable i. So i is no longer modifiable. And it is more efficient than using both :let and :lockvar because both are done in one command.

In addition, :const raises an error if the variable is already existing:

let x = 0
const x = 1  " => E995

So :const does not lock and overwrite existing variable unexpectedly and x is guaranteed to be a new variable.

Another use case of :const would be defining constants in the script. For example:

const s:SEP = has('win32') ? '\' : '/'

Here the constant is not intended to be modified any more. So :const is better than :let.

@brammool

This comment has been minimized.

Copy link
Contributor

brammool commented Jun 15, 2019

Thanks for doing this. I was actually thinking about this, since I was working with Javascript. And the ":const" command was available.

@k-takata

This comment has been minimized.

Copy link
Member

k-takata commented Jun 15, 2019

Fixed by 8.1.1539.

@k-takata k-takata closed this Jun 15, 2019
@rhysd

This comment has been minimized.

Copy link
Author

rhysd commented Jun 16, 2019

@brammool

Thank you for your quick review and merge!
My name (Ryuichi Hayashida) seems missing in the patch 8.1.1539. Would you like to keep adding it at Vim 8.2 release note at runtime/doc/version8.txt in your mind?

@rhysd rhysd referenced this pull request Jun 16, 2019
@brammool

This comment has been minimized.

Copy link
Contributor

brammool commented Jun 16, 2019

@rhysd

This comment has been minimized.

Copy link
Author

rhysd commented Jun 16, 2019

Will do. I didn't see your name on github.

@brammool Thank you for your kind consideration. And I'm sorry that I forgot to show my name in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.