1

My goal is, given a positive integer, write a function to remove the leading digit and return the number given by the remaining digits. I have two ways of doing it presented here, and I'd like the know which is the more correct way of doing it.

  1. The first one seems to implicitly convert the number to a string, from which [1:] will return all but the first digit. Then we convert it back to a number.
  2. The second function takes a strictly mathematical approach, using the % operator with an appropriate power of 10 as the divisor.
function RemoveWithSublist(n)
    return str2nr(a:n[1:])
endfunction

echomsg 'RemoveWithSublist Tests...'
echomsg '  Number Returned:                   '.type(RemoveWithSublist(314159)).' == '.v:t_number
echomsg '  Leading 1 Removed:                 '.RemoveWithSublist(1234).' == '.234
echomsg '  Intermediate Zeroes Also Removed:  '.RemoveWithSublist(10042).' == '.42
echomsg '  Intermediate Zeroes Also Removed:  '.RemoveWithSublist(100000).' == '.0

function RemoveWithMath(n)
    return a:n % float2nr(pow(10, floor(log10(a:n))))
endfunction

echomsg 'RemoveWithMath Tests...'
echomsg '  Number Returned:                   '.type(RemoveWithMath(314159)).' == '. v:t_number
echomsg '  Leading 1 Removed:                 '.RemoveWithMath(1234).' == '.234
echomsg '  Intermediate Zeroes Also Removed:  '.RemoveWithMath(10042).' == '.42
echomsg '  Intermediate Zeroes Also Removed:  '.RemoveWithMath(100000).' == '.0

Sourcing this vim script outputs the following text, showing identical results. I like the Sublist approach because it's shorter and IMHO, easier to understand. Is the implicit conversion to string a guaranteed behavior in Vim, or did I stumble upon something that shouldn't be allowed?

RemoveWithSublist Tests...
  Number Returned:                   0 == 0
  Leading 1 Removed:                 234 == 234
  Intermediate Zeroes Also Removed:  42 == 42
  Intermediate Zeroes Also Removed:  0 == 0
RemoveWithMath Tests...
  Number Returned:                   0 == 0
  Leading 1 Removed:                 234 == 234
  Intermediate Zeroes Also Removed:  42 == 42
  Intermediate Zeroes Also Removed:  0 == 0

1 Answer 1

2

Is the implicit conversion to string a guaranteed behavior in Vim?

Yes, in Vim 8 script, which is the default scripting language, this is a guaranteed behavior. See :help expr-[:], which describes the [1:] operator in use here. That help section includes this passage:

In legacy Vim script ... If expr9 is a Number it is first converted to a String.

This behavior goes away in Vim 9 script, but as mentioned above, Vim 8 script is and might continue being the default scripting language even after Vim 9 ships, you need to explicitly opt into using Vim 9 script at least for the time being.

If you want to be explicit about the conversion, you can always use the string() function to convert the argument explicitly:

function RemoveWithSublist(n)
    return str2nr(string(a:n)[1:])
endfunction
1
  • 1
    Thanks, @filbranden. That explains it well, and I'll add the string() function to make it explicit without adding confusion.
    – Phil R
    Mar 15 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.