Search code examples
rubyrequireprogram-entry-pointself

Ruby require and self.require


I ruby 1.8.7, Why I can use require in main, but can't use self.require?

require('date') # ok
self.require('date') 
NoMethodError: private method `require' called for main:Object
from (irb):22
from /usr/lib/ruby/1.8/date.rb:437

Well known that main is Object class: irb(main):045:0> self => main

irb(main):043:0> self.class
=> Object

But I discovered that it have Kernel mixin:

irb(main):042:0> self.class.included_modules
=> [Kernel]

Moreover, I found that require is private method of self:

irb(main):037:0> self.private_methods
=> [... "require", ...]

Same way, I can't use self.attr_accessor:

irb(main):051:0> class X
irb(main):052:1> self.attr_accessor(:ssss)
irb(main):053:1> end
NoMethodError: private method `attr_accessor' called for X:Class
from (irb):52
from /usr/lib/ruby/1.8/date.rb:437

How does it happend? Can anybody clarify that questions?


Solution

  • Check the following simple example:

    class Person
      def initialize(age)
        @age = age
      end
    
      def compare_to(other)
        # we're calling a protected method on the other instance of the current class
        age <=> other.age
      end
    
      # it will not work if we use 'private' here
      protected
    
      def age
        @age
      end
    end
    

    In ruby we have implicit and explicit methods receiver, check the next code snippet:

    class Foo
      def a; end
    
      # call 'a' with explicit 'self' as receiver
      def b; self.a; end
    
      # call 'a' with implicit 'self' as receiver
      def c; a; end
    end
    

    Basically in ruby if a method is private it can be called only on implicit receiver (without self keyword). In your example require is a private method defined the Kernel module and it can be called only on the implicit subject.