首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby require和self.require

Ruby require和self.require
EN

Stack Overflow用户
提问于 2012-04-25 19:06:18
回答 3查看 627关注 0票数 4

我ruby 1.8.7,为什么我可以在main中使用require,但不能使用self.require?

代码语言:javascript
复制
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( main ):045:0>自身=> main

代码语言:javascript
复制
irb(main):043:0> self.class
=> Object

但我发现它有内核混合:

代码语言:javascript
复制
irb(main):042:0> self.class.included_modules
=> [Kernel]

此外,我发现require是self的私有方法:

代码语言:javascript
复制
irb(main):037:0> self.private_methods
=> [... "require", ...]

同样,我不能使用self.attr_accessor:

代码语言:javascript
复制
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

它是如何发生的?有人能澄清这个问题吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-25 20:39:26

看看下面这个简单的例子:

代码语言:javascript
复制
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中,我们有隐式和显式的方法接收器,请检查下面的代码片段:

代码语言:javascript
复制
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

基本上,在ruby中,如果一个方法是private,那么它只能在implicit接收器上调用(没有self关键字)。在您的示例中,require是一个定义在Kernel模块中的private方法,它只能在implicit主题上调用。

票数 2
EN

Stack Overflow用户

发布于 2012-04-25 20:52:00

require是一个私有方法。所以你不能把它叫做

代码语言:javascript
复制
Object.require 'date'

但是你可以用ruby的eval/send方法来调用它:

代码语言:javascript
复制
Object.send(:require, 'date')
# or
self.send(:require', 'date')

实际上非常类似于

代码语言:javascript
复制
require 'date'

例如,pry console会将其解释为

代码语言:javascript
复制
instance_exec do
  require 'date'
end

我相信Ruby解释器也会做同样的事情。它会将任何顶级命令作为instance_exec块传递给Object,后者可以调用任何私有方法。

票数 2
EN

Stack Overflow用户

发布于 2012-04-25 21:28:38

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

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10314367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档