在另一个方法中定义的方法范围
Scope of method defined inside another method
考虑以下代码:
class Emotion
def confused?
def confused?
'yes'
end
'no'
end
end
am_i = Emotion.new
am_i.confused? # => "no"
am_i.confused? # => "yes"
5.times.map { Emotion.new.confused? } # => ["yes", "yes", "yes", "yes", "yes"]
解释:
- 第一次运行
confused?
returns "no"
并且 重新定义 本身。
- 第二次运行
confused?
会调用returns"yes"
. 的新方法
虽然上面的功能很清楚,但我不确定如何将这两种方法定义到相同的 scope。
我问的原因是因为:
- 无法在方法内部和外部以类似方式访问变量;例如:如果我在方法内部和外部定义
@variable
它具有不同的含义。
- 我了解到方法定义发生了变化
self
。与外部定义相比,confused?
方法的内部定义不会有不同的范围吗?
def
实际上如何确定定义方法的位置?
A variable cannot be accessed in similar fashion inside and outside a method; for instance: if I define @variable inside and outside a method it has different meanings.
使用@x = y
语法设置实例变量时,实例变量设置为self
。
I have learned that method definition changes self. Won't the inside definition of the confused? method have a different scope in comparison with the outside definition?
范围可以改变,但在这种情况下不会。方法中 self
的值始终是调用该方法的对象。在您的两个 confused?
方法定义中,self
是 Emotion
.
的一个实例
How does def actually determine where to define the method?
这个问题的答案(至少在 MRI 中)实际上有些不直观。每个作用域都有对 "default definee" 对象的引用,该对象不一定与 self
相关,并且始终是 Module
的实例。 def
在该范围内将为默认定义者定义一个方法。在 ruby 代码中获取默认定义的最简单的方法是:
eval("def __m; end; m = method(:__m); undef __m; m.owner")
例如,运行 在 ruby 程序的顶层 returns Object
。因此,顶级范围的默认定义是 Object
.
下面是一些代码,希望能回答您关于作用域的问题:
# `self` is the toplevel object
# default definee is `Object`
class X
# `self` is X
# default definee is also X
@a = 1 # defines instance variable @a for `X`
def y # defines method 'y' on X
# `self` is an instance of X
# default definee is X
@b = 2 # defines instance variable @b for an instance of `X`
def z # defines method 'z' on X
# `self` is still an instance of X
# default definee is still X
@c = 3 # defines instance variable @c for an instance of `X`
end
end
class << self
# `self` is the metaclass of X
# default definee is also the metaclass of X
@d = 4 # defines instance variable @d for the metaclass of X
end
end
重要的是要记住 方法 总是存储在 Module
的实例中,其中 实例变量 可以是存储在任何对象中(不包括 nil
或布尔值或整数等原语)。
考虑以下代码:
class Emotion
def confused?
def confused?
'yes'
end
'no'
end
end
am_i = Emotion.new
am_i.confused? # => "no"
am_i.confused? # => "yes"
5.times.map { Emotion.new.confused? } # => ["yes", "yes", "yes", "yes", "yes"]
解释:
- 第一次运行
confused?
returns"no"
并且 重新定义 本身。 - 第二次运行
confused?
会调用returns"yes"
. 的新方法
虽然上面的功能很清楚,但我不确定如何将这两种方法定义到相同的 scope。
我问的原因是因为:
- 无法在方法内部和外部以类似方式访问变量;例如:如果我在方法内部和外部定义
@variable
它具有不同的含义。 - 我了解到方法定义发生了变化
self
。与外部定义相比,confused?
方法的内部定义不会有不同的范围吗? def
实际上如何确定定义方法的位置?
A variable cannot be accessed in similar fashion inside and outside a method; for instance: if I define @variable inside and outside a method it has different meanings.
使用@x = y
语法设置实例变量时,实例变量设置为self
。
I have learned that method definition changes self. Won't the inside definition of the confused? method have a different scope in comparison with the outside definition?
范围可以改变,但在这种情况下不会。方法中 self
的值始终是调用该方法的对象。在您的两个 confused?
方法定义中,self
是 Emotion
.
How does def actually determine where to define the method?
这个问题的答案(至少在 MRI 中)实际上有些不直观。每个作用域都有对 "default definee" 对象的引用,该对象不一定与 self
相关,并且始终是 Module
的实例。 def
在该范围内将为默认定义者定义一个方法。在 ruby 代码中获取默认定义的最简单的方法是:
eval("def __m; end; m = method(:__m); undef __m; m.owner")
例如,运行 在 ruby 程序的顶层 returns Object
。因此,顶级范围的默认定义是 Object
.
下面是一些代码,希望能回答您关于作用域的问题:
# `self` is the toplevel object
# default definee is `Object`
class X
# `self` is X
# default definee is also X
@a = 1 # defines instance variable @a for `X`
def y # defines method 'y' on X
# `self` is an instance of X
# default definee is X
@b = 2 # defines instance variable @b for an instance of `X`
def z # defines method 'z' on X
# `self` is still an instance of X
# default definee is still X
@c = 3 # defines instance variable @c for an instance of `X`
end
end
class << self
# `self` is the metaclass of X
# default definee is also the metaclass of X
@d = 4 # defines instance variable @d for the metaclass of X
end
end
重要的是要记住 方法 总是存储在 Module
的实例中,其中 实例变量 可以是存储在任何对象中(不包括 nil
或布尔值或整数等原语)。