红宝石顶层定义的方法在哪里? [英] Where are methods defined at the ruby top level?

查看:106
本文介绍了红宝石顶层定义的方法在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在顶层,方法定义应导致在Object上使用私有方法,而测试似乎证明了这一点:

At the top level, method definition should result in private methods on Object, and tests seem to bear this out:

def hello; "hello world"; end

Object.private_instance_methods.include?(:hello) #=> true
Object.new.send(:hello) #=> "hello world"

但是,以下内容也可以在顶级使用(self.metamain的本征类):

However, the following also works at top level (self.meta is the eigenclass of main):

self.meta.private_instance_methods(false).include?(:hello) #=> true

看来,hello方法是在main的本征类以及Object上同时定义的.这是怎么回事?请注意,private_instance_methodsfalse参数从方法列表中排除超类方法.

It appears that the hello method is simultaneously defined on the eigenclass of main as well as on Object. What's going on? Note that the false parameter to private_instance_methods excludes super class methods from the method list.

推荐答案

首先,这种行为和潜在的推理一直存在. 1.9并不新鲜.发生这种情况的技术原因是因为main是特殊的,并且与其他任何对象都不同的对待.没有花哨的解释:它的行为是因为它是按照这种方式设计的.

First of all, this behavior and the underlying reasoning have always existed; it's nothing new to 1.9. The technical reason it happens is because main is special and treated differently than any other object. There's no fancy explanation available: it behaves that way because it was designed that way.

好的,但是为什么呢? main神奇的原因是什么?因为Ruby的设计师Yukihiro Matsumoto认为使语言变得更好具有这种行为:

Okay, but why? What's the reasoning for main to be magical? Because Ruby's designer Yukihiro Matsumoto thinks it makes the language better to have this behavior:

是的,为什么在此对象上没有使顶级方法成为单例方法, 而不是作为Object类的实例方法插入 本身 (因此归入所有其他类别,即,名称空间污染多于 通常是预期的).这仍然允许顶级方法调用其他方法 顶级方法.并且如果顶级对象是由 一些 像Main这样的常量,然后可以从任何地方调用这些方法 和 Main.method(...).

Is so, why are top-level methods not made singleton-methods on this object, instead of being pulled in as instance methods on the Object class itself (and hence into all other classes i.e. more namespace pollution than is usually intended). This would still allow top-level methods to call other top-level methods. And if the top-level object were referred to by some constant like Main, then those methods could be called from anywhere with Main.method(...).

您真的要输入吗 到处都是"Main.print"?

Do you really wish to type "Main.print" everywhere?

在讨论中,他进一步解释了这种行为,因为他觉得假设是自然的".

Further on in the discussion, he explains that it behaves this way because he feels the "assumption is natural."

针对您的评论,您的问题针对的是为什么main的本征类似乎将hello报告为私有实例方法.问题在于,实际上没有任何顶级函数被添加到main中,而是直接添加到Object中.使用本征类时,instance_methods函数族的行为始终像本征类仍是原始类一样.即,该类中定义的方法被视为直接在本征类中定义.例如:

In response to your comment, your question is aimed at why main's eigenclass seems to report hello as a private instance method. The catch is that none of the top-level functions are actually added to main, but directly to Object. When working with eigenclasses, the instance_methods family of functions always behave as if the eigenclass is still the original class. That is, methods defined in the class are treated as being defined directly in the eigenclass. For example:

class Object
  private
  def foo
    "foo"
  end
end

self.send :foo  # => "foo"
Object.private_instance_methods(false).include? :foo  # => true
self.meta.private_instance_methods(false).include? :foo  # => true

class Bar
  private
  def bar
    "bar"
  end
end

bar = Bar.new
bar.send :bar  # => "bar"
Bar.private_instance_methods(false).include? :bar  # => true
bar.meta.private_instance_methods(false).include? :bar  # => true

不过,我们可以直接将方法添加到main的本征类.将您的原始示例与此进行比较:

We can add a method directly to main's eigenclass, though. Compare your original example with this:

def self.hello; "hello world"; end

Object.instance_methods.include? :hello  # => false
self.meta.instance_methods.include? :hello  # => true

好的,但是如果我们真的想知道某个给定的函数是在本征类上定义的,而不是在原始类上定义的,该怎么办?

Okay, but what if we really want to know that a given function is defined on the eigenclass, not the original class?

def foo; "foo"; end  #Remember, this defines it in Object, not on main
def self.bar; "bar"; end  #This is defined on main, not Object

foo  # => "foo"
bar  # => "bar"

self.singleton_methods.include? :foo  # => false
self.singleton_methods.include? :bar  # => true

这篇关于红宝石顶层定义的方法在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