Feature #2709

$VERBOSE, $DEBUG and Kernel#sprintf

Added by Patrik Wenger over 5 years ago. Updated over 2 years ago.

[ruby-core:28029]
Status:Assigned
Priority:Normal
Assignee:Shyouhei Urabe

Description

=begin
Kernel#sprintf is very useful. I think the power lies within the ignorance of too many arguments. So one is free to decide which arguments he uses and which one he doesn't. This applies to a Ruby runtime where $VERBOSE and $DEBUG are false.

Following the POLS (Principle of the least surprise), one would assume that changing the variables $VERBOSE and $DEBUG wouldn't change the behavior of Kernel#sprintf. But they do.

$VERBOSE causes warnings when there are too many arguments.
$DEBUG causes an ArgumentError when there are too many arguments. This isn't useful at all.

I like the effect of $DEBUG according to threads, to raise uncaught exceptions from the thread.
But in the case of Kernel#sprintf, it's just not useful. This behavior prohibits some power of Ruby.

My suggestion:
Remove the special behavior of $VERBOSE and $DEBUG in Kernel#sprintf.

Thank you very much.
=end


Related issues

Related to Ruby trunk - Bug #5763: sprintf not throwing error for wrong number of arguments Closed 12/15/2011

History

#1 Updated by Shyouhei Urabe over 5 years ago

=begin

I think the power lies within the ignorance of too many arguments. So one is free to decide which arguments he uses and which one he doesn't.

Can you be a bit more verbose here? Please illustrate a tiny example where ignoring sprintf argumens is powerful.

=end

#2 Updated by Patrik Wenger over 5 years ago

=begin

Can you be a bit more verbose here? Please illustrate a tiny example where ignoring sprintf argumens is powerful.

At our company we have a framework to execute commands in telnet sessions on many hosts in parallel.
This framework is used in many scripts. Depending on the scripts, the needs for log files are different.
Some scripts write one log file per host and append to it in a second run.
Other scripts write one log file per telnet session, so the name of the host and some date/time integers are involved.

And that's exactly what the framework provides to the freely configurable log file format string:
hostname, year, month, day, hour, minute, second

The former scripts could then use a log path like this:
"~/log/%s"

The latter one something like this (a directory each day, a file per host and session):
"/path/to/session/logs/%2$i-%3$02i-%4$02i/%1$s_%5$02i%6$02i%7$02i"

I think this is power of Ruby. And it shouldn't be prohibited, just because one is debugging.
It wouldn't change the default behavior ($DEBUG and $VERBOSE are false) anyway. :-)
=end

#3 Updated by Patrik Wenger over 5 years ago

=begin
Any updates here?
=end

#4 Updated by Yukihiro Matsumoto over 5 years ago

=begin
Hi,

In message "Re: [Bug #2709] $VERBOSE, $DEBUG and Kernel#sprintf"
on Wed, 3 Feb 2010 19:00:23 +0900, Patrik Wenger redmine@ruby-lang.org writes:

|Following the POLS (Principle of the least surprise), one would assume that changing the variables $VERBOSE and $DEBUG wouldn't change the behavior of Kernel#sprintf. But they do.

We don't accept any proposal with the POLS reason by default, since
the background vary person to person. So don't be so lazy. Explain
why YOU have assumed Kernel#sprintf not to change behavior according
to the variables $VERBOSE and $DEBUG.

                        matz.

=end

#5 Updated by Shyouhei Urabe over 5 years ago

=begin
Yukihiro Matsumoto wrote:

We don't accept any proposal with the POLS reason by default, since
the background vary person to person. So don't be so lazy. Explain
why YOU have assumed Kernel#sprintf not to change behavior according
to the variables $VERBOSE and $DEBUG.

Take a look at . My current feeling is neutral ... I have
been helped by printf's argument checks many time so it is useful for me at
least, but it seems the reporter does have needs to ignore it.

