From: ruby-core@... Date: 2016-08-25T18:44:25+00:00 Subject: [ruby-core:77068] [Ruby trunk Feature#12697] Why shouldn't Module meta programming methods be public? Issue #12697 has been updated by Marc-Andre Lafortune. Hi, As stated by bughit, a typical case where we have to resort to `send` for these is in meta programming, say: def self.included(base) base.send(:define_method, :foo) { ... } unless base.column_names.include?(:foo) end Yukihiro Matsumoto wrote: > I still believe > > ``` > class String > include Term::ANSIColor > end > ``` > > is far better than `String.include Term::ANSIColor`. It is clearer and has more space to optimize. I respect your opinion. Please realize that not everybody agree with this though. I feel that `String.include Term::ANSIColor` is clearer as it does one and one thing only. It's a single atomic operation. The `class ...` form, for me, means "Reopen the class", followed by "include ANSIColor", followed by "ok, that's actually all we wanted to do for this class". The same way some people will prefer if some_condition do_this_single_thing end I usually prefer do_this_single_thing if some_condition Typical scenario of a gem: define modules in `lib/my_gem/...`, then in `lib/my_gem.rb`: require_relative 'lib/...' String.include MyGem::StringExtension SomethingElse.extend MyGem::Something That is my preference over require_relative 'lib/...' class String include MyGem::StringExtension end class SomethingElse extend MyGem::Something end Here are some actual examples of other people that feel this way, from a quick github search: https://github.com/edgecase/authorize_me/blob/4a1ccf42b2d89a53cafbc0cb4ace236b57ba12ea/rails/init.rb https://github.com/redradiant/centsible/blob/e4cc35ee1ccb8b1e66992bc18a9b7a26643affe4/vendor/bundle/ruby/1.9.1/gems/recaptcha-0.2.3/lib/recaptcha/merb.rb https://github.com/nbino/eegloo/blob/a51e6ba77616bc4dd84c76bd0bf07f7ada3a7bd7/vendor/plugins/paginating_find/init.rb https://github.com/mailserv/mailserv/blob/36b9ff211ba71df0b77aa9de2f6382f60787151b/admin/vendor/plugins/spawn/init.rb etc. The search returns over 2.6 million hits (but that includes a lot of duplicates): https://github.com/search?utf8=%E2%9C%93&q=send+include+language%3Aruby+&type=Code&ref=searchresults > Besides that the fact that `include` etc may have huge performance penalty is also a reason to prohibit casual class/module modification. I'm afraid I don't see this; I feel that if a programmer is calling `include`, then it is because `include` is needed. It will be called no matter what. I doubt this prevented a single misuse of `include`! > Is there any reason to allow this in addition to saving extra few keystrokes? As I stated in my original request, I feel that calling `send` is what should be discouraged, not `include`. Using `public_send` is fine, but needing to use `send` means: - I'm doing something I shouldn't be doing - I'm calling a method that was not intended for me to call - this might break or have unintended consequences, now or in the future But classes are *intended* to be augmented, to have methods defined, to have plugins included in them. We shouldn't have to use `send` to do that. ---------------------------------------- Feature #12697: Why shouldn't Module meta programming methods be public? https://bugs.ruby-lang.org/issues/12697#change-60290 * Author: bug hit * Status: Feedback * Priority: Normal * Assignee: Yukihiro Matsumoto ---------------------------------------- Methods like alias_method, attr_accessor, define_method, and similar I don't think Ruby discourages this kind of meta programming, so why make it less convenient, by necessitating `send` or `module_eval`? -- https://bugs.ruby-lang.org/ Unsubscribe: