Feature #15817

Warnings for undef_method and remove_method on initialize()

Added by shevegen (Robert A. Heiler) about 2 months ago.

Target version:


Title: Warnings for undef_method and remove_method on initialize()

Right now ruby warns you if you remove or undefine initialize, at the least if you
run in verbose mode e. g. the -w flag.

Example for such a warning:

gtk_combo_box.rb:17: warning: undefining `initialize' may cause serious problems

What am I trying to do here, that caused this warning to appear, actually?

I am modifying some of the ruby-gtk code to extend the core gtk widgets with some
"shortcuts", that is, functionality that I may use in order to write less code when
I write ruby-gtk specific code.

Part of this means that I have to modify how initialize works for some of these
widgets; in particular enabling support for some Symbols via blocks given to the
initializer (I happily use/abuse Symbols that way; ruby-gtk has also added a few
Symbols in the last few years, in particular to avoid having to type long CONSTANT
names when it is not necessary - see Kouhei Sutou's continued efforts here).

In order to do this, and modify these gtk-widgets, I thus modify initialize - and
ruby gives me warnings here.

The first warning I actually got was:

"warning: method redefined; discarding old initialize"

Ok, fair enough. So my idea was ... "I'll simply remove the old initialize, and
then set a new one, aka my own variant. That way I won't get the warning anymore."

I then tried to use both remove_method, and undef_method, and while initialize is
removed, ruby still warns me, e. g. with the "may cause serious problems" issue.
This was the reason (and moment) for creating the issue request here.

I should say that I always run all my ruby code with warning flags enabled, set in
the shebang-header in a .rb file. I find it very useful that ruby tells me if
there may be something wrong in general. However had, in this particular case, I
actually consider ruby warning me to be a feature that I would prefer to not have,
in that particular instance. The reason is that I am actually specifically telling
ruby to get rid of the old initialize, so it is a bit surprising to me that ruby
warns me. Here the assumption may be that the ruby user did not know what was done,
and although I am still quite clueless, I actually think that in this case I knew
what I wanted to do - that is, getting rid of the old initialize, then setting a
new initialize. (Perhaps ruby could detect such a case, where the ruby users removes
the old initialize, then specifically defines a new one; this may solve the issue
here, but I have no idea how feasible this may be, or how much work. Just mentioning
it really.)

We can say that my approach is not a good one; this may well be, but the primary question
is whether ruby should warn/notify us in such a case either way.

I think you can find arguments for both cases, e. g. that ruby warns us (some people may
want this, even in this case) when it comes to undef_method/remove_method on initialize
only - but it may also equally be the case that the ruby user at hands knows what she/he/it
is doing. And I believe that in the latter case ruby should NOT warn about this. Obviously
ruby then would need a way to distinguish between these two cases:

a) the case where the user wants to see a warning, because it may be helpful or for any other reason
b) the case where the user does not want to see the warning, for whatever reason

This makes the issue request here a bit complicated, because while I actually think that
ruby should not warn in regards to undef_method/remove_method, there are also perfectly
valid use cases for the latter, where ruby should warn. One use case can be when people
dynamically add/remove methods and may "accidentally" - and automatically - remove initialize,
so in this case it would be a GOOD thing that ruby warns them. But in other cases, such as in
the use case described here, I would rather prefer to not have ruby print anything about this
to me.

There are workarounds of course - for example, I can temporarily silence on $VERBOSE, and then
re-set it to the old value. I do this in other gems.

There may be other workarounds - perhaps working on a new copy of initialize and then replacing
the old one differently (not sure if these work ... perhaps with some variant of the *eval-family).
All of which is fine - my primary reason here is that I believe it should be simple for the
ruby user to tell ruby to not warn about a specific error at hand, e. g. in all the cases where
the user knows the problem domain (and thus does not need the warning at hand).

I have no really good general suggestion in how to improve this aspect here, because it may be
better to make warnings in ruby more flexible in general. Perhaps even on a per module/class
"namespace" - a bit similar to refinements, but with a simple(r) API and a simple(r) concept.

I don't have a good proposal here either, so this is just a little bit of feedback really. (If
there are more similar comments about warnings in ruby in general, please feel free to close
the issue here and gather discussions in any other tracker issue if you feel this to be better.)

To further explain the above issue - my use case was primarily motivated in order to silence the
first warning. It took me a little bit by surprise that my course of action then led to another
warning, which sort of defeated my original intent of silencing the other warning, since I now
had a new warning issued on the commandline. :)

Hopefully I could describe the intent/idea behind the suggestion. It is of course nothing that
is hugely important, since it is just a warning and the code works fine, but I kind of like
seeing no warnings on the commandline actually (don't know why but I dislike seeing warnings
when I can avoid them).

PS: I think for the particular issue at hand, I will do the old trick with temporarily modifying
$VERBOSE. It feels a bit hackish, but it also kind of works, and I can then silence the specific
warning at hand, e. g. "wrap" the offending code part between $VERBOSE or two method calls that
modify $VERBOSE; so perhaps a more general solution may be to be able to modify $VERBOSE through
method calls in general, though I don't know if this would make the code too slow, or where this
method should reside (Kernel? Not sure) - I just think it may be nicer to read, API-wise, to have
a method rather than have to modify $VERBOSE. But that is just an opinion really; the more
important thing is that modifying $VERBOSE does work, so the functionality already exists
for us to use as-is.

Also available in: Atom PDF