What about it: raise exceptions as it is when arguments are too few, but not
for too many, even when $DEBUG is true.

Signed-off-by: Urabe, Shyuohei shyouhei@ruby-lang.org


sprintf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/sprintf.c b/sprintf.c
index b5cad94..ebb26eb 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -1057,7 +1057,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
*/
if (posarg >= 0 && nextarg < argc) {
const char *mesg = "too many arguments for format string";
- if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
+ if (RTEST(ruby_debug)) rb_warn("%s", mesg);
if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
}
rb_str_resize(result, blen);

Attachment: signature.asc
=end

#6 Updated by Patrik Wenger over 5 years ago

=begin
Yukihiro Matsumoto wrote:

We don't accept any proposal with the POLS reason by default, since
the background vary person to person. So don't be so lazy. Explain
why YOU have assumed Kernel#sprintf not to change behavior according
to the variables $VERBOSE and $DEBUG.

I assumed Kernel#sprintf doesn't change behavior according to the variables $VERBOSE and $DEBUG because there's absolutely no reason to raise if there are too many arguments.
The work can be done by Kernel#sprintf without errors (like when $DEBUG evaluates to false).

Shyouhei Urabe wrote:

What about it: raise exceptions as it is when arguments are too few, but not
for too many, even when $DEBUG is true.

Thank you, Shyouhei Urabe. That's what I meant. That would be great.
Sorry if I'm wrong, but the change set shown in your post, wouldn't it cause two messages to be printed, if $VERBOSE and $DEBUG are true? Maybe the line should look like this:

if (RTEST(ruby_debug) || RTEST(ruby_verbose)) rb_warn("%s", mesg);

By the way, is this warning really needed? Same reason: If there are too many arguments, there's nothing to complain about. The functionality of Kernel#sprintf isn't affected by too many arguments. So removing the warning as well would be wise I think.
=end

#7 Updated by Yukihiro Matsumoto over 5 years ago

=begin
Hi,

In message "Re: [Feature #2709] $VERBOSE, $DEBUG and Kernel#sprintf"
on Wed, 10 Feb 2010 02:05:11 +0900, Patrik Wenger redmine@ruby-lang.org writes:

|Thank you, Shyouhei Urabe. That's what I meant. That would be great.

OK, I am happy to know what you want. Could you explain why you want?
Too many arguments are error anyway, so why do you want to keep it
warning, when you are debugging?

                        matz.

=end

#8 Updated by Patrik Wenger over 5 years ago

=begin
Because, in my opinion, too many arguments aren't an error. Why is this an error for you?
Too many arguments have no impact on the functionality of Kernel#sprintf.
Too few arguments are an error, however.

My suggestion:
1. never raise or warn on too many arguments
2. always raise on too few arguments

I figured out that if you provide absolute position arguments ("%1$s"),
no warnings are issued, even if $VERBOSE or $DEBUG.
That's the way it should work with relative position arguments ("%s"), too.
=end

#9 Updated by Kazuhiro NISHIYAMA about 5 years ago

  • Category set to core
  • Target version set to 2.0.0

=begin

=end

#10 Updated by Hiroshi Nakamura over 3 years ago

  • Description updated (diff)
  • Assignee set to Shyouhei Urabe

#11 Updated by Shyouhei Urabe over 3 years ago

  • Status changed from Open to Assigned

#12 Updated by Shyouhei Urabe over 2 years ago

  • Target version changed from 2.0.0 to Next Major

I personally like this feature so I really hesitate to reject, but as matz do not like it so much, there are relatively few chances for the proposal now.

We have to persuade him.

#13 Updated by Thomas Sawyer over 2 years ago

+1 The behavior seems too surprising. In general I do not think $DEBUG and $VERBOSE should alter execution, but rather only serve to change information provided to user/developer. In other words, it should be an error, or not, independent of $DEBUG.

Also available in: Atom PDF