Ruby self.extended 作为实例方法被调用
Ruby self.extended gets called as instance method
module Country
def location
puts "location"
end
def self.included(base)
def cities
puts "cities"
end
end
def self.extended(base)
def animals
puts "animals"
end
end
end
class Test
include Country
end
class Test2
extend Country
end
据我了解,self.included 将在模块作为实例方法包含时调用,而 self.extended 将在模块扩展为静态时调用 class方法。
但是当我在同一个文件中有两个 class 时,为什么它没有抛出错误
Test.new.animals
=>动物
如果我删除了测试 2 class,
# class Test2
# extend Country
# end
Test.new.animals
=>没有方法错误
def bar
没有明确的 definee(即 def foo.bar
)在最近的词法封闭模块中定义 bar
。所有三个 def
的最接近词法封闭模块始终是 Country
,因此所有三个方法都在 Country
模块中定义。
如果你想定义一个单例方法,你可以使用
module Country
def self.extended(base)
def base.animals
puts "animals"
end
end
end
有关详细信息,请参阅 。
也许我会向那些不熟悉 Ruby 的“Object Model”的人明确说明我认为没有完全和明确地解决 Jorg 漂亮的回答(怀着最大的敬意):
module Country
def location
puts "location"
end
def self.included(base)
def cities
puts "cities"
end
end
def self.extended(base)
puts "#{self}" ## NOTICE THIS NEW LINE! NEW LINE
def animals
puts "animals"
end
end
end
class Test
include Country
end
class Test2
extend Country
end
Test.new.animals
有什么问题?
我们正在扩展 Test2,不是吗?那么 animals 方法是如何定义的
在测试 1 中?
关键是在 animals 方法上面添加 puts "#{self}
行。
我们可以看到这里的animals方法是在Country中定义的
模块。所以真的,当你认为你正在扩展时,它,你在
事实上确保它被添加为实例方法,而不是
"static class method"(如果您来自 c#/java 背景)。严格来说,这并不准确:当你像这样 "extending" - 如果你做对了 - 你实际上是在添加方法
到 Test2 的单例 class。 Ruby 的对象模型在这方面有点棘手。静态 class 方法是添加到 class 的单例 class 的方法。什么是单例class?现在您正在进入 ruby 的对象模型。它很复杂,有点耗费人才,但一旦你掌握了它,你就可以做一些非常强大(而且危险?)的事情,比如:猴子修补。
解决方案:
Jorg 说得比我好。你需要这样定义动物:def base.animals
.
module Country
def location
puts "location"
end
def self.included(base)
def cities
puts "cities"
end
end
def self.extended(base)
def animals
puts "animals"
end
end
end
class Test
include Country
end
class Test2
extend Country
end
据我了解,self.included 将在模块作为实例方法包含时调用,而 self.extended 将在模块扩展为静态时调用 class方法。
但是当我在同一个文件中有两个 class 时,为什么它没有抛出错误
Test.new.animals
=>动物
如果我删除了测试 2 class,
# class Test2
# extend Country
# end
Test.new.animals
=>没有方法错误
def bar
没有明确的 definee(即 def foo.bar
)在最近的词法封闭模块中定义 bar
。所有三个 def
的最接近词法封闭模块始终是 Country
,因此所有三个方法都在 Country
模块中定义。
如果你想定义一个单例方法,你可以使用
module Country
def self.extended(base)
def base.animals
puts "animals"
end
end
end
有关详细信息,请参阅
也许我会向那些不熟悉 Ruby 的“Object Model”的人明确说明我认为没有完全和明确地解决 Jorg 漂亮的回答(怀着最大的敬意):
module Country
def location
puts "location"
end
def self.included(base)
def cities
puts "cities"
end
end
def self.extended(base)
puts "#{self}" ## NOTICE THIS NEW LINE! NEW LINE
def animals
puts "animals"
end
end
end
class Test
include Country
end
class Test2
extend Country
end
Test.new.animals
有什么问题?
我们正在扩展 Test2,不是吗?那么 animals 方法是如何定义的 在测试 1 中?
关键是在 animals 方法上面添加 puts "#{self}
行。
我们可以看到这里的animals方法是在Country中定义的 模块。所以真的,当你认为你正在扩展时,它,你在 事实上确保它被添加为实例方法,而不是 "static class method"(如果您来自 c#/java 背景)。严格来说,这并不准确:当你像这样 "extending" - 如果你做对了 - 你实际上是在添加方法 到 Test2 的单例 class。 Ruby 的对象模型在这方面有点棘手。静态 class 方法是添加到 class 的单例 class 的方法。什么是单例class?现在您正在进入 ruby 的对象模型。它很复杂,有点耗费人才,但一旦你掌握了它,你就可以做一些非常强大(而且危险?)的事情,比如:猴子修补。
解决方案:
Jorg 说得比我好。你需要这样定义动物:def base.animals
.