Two suggestions for future version of Ruby that wold make warning levels more intuitive easier to work with.
First, rename $VERBOSE to $WARN for these reasons:
ruby flags that set $VERBOSE are -w and -W (warnings levels).
$VERBOSE controls output produced by warn method.
$VERBOSE and FileUtils:Verbose are unrelated.
$WARN is shorter ;-)
Second, it is confusing that nil and false mean different levels. Instead of the current nil as level 0, false as level 1, and true as level 2, it would be nice if nil and false both mean "off", and then go from 0 on up to mean "on" of increasing degree. Just to clarify my meaning (not a use case example):
# nil, false mean no warning
if $WARN
case $WARN
when 0
# lesser level of warning
when 1
# greater level of warning
when 2
# can go higher if needed for rare use case
end
end
These are incompatible changes, but can be phased-in with support both $WARN and $VERBOSE for intermediate period.
I realized if -W0 is to remain the same meaning as it does now than one modification to the above idea is required: The warning levels must start with 1 instead of 0. Zero would be equivalent to nil. So given that, and example.rb as:
# if no warnings
if $VERBOSE.nil? -> if !$WARN
# if medium warnings
if $VERBOSE == false -> if $WARN
# if strong warnings
if $VERBOSE -> if $WARN && $WARN > 1
It would be nice if just $WARN > 1 would work for the last. But since $WARN can be nil, that's not possible. (Can nil be comparable to integers as if it were zero?) So while it would be nice for $WARN == 0 to mean no warnings, instead of nil, it would mean that a simple if $WARN would not be possible --which I think is the preferable choice.
That's a great idea! Abstracting the interface away as a method leaves the underpinnings free for adjustment. With that, it seems most intuitive that -W[level] would simply translate directly into $WARN=level. And -W0 flag would still mean "no warnings".
I worked on making an exact definition #warning?. It soon become clear to me that it was more complicated than it seemed it should be b/c what it was really calling for two methods, not just one. With two methods it becomes very simple. What do you think of:
# medium warnings
if notice?
$WARN >= 1
end
# strong warnings
if warning?(level=2)
$WARN >= level
end
That way we can use if and unless on either notice? or warning? and not have to worry about the level at all (except for supporting rare high levels >= 3).
Daniel, that does seem like an even better idea. But it's also a much bigger change. I wonder what effect would that have on performance? Also, I wonder if there could still some type of "severity" level. For instance I could imagine wanting certain warnings to behave like errors so I could root them out when testing.
I wouldn't think it would have a major impact on performance since (hopefully) not that many warnings are issued in practice.
I think compilers have a "treat warnings as errors" flag, so I suppose Ruby could do something similar. I think that's much less important for Ruby though, since often the warnings are something you can't usually do anything about, whereas in C they often indicate a possible bug.
I hope this is a related question: is one supposed to link the $VERBOSE/$WARN levels to the "Logger" object's level? If so, how?
I am currently trying to figure out if they represent the same notion, or if the $VERBOSE levels are more related to the interpreter's, and the Logger ones let under each developer's responsibility.