特定
module Foo
def bar
puts "foobar"
end
end
Run Code Online (Sandbox Code Playgroud)
我可以
String.extend(Foo)
Run Code Online (Sandbox Code Playgroud)
结果呢
String.bar # => "foobar"
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?:
a = String.new
a.bar # => NoMethodError: undefined method `bar' for "":String
Run Code Online (Sandbox Code Playgroud)
是因为'a'现在和实例和.extend只对类方法有效吗?为什么它会失去我通过.extend给String的"新"功能?
Ruby允许您以两种方式将模块中的方法添加到类中:extend和include.
使用您提供的模块:
module Foo
def bar
puts "foobar"
end
end
Run Code Online (Sandbox Code Playgroud)
随着extend方法被添加为类方法,并且可以直接在类对象本身上调用:
class Bar
extend Foo
end
Bar.bar # => "foobar"
Run Code Online (Sandbox Code Playgroud)
或者,您可以在类范围之外调用它:
class Bar
end
Bar.extend Foo
Bar.bar # => "foobar"
Run Code Online (Sandbox Code Playgroud)
include略有不同.它将添加方法作为实例方法.它们只能在类的实例上调用:
class Bar
include Foo
end
Bar.bar # NoMethodError
a = Bar.new
a.bar # => "foobar"
Run Code Online (Sandbox Code Playgroud)
关键的区别在于我们首先必须创建一个实例a,然后才能调用实例方法.
正如sepp2k所说,extend可以在任何Object上调用,而不仅仅是Class对象.例如,你可以去:
class Bar
end
a = Bar.new
a.extend Foo
a.bar # => "foobar"
Run Code Online (Sandbox Code Playgroud)
但是,bar只会添加到单个实例中a.如果我们创建一个新实例,您将无法调用它.
b = Bar.new
b.bar # => MethodNotFoundError
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
603 次 |
| 最近记录: |