Skip to content

Inquiry about Number Parsing in minimist #79

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

Open
atx49559 opened this issue Apr 9, 2025 · 6 comments
Open

Inquiry about Number Parsing in minimist #79

atx49559 opened this issue Apr 9, 2025 · 6 comments

Comments

@atx49559
Copy link

atx49559 commented Apr 9, 2025

Hi,
While working with minimist, I noticed a few parsing behaviors that might be either limitations or intentional design choices. I would appreciate clarification on whether the following are expected behaviors, and whether there's a recommended approach to handle them.

Environment

  • Node.js: v22.13.0
  • minimist: v1.2.8

Cases

1. Negative number not parsed correctly when not using =

node main.js position 0 0 -3

Expected:

{ _: [ 'position', 0, 0, -3 ] }

Actual:

{ '3': true, _: [ 'position', 0, 0 ] }

2. Negative number parsed correctly only when using = syntax

node main.js position -x=0 -y=0 -z=-3

This works correctly and gives:

{ _: [ 'position' ], x: 0, y: 0, z: -3 }

Note: It would be more convenient if negative numbers could be handled the same way in both cases, without needing = syntax.

3. Float values not parsed correctly

node main.js -x=0.1

Expected:

{ _: [], x: 0.1 }

Actual:

{ _: [ 0.1 ], x: 0 }

4. Negative number parsed correctly only when not using = syntax

node main.js -x 0.1

This works correctly and gives:

{ _: [], x: 0.1 }

5. If only number stringified numbers lose their leading zeros

node main.js --name "0123"

Expected:

{ _: [], name: '0123' }

Actual:

{ _: [], name: 123 }

6. If only number stringified numbers lose their leading zeros even using = syntax

node main.js --name="0123"

Expected:

{ _: [], name: '0123' }

Actual:

{ _: [], name: 123 }

7. If use leading zeros number plus chars parsed correctly

node main.js --name "0123kk"

This works correctly and gives:

{ _: [], name: '0123kk' }

8. If use leading zeros number plus chars and using using = syntax parsed correctly

node main.js --name="0123kk"

This works correctly and gives:

{ _: [], name: '0123kk' }
@shadowspawn
Copy link
Collaborator

I am using test program

const argv = require('minimist')(process.argv.slice(2));
console.log(argv);
  1. Negative number not parsed correctly when not using =

This is expected behaviour because a digit can be used as the short flag for an option. So -3 is parsed as an option. Compared a and 3 in this example:

$ node main.js -a -3 
{ '3': true, _: [], a: true }
  1. Float values not parsed correctly

I was not able to reproduce this.

$ node main.js -x=0.1
{ _: [], x: 0.1 }
  1. If only number stringified numbers lose their leading zeros
  2. If only number stringified numbers lose their leading zeros even using = syntax

These are expected behaviours. The option argument gets recognised as a number and converted to a number.

The isNumber routine is the code that recognises numbers:

@atx49559
Copy link
Author

atx49559 commented Apr 10, 2025

Thank for response :)

For case1, I noticed that there are two ways to assign a value to x: -x 3 and -x=3.
Would you recommend using the one with =?
Or do these two forms correspond to different use cases?

I use same test program, can reproducible case3.
But the same code works in Linux, maybe this issue only happened at Windows?

So in cases like case5 and case6, even if double quotes ""are added, the number inside is still not treated as a string?

@ljharb
Copy link
Member

ljharb commented Apr 10, 2025

Although I think the actual standard allows you to keep or omit equals signs, I think the proper thing is to never use them with single-dashed options, and always use them with double-dashed options.

@shadowspawn
Copy link
Collaborator

shadowspawn commented Apr 10, 2025

There are four forms for supplying the option-argument for an argument with Minimist. The parsing result is usually the same, except for option-arguments that start with a -.

util -a AAA
util -b=BBB
util --ccc CCC
util --ddd=DDD
$ node main.js -a AAA -b=BBB --ccc CCC --ddd=DDD
{ _: [], a: 'AAA', b: 'BBB', ccc: 'CCC', ddd: 'DDD' }

Three reasons for choosing one form over another:

  • personal preference!
  • if the option argument might start with a -, use an embedded form like -x=-1 or --yyy=-2
  • if you want compatible syntax with other utilities, use -a AAA over -a=AAA as many other utilities do not use = with a short option (they expect -aAAA).

@shadowspawn
Copy link
Collaborator

shadowspawn commented Apr 10, 2025

I use same test program, can reproducible case3.
But the same code works in Linux, maybe this issue only happened at Windows?

So in cases like case5 and case6, even if double quotes ""are added, the number inside is still not treated as a string?

The difference is likely what shell you are using and how it processes the arguments BEFORE they reach minimist. Try logging out the arguments in your test program. For example, you can see why the quotes make no difference for me using zsh, the quotes got stripped by the shell processing!

const argv = require('minimist')(process.argv.slice(2));
console.log(process.argv);
console.log(argv);
$ node main.js -x="0123"
[ '-x=0123' ]
{ _: [], x: 123 }

@atx49559
Copy link
Author

atx49559 commented Apr 11, 2025

I understand the design and selection method for choosing parameters, thank you :)

About float parse, you're right that only encounter this issue on PowerShell in Windows VSCode. Other terminals at Windows like CMD and git-bash.exe can parse it correctly.

About quotes to covert number to string, I agree that if the double quotes are stripped by the shell, it becomes impossible to determine whether the value should be treated as a number or a string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants