Project

General

Profile

Actions

Bug #19354

closed

Issues with arguments validation in IO.read

Bug #19354: Issues with arguments validation in IO.read

Added by andrykonchin (Andrew Konchin) almost 3 years ago. Updated almost 3 years ago.

Status:
Feedback
Assignee:
-
Target version:
-
[ruby-core:111907]

Description

I've noticed a strange error message when IO.read is called with additional positional argument:

IO.read("a.txt", 3, 0, {mode: "r+"})
# (irb):2:in `read': wrong number of arguments (given 3, expected 0..2) (ArgumentError)

But I would expect receiving given 4, expected 1..3 as far as the first argument (file name) is mandatory and all the other arguments - are optional.

I've encountered another related issue - looks like existing of a file with specified name is checked before number of arguments.

So when passed additional argument and specified a name of not existing file - I receive error about wrong file name, but would expect more basic and essential error about wrong number of arguments:

IO.read("b.txt", 3, 0, {mode: "r+"})
# (irb):3:in `read': No such file or directory @ rb_sysopen - b.txt (Errno::ENOENT)

Updated by andrykonchin (Andrew Konchin) almost 3 years ago Actions #1

  • ruby -v changed from 3.2.1, 3.2.1 to 3.2.0, 3.2.1

Updated by andrykonchin (Andrew Konchin) almost 3 years ago Actions #2

  • ruby -v changed from 3.2.0, 3.2.1 to 3.2.0, 3.1.3

Updated by nobu (Nobuyoshi Nakada) almost 3 years ago Actions #3 [ruby-core:111925]

  • Status changed from Open to Feedback

IO.read opens the file given as the first argument, then delegates the other arguments to IO#read on the instance.
Your error happens in the delegated IO#read.

Since 3.0, keyword arguments are separated from mere hashes.
I think you may want to write:

IO.read("a.txt", 3, 0, mode: "r+")

Updated by andrykonchin (Andrew Konchin) almost 3 years ago Actions #4 [ruby-core:111932]

Yeah, I understand that it's caused by the way how IO.read is implemented.

My point is that from the end-user point of view current error message (given 3, expected 0..2) is slightly misleading/confusing.

Updated by Eregon (Benoit Daloze) almost 3 years ago Actions #5 [ruby-core:112006]

I think the current error could be acceptable if it's clear IO#read is in the backtrace.
But it's not part of the backtrace currently (and on top it's not possible to differentiate IO.read and IO#read from the backtrace):

$ ruby -e 'IO.read("a.txt", 3, 0, {mode: "r+"})'      
-e:1:in `read': wrong number of arguments (given 3, expected 0..2) (ArgumentError)
	from -e:1:in `<main>'

And so this is rather inconsistent (in expected args) with:

$ ruby -e 'IO.read("a.txt", 3, 0, {mode: "r+"}, 5, 6)'
-e:1:in `read': wrong number of arguments (given 6, expected 1..4) (ArgumentError)
	from -e:1:in `<main>'

The second error in the description seems clearly wrong behavior.
So I guess we should check args more strictly in IO.read itself, before calling IO#read.

Actions

Also available in: PDF Atom