Issue #11779 has been updated by bug hit.


Shugo Maeda wrote:
> 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.

Of course I don't mean in the same exact way, meta-programming is different than native syntax.  However the question of "how" does not apply here, because you are arguing that it should be forbidden (not different), and I'm saying that if a class body can call a module_eval with using, then a class macro method should be able to, as well.


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

* 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/