Where are the methods defined at the top level?

I am learning metaprogramming and I am stuck trying to find a method. Let's say I have the following class:

class MyClass
  def self.my_method
  end
  def your_method
  end
end

In the following code, I can search for each method in an object space:

type = Class
name = /^my_method$/
result = ObjectSpace.each_object(type).select do |o|
  o.instance_methods(false).grep(name).size > 0 || o.methods.grep(name).size > 0
end
p result

And he finds that he shows the following output:

[MyClass]

Since the search code also looks for instance methods, it shows the same result when searching for your_method.

Even if I add a single method to the object:

mc = MyClass.new
def mc.our_method
end

Just change the search engine as follows:

type = Object
name = /^our_method$/
result = ObjectSpace.each_object(type).select do |o|
  o.methods.grep(name).size > 0
end
p result

He also finds this:

[#<MyClass:0x8f86760>]

The question is how to find the method defined in the top-level object? This method:

def hidden
end

Also, which is the current class when defining a method like this?

+4
source share
2 answers

?

, , self :

self        #=> main
self.class  #=> Object

, , Object, "main".


, ?

. Ruby , , :

def foo; :bar; end
method(:foo).owner     #=> Object
Object.new.foo         #=> NoMethodError: private method `foo' called
Object.new.send(:foo)  #=> :bar

, , , ( *) . , "" , , , methods, instance_methods , private_methods private_instance_methods:

Object.instance_methods.include?(:foo)          #=> false
Object.private_instance_methods.include?(:foo)  #=> true

* , Pry ( , v0.10.1) , , REPL public.

+5

:

def my_method() end

class A
  def self.my_method() end
end

class B < A
  def my_method() end
end

class C
  def my_method() end
end

'my_method', , :

ObjectSpace.each_object(Class).select do |o|
  o.instance_methods(false).include?(:my_method)
end
  #=> [C, B]

ObjectSpace.each_object(Class).select do |o|
  o.methods(false).include?(:my_method)
end
  #=> [A]

ObjectSpace.each_object(Class).select do |o|
  o.private_instance_methods(false).include?(:my_method)
end
  #=> [Object]
0

All Articles