Method access in Ruby

試著忘記壹切 提交于 2019-12-12 10:34:13

问题


How is it that Ruby allows a class access methods outside of the class implicitly?

Example:

class Candy
    def land
        homer
    end
end

def homer
    puts "Hello"
end

Candy.new.land #Outputs Hello

回答1:


The definition of the "homer" method is adding the method to the Object class. It is not defining a free function.

Class Candy implicitly inherits from Object, and so has access to the methods in Object. When you call "homer" in the "land" method, the method resolution can't find a definition in the current class, goes to the super class, finds the method you have added to Object, and calls it.




回答2:


A simple way to find out what happens

  1. What classes/modules are searched to resolve methods used in Candy objects?

    p Candy.ancestors #=> [Candy, Object, Kernel]

  2. Does Candy have method called homer?

    p Candy.instance_methods(false).grep("homer") #=> []

    p Candy.private_instance_methods(false).grep("homer") #=> []

  3. OK Candy does not have any method called 'homer'.

  4. What's next in the lookup chain (see 1) => "Object"

  5. Does Object have a method called "homer" ? p Object.instance_methods(false).grep("homer") #=> []

    p Object.private_instance_methods(false).grep("homer") #=> ["homer"]

Candy has Object in its lookup chain which in turn has a private instance method "homer" so method resolution succeeds

The def statement always defines the method in the class of whatever self is at the point of definition

  1. What is self just before homer is defined ?

    p self #=> main def homer puts "Hello" end

  2. So what is its type ?

    p self.class #=> Object

Which is why homer ends up on Object




回答3:


Technically, the definition of the homer method is actually on the Kernel module which is mixed into Object, not on Object directly. So when homer is not a local variable or an instance method defined on Candy, the Ruby method inheritance chain is followed up through Object and then to the mixed-in Kernel module and then this code is run.

Edit: Sorry, I don't know why I thought this. It appears that the method really lives on Object. Not sure it makes too much of a difference in practice but I should have confirmed things before posting.




回答4:


Ruby has no free-floating functions. Every method belongs to some object. Methods that you def at the top level are actually becoming instance methods of class Object. Because everything is an Object at some level, all objects have access to Object's instance methods.



来源:https://stackoverflow.com/questions/156394/method-access-in-ruby

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!