Ruby-require和self.require
我喜欢ruby 1.8.7,为什么我可以在main中使用require,但不能使用self.requireRuby-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
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