Project

General

Profile

Actions

Feature #22136

closed

`sprintf` shouldn't raise ArgumentError when $DEBUG is set

Feature #22136: `sprintf` shouldn't raise ArgumentError when $DEBUG is set

Added by byroot (Jean Boussier) 26 days ago. Updated 16 days ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:125889]

Description

Expected behavior

If I'm tracking down a problem and suspect an error might be swallowed somewhere, I do run my test case with RUBYOPT="-d" (or simply set $DEBUG = true.

I do expect the program to execute all in the same way than without -d, expect for extra output on STDERR.

Actual behavior

If some code happens to call sprintf or String#% with too many arguments, then it will raise an error and likely break the program, preventing me from simply running the same code but in debug mode.

Reproduction

$ ruby -e 'sprintf("foo", "bar"); p :ok'
:ok

$ ruby -We 'sprintf("foo", "bar"); p :ok'
-e:1: warning: too many arguments for format string
:ok

$ ruby -dWe 'sprintf("foo", "bar"); p :ok'
Exception 'LoadError' at .../lib/ruby/4.0.0/rubygems.rb:1423 - cannot load such file -- rubygems/defaults/operating_system
Exception 'LoadError' at .../lib/ruby/4.0.0/rubygems.rb:1438 - cannot load such file -- rubygems/defaults/ruby
Exception 'ArgumentError' at -e:1 - too many arguments for format string
Exception 'RuntimeError' at <internal:ast>:96 - cannot get AST for ISEQ compiled by prism
-e:1:in 'Kernel#sprintf': too many arguments for format string (ArgumentError)
	from -e:1:in '<main>'

Bug or Feature?

I looked around the Ruby codebase, as far as I can tell this is the only method behaving this way (aside from its aliases like String#%).

So I filed this as a Feature, but really in my opinion it is a bug.

Pull Request: https://github.com/ruby/ruby/pull/17579

Updated by byroot (Jean Boussier) 26 days ago Actions #1

  • Description updated (diff)

Updated by byroot (Jean Boussier) 26 days ago Actions #3 [ruby-core:125900]

I don't think so, the code very explicitly raises in debug mode:

if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);

And that has been the case for at least 18 years: https://github.com/byroot/ruby/commit/549c345cefe03ab3f35b9cca1192a0062f288eca, and speced for about as long: https://github.com/ruby/spec/blame/06fba2498a086886191d05b91f57f1e54bf47e8f/core/string/modulo_spec.rb#L103

Updated by matz (Yukihiro Matsumoto) 16 days ago Actions #4 [ruby-core:126023]

Accepted.

The $DEBUG flag is meant to add diagnostic output, not to change program behavior. Raising ArgumentError for extra arguments only under -d violates that expectation and can prevent the very debugging session it was supposed to help. A warning on $stderr is enough.

Matz.

Updated by byroot (Jean Boussier) 16 days ago Actions #5

  • Status changed from Open to Closed

Applied in changeset git|64450290f3b8e3f3653cc399f388e473ea8fb66a.


sprintf.c: don't raise "too many arguments" errors when $DEBUG is set

[Feature #22136]

This is as far as I can tell the only method that changes its behavior
in debug mode, and that's all but helpful because it might cause
the program to abort.

Usually when you run a program with $DEBUG set, it is to find some
error that may have been swallowed, so aside from the extra output
you would expect Ruby to behave the same than in normal mode.

Actions

Also available in: PDF Atom