class A
def m
def m2; end
end
end
A.new.m
p A.instance_methods(false) # [:m2, :m]
同样的情况也发生在这里,但是这里的封闭类是A的单例类:
class A
class << self
def m
def m2; end
end
end
end
A.m
p A.singleton_class.instance_methods(false) # [:m2, :m]
如果我们使用def self.<name>表示法呢?
class A
def self.m
def m2; end
end
end
A.m
p A.singleton_class.instance_methods(false) # [:m]
p A.instance_methods(false) # [:m2]
因此,self.只影响m,m2成为A的示例方法。 实际上,除了self之外,还可以有一些随机对象:
o = Object.new
A = Class.new do
def o.m
def m2; end
end
end
o.m
p o.singleton_class.instance_methods(false) # [:m]
p A.instance_methods(false) # [:m2]
我必须使用Class.new,因为使用class,o在类定义中不可见。 其实我没有
class A
o = Object.new
def o.m
def m2; end
end
o.m
p o.singleton_class.instance_methods(false) # [:m]
p A.instance_methods(false) # [:m2]
end
但我们先忽略这一分支。 做了一些改动,你会得到这个:
main = Object.new
Object.class_eval do
def main.go
@a = 1
def m2
puts @a
end
m2 # 1
end
end
main.go
p Object.instance_methods(false) # [:m2]
p main.instance_variables # [:@a]
我不得不使用class_eval,这样它就不会抱怨我试图重新定义Object常量。 您还可以添加:
def main.to_s
"main"
end
main.instance_eval { alias inspect to_s }
为了完整性。 另一种方法是使用全局变量:
$main = Object.new
class Object
def $main.go
@a = 1
def m2
puts @a
end
m2 # 1
end
end
$main.go
p Object.instance_methods(false) # [:m2]
p $main.instance_variables # [:@a]
6条答案
按热度按时间fsi0uk1n1#
顶级调用方是Object类的对象main。
试试这个ruby程序:
uxh89sit2#
这是X类,你正在调用new方法来创建X类的对象,所以,如果你把这段文字作为脚本运行,Ruby:
new
就是其中之一。x
X
上的new
方法,创建X示例对象;x得到对该对象的引用。brqmpdu13#
是ruby解释器在运行这行代码
与许多脚本语言一样,脚本是从上到下解释的,而不是像大多数编译语言那样具有标准的入口点方法。
afdcj2ne4#
正如Charlie Martin所说,X.new是对X类上构造函数的调用,它返回一个类型X的对象,存储在变量x中。
基于你的标题,我认为你需要更多的东西。Ruby不需要main,它按照它看到的顺序执行代码。所以依赖关系必须在调用之前包含在内。
因此,main是在类或模块定义之外编写的任何过程样式代码。
1zmg4dgp5#
main
是在其上下文中执行顶层代码的对象。这意味着顶层的self
引用main
对象:并且
ruby
遵循main
的方法查找链来确定调用哪个方法:可能会有更多,但这是你从一开始就得到的。
main
本身是Object
的示例:它有一个单例类,该类有2个方法(更准确地说是一个方法和一个别名):
它在这里定义。
正如您所看到的,它的
to_s
方法返回"main"
(覆盖Object
的行为),这是您执行p self
时得到的结果。你可以认为你执行的代码被放进了
main
的方法中,然后这个方法被调用。这是一个粗略的想法,让我分几步来说明它的合理性。
在Ruby中,实际上可以嵌套方法,但是每次调用外部方法时,内部方法都会被定义/重定义,更重要的是,它被定义为嵌套类的一个示例方法:
同样的情况也发生在这里,但是这里的封闭类是
A
的单例类:如果我们使用
def self.<name>
表示法呢?因此,
self.
只影响m
,m2
成为A
的示例方法。实际上,除了
self
之外,还可以有一些随机对象:我必须使用
Class.new
,因为使用class
,o
在类定义中不可见。其实我没有
但我们先忽略这一分支。
做了一些改动,你会得到这个:
我不得不使用
class_eval
,这样它就不会抱怨我试图重新定义Object
常量。您还可以添加:
为了完整性。
另一种方法是使用全局变量:
当然,变量
main
/$main
和go
方法并不存在,但是当我想到这个想法时,我的脑海中就没有更多的缺陷了,这个想法就像你的代码被放入main
的方法中,并通过运行该方法来执行。这也解释了为什么在顶层定义的方法到处可见:
a.rb
:一个一个三个一个一个
因为它们变成了
Object
的示例方法。您还可以使用示例变量,它们是
main
对象的示例变量。ssm49v7z6#
Ruby中的所有内容都发生在某个对象的上下文中,顶层的对象称为“main”,它基本上是Object的一个示例,具有一个特殊属性,即在那里定义的任何方法都被添加为Object的示例方法(因此它们在任何地方都可用)。
因此,我们可以创建一个完全由以下内容组成的脚本:
它将打印“105640”和“看,我有示例变量!"。
这不是你通常需要关心的事情,但它就在那里。