Issue #11779 has been updated by Shugo Maeda.


bug hit wrote:
> > > ruby is too dynamic a language to have a clear distinction between what you're calling "static" and "dynamic"  You are labeling class bodies as "static" and methods "dynamic" but a class body is executable ruby and can be invoked by methods, so the current restriction on module_eval can be overcome with relative ease:
> > 
> > Methods are expected to be invoked more than once, so there's a significant difference from class bodies.
> > That's why static features like constant assignments are prohibited in method definitions.
> 
> Did you see the example in my previous post?  Effectively there is no prohibition against module_eval with #using in methods, because you can open a class in a method and call module_eval from there.

Other features have similar loopholes (e.g., constants can be assigned in methods by eval,
private methods can be called by Kernel#send, etc.), but it doesn't mean such restriction
is meaningless, because it can express the intention.

> Also you are forgetting a category of methods (class macros) that help initialize/modify classes through meta-programming and are meant to be called once in the class body.  Such methods should be able to do whatever the class body can do.

Perhaps, perhaps not.  I depends on what the phrase "whatever the class body can do" mean. 
For exmaple, such methods should be able to define constants in a class, but need not to
be able to define constants in the same way as in a class body.


----------------------------------------
Bug #11779: Module#using does not make sense as a method
https://bugs.ruby-lang.org/issues/11779#change-55439

* Author: bug hit
* Status: Feedback
* Priority: Normal
* Assignee: 
* ruby -v: 2.2.3
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
1. it can't be called from another method
2. the receiver must be self
3. since refinements are lexically scoped the self receiver must match the currently open class

#3 is particularly curious

```ruby
module Refinement
  refine String do
    def refined?
      true
    end
  end
end

module Foo
  def self.refined?
    ''.refined? rescue false
  end
end


module Bar
  def self.refined?
    ''.refined? rescue false
  end
  Foo.module_eval do
    using Refinement

  end
end

p Foo.refined? #false
```

The module_eval `#using` call does not raise (it's not from a method and the receiver is self), but evidently because currently open class does not match self, it does not do anything. So it should at least raise.

So `#using`, though a method, does not function as a method, which is misleading.



-- 
https://bugs.ruby-lang.org/