As mentioned in this answer , in Ruby 2.1 or later, this code:
class SimpleTest private define_method :foo do 42 end end
will define foo as a private instance method of SimpleTest . (In Ruby 2.0, it will not be closed before.) However, I am looking to make something a little less trivial. I would like to define a DSL that classes can extend, and I would like the methods that DSL defines internally to respect the visibility of the visible / closed context of the calling context. This may not be clear, here is an example:
module Dsl def has_a(name) define_method name do 42 end end end class Test extend Dsl private has_a :thing end
As written, this code will define the public thing method in Test instances. Instead, I would like has_a to think about the visibility of the method where it was called ( private in this case), and define thing under the same visibility of the method.
I am not familiar with the source code of Ruby C, but I quickly looked through and found this function , which seems to be what I want, but I don't think it is available from Ruby. (It seems to be used only here .) I also looked at the documentation for define_method (since the first example works as desired) here and it seems that the noex variable noex declared and set here:
int noex = NOEX_PUBLIC; const NODE *cref = rb_vm_cref_in_context(mod, mod); if (cref) { noex = (int)cref->nd_visi; }
may be the value I want, but again I donβt know how to get it in Ruby, or even if it can reflect the scope of the call (in Test ). Assuming I had visibility, I could just call private name (or protected name ) after calling define_method inside has_a if it was not called in the public context.
Thoughts? Is there a way to do this, or am I out of luck?