Feature #14133
closedModule#{define|alias|undef}_method should be made public
Description
Modules and classes can be reopened and changed (unless frozen).
This is used in many meta programming techniques.
Currently, define_method
is private, so we need to either do a class_eval
, reopen the class somehow, or resort to :send
.
As I previously stated in #6539, I feel that the use of send
should be reserved for incorrect usage of actually private methods that might change of interface or aren't meant to be called this way (e.g. respond_to_missing?
, puts
)
Matz has stated before that "class/module operations should be done in the scope.". Nevertheless, common usage shows that there are many cases where Rubyists prefer using a single line for this, even if it means having to call send.
Here are 95k+ examples of send :define_method
in the wild:
https://github.com/search?utf8=%E2%9C%93&q=language%3Aruby+%22send+%3Adefine_method%22&type=Code
Note that many of these are very bad usage of define_method
. I feel this shows that even beginner programmers will use :send
if privacy gets in the way. Let's not hinder advanced users in a failed attempt to protect the beginners.
Rails has good examples of use of send :define_method
like https://github.com/rails/rails/blob/master/actionview/lib/action_view/lookup_context.rb#L27
That's despite the fact for most metaprogramming they don't use define_method
and instead build a string of code and do a module_eval
for both performance and ease debugging (see the next lines in the example). That's not possible when the new methods must access blocks though, like in the example given.
alias_method
and undef_method
can be seen as special cases of define_method
and should have the same privacy.
55k+ examples of send :alias_method
in the wild:
https://github.com/search?utf8=%E2%9C%93&q=language%3Aruby+%22send+%3Aalias_method%22&type=Code
30k+ examples of send :undef_method
in the wild:
https://github.com/search?utf8=%E2%9C%93&q=language%3Aruby+%22send+%3Aundef_method%22&type=Code
20k+ examples of send :remove_method
in the wild:
https://github.com/search?utf8=%E2%9C%93&q=language%3Aruby+%22send+%3Aundef_method%22&type=Code