self 在初始化和其他 class 方法中使用时如何工作?
How self works when using it in the initialize and other class methods?
我正在学习 ruby,在这个例子中 self
的概念让我很困惑。
class Alpha
def initialize
self.A
end
def self.A
puts "A"
end
def self.B
self.A
puts "B"
end
end
当我尝试从 class Alpha
创建一个新实例时
Alpha.new
我得到了NoMethodError
,但是当我调用B
方法时,它正常执行。
Alpha.B
# A
# B
#=>nil
initialize
在实例上下文中运行,而不是在 class 上下文中运行。如果要调用class方法,则需要self.class.A
。或者你可以尝试更疯狂地覆盖 class new
方法:
class Alpha
def self.new
self.A
super # this actually calls initialize after object is created
end
[...]
end
首先定义class Alpha
如下。
class Alpha
puts "self in Alpha = #{self}"
def a
puts "self in a = #{self}"
end
def Alpha.b
puts "self in b = #{self}"
end
def Alpha.c
puts "self in c = #{self}"
end
end
# self in Alpha = Alpha
我们有一个实例方法 Alpha#a
和两个 class 方法,Alpha::b
和 Alpha::b
。 (以这种方式引用实例和 class 方法是一种 Ruby 约定,您将一直在文档中看到这一约定。)
Alpha.methods(false)
#=> [:c, :b]
Alpha.instance_methods(false)
#=> [:a]
参见 Object::methods and Module#instance_methods,注意包含参数 false
的含义。
在 class 的实例上调用实例方法; class 方法在 class.
上被调用
alpha = Alpha.new
#=> #<Alpha:0x000059c5ff614f08>
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
Alpha.b
# self in b = Alpha
Alpha.c
# self in c = Alpha
如果我们尝试调用 class 上的实例方法或实例上的 class 方法怎么办?
Alpha.a
#=> NoMethodError (undefined method `a' for Alpha:Class)
alpha.b
#=> NoMethodError (undefined method `b' for #<Alpha:0x000059c5ff614f08>)
我们通常会这样写class。
class Alpha
def a
puts "self in a = #{self}"
end
def self.b
puts "self in b = #{self}"
end
def self.c
puts "self in c = #{self}"
end
end
在class定义中self
是Alpha
,这就是为什么class的两种写法是等价的。使用 self
的唯一原因是,如果我们稍后决定将 class 的名称更改为 Beta
,我们将不必将所有 Alpha
的名称更改为Beta
在 class 方法定义中。
如果我们想从实例方法 Alpha#a
中调用 class 方法 Alpha::b
我们必须按如下方式更改后者:
class Alpha
def a
puts "self in a = #{self}"
self.class.b
end
end
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
# self in b = Alpha
这里self.class
returnsAlpha
,我们知道Alpha.b
returns.
让我们再次更改Alpha#a
并添加第二个实例方法:
class Alpha
def a
puts "self in a = #{self}"
d
end
def d
puts "self in d = #{self}"
end
end
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
# self in d = #<Alpha:0x000059c5ff614f08>
我本可以写成:
def a
puts "self in a = #{self}"
self.d
end
但 self.
不是必需的,通常不包括在内。原因是当一个方法没有明确的接收者时,如d
in:
def a
puts "self in a = #{self}"
d
end
self
成为 默认接收者 。我们从上面的讨论中知道,在实例方法定义中 self
等于实例 alpha
.
我正在学习 ruby,在这个例子中 self
的概念让我很困惑。
class Alpha
def initialize
self.A
end
def self.A
puts "A"
end
def self.B
self.A
puts "B"
end
end
当我尝试从 class Alpha
Alpha.new
我得到了NoMethodError
,但是当我调用B
方法时,它正常执行。
Alpha.B
# A
# B
#=>nil
initialize
在实例上下文中运行,而不是在 class 上下文中运行。如果要调用class方法,则需要self.class.A
。或者你可以尝试更疯狂地覆盖 class new
方法:
class Alpha
def self.new
self.A
super # this actually calls initialize after object is created
end
[...]
end
首先定义class Alpha
如下。
class Alpha
puts "self in Alpha = #{self}"
def a
puts "self in a = #{self}"
end
def Alpha.b
puts "self in b = #{self}"
end
def Alpha.c
puts "self in c = #{self}"
end
end
# self in Alpha = Alpha
我们有一个实例方法 Alpha#a
和两个 class 方法,Alpha::b
和 Alpha::b
。 (以这种方式引用实例和 class 方法是一种 Ruby 约定,您将一直在文档中看到这一约定。)
Alpha.methods(false)
#=> [:c, :b]
Alpha.instance_methods(false)
#=> [:a]
参见 Object::methods and Module#instance_methods,注意包含参数 false
的含义。
在 class 的实例上调用实例方法; class 方法在 class.
上被调用alpha = Alpha.new
#=> #<Alpha:0x000059c5ff614f08>
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
Alpha.b
# self in b = Alpha
Alpha.c
# self in c = Alpha
如果我们尝试调用 class 上的实例方法或实例上的 class 方法怎么办?
Alpha.a
#=> NoMethodError (undefined method `a' for Alpha:Class)
alpha.b
#=> NoMethodError (undefined method `b' for #<Alpha:0x000059c5ff614f08>)
我们通常会这样写class。
class Alpha
def a
puts "self in a = #{self}"
end
def self.b
puts "self in b = #{self}"
end
def self.c
puts "self in c = #{self}"
end
end
在class定义中self
是Alpha
,这就是为什么class的两种写法是等价的。使用 self
的唯一原因是,如果我们稍后决定将 class 的名称更改为 Beta
,我们将不必将所有 Alpha
的名称更改为Beta
在 class 方法定义中。
如果我们想从实例方法 Alpha#a
中调用 class 方法 Alpha::b
我们必须按如下方式更改后者:
class Alpha
def a
puts "self in a = #{self}"
self.class.b
end
end
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
# self in b = Alpha
这里self.class
returnsAlpha
,我们知道Alpha.b
returns.
让我们再次更改Alpha#a
并添加第二个实例方法:
class Alpha
def a
puts "self in a = #{self}"
d
end
def d
puts "self in d = #{self}"
end
end
alpha.a
# self in a = #<Alpha:0x000059c5ff614f08>
# self in d = #<Alpha:0x000059c5ff614f08>
我本可以写成:
def a
puts "self in a = #{self}"
self.d
end
但 self.
不是必需的,通常不包括在内。原因是当一个方法没有明确的接收者时,如d
in:
def a
puts "self in a = #{self}"
d
end
self
成为 默认接收者 。我们从上面的讨论中知道,在实例方法定义中 self
等于实例 alpha
.