Ruby-require和self.require

Ruby-require和self.require,ruby,require,main,self,Ruby,Require,Main,Self,我喜欢ruby 1.8.7,为什么我可以在main中使用require,但不能使用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 众所周知,main是对象类: irb(主):045:0>self =>主要 ir

我喜欢ruby 1.8.7,为什么我可以在main中使用require,但不能使用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
众所周知,main是对象类: irb(主):045:0>self =>主要

irb(main):043:0> self.class
=> Object
但我发现它有内核混合:

irb(main):042:0> self.class.included_modules
=> [Kernel]
此外,我发现需要是一种私人的自我方法:

irb(main):037:0> self.private_methods
=> [... "require", ...]
同样,我不能使用self.attr\u访问器:

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

这是怎么发生的?有人能澄清这些问题吗?

检查以下简单示例:

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

基本上在ruby中,如果方法是
private
,则只能在
implicit
接收器上调用它(没有
self
关键字)。在您的示例中,
require
是由
内核
模块定义的
私有
方法,它只能在
隐式
主题上调用。

require
是私有方法。所以你不能这么说

Object.require 'date'
但您可以使用ruby的eval/send方法调用它:

Object.send(:require, 'date')
# or
self.send(:require', 'date')
实际上,什么与

require 'date'
例如,我们将其解释为

instance_exec do
  require 'date'
end

我相信Ruby解释器也会这样做。它将把任何顶级命令作为
实例执行
块传递给
对象
,该对象可以调用任何私有方法。

私有方法只能用隐式接收器调用。这意味着
require
将起作用,但
self.require
将不起作用

受保护的方法可以在
self
上调用,公共方法可以在任何对象上显式调用


这些是唯一的限制。是的,您可以在子类中使用私有方法,
send
将绕过任何和所有访问控制。

此外,我不能在类定义中使用self.attr\u访问器:
self.send(:require,'date')
私有setter可以被称为
self.attr=:foo
,事实上,它们必须以这种方式调用,因为
attar=:foo
是一个局部变量赋值。@JörgWMittag,你说得对。这是否适用于以
=
结尾的任何方法,或者仅适用于
attr\u writer
attr\u accessor
定义的setter?你能提供一个到实现此行为的源的链接吗?
attr\u writer
绝对没有什么特别之处。实际上,它实际上只是
类模块;def attr|u writer(*attrs)attrs.each do|attr|define|u方法(:“#{atttr}=”)do|val|instance|u变量集(:“@#{attr}”,val)end end end end
。因此,是的,这适用于以
=
结尾的任何方法,因为否则您将永远无法调用它。
instance_exec do
  require 'date'
end