首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要ruby .extend帮助

需要ruby .extend帮助
EN

Stack Overflow用户
提问于 2011-12-15 05:44:29
回答 3查看 631关注 0票数 2

给定的

代码语言:javascript
复制
module Foo
  def bar
    puts "foobar"
  end
end

我能做到

代码语言:javascript
复制
String.extend(Foo)

其结果就是

代码语言:javascript
复制
String.bar # => "foobar"

为什么这个不起作用?:

代码语言:javascript
复制
a = String.new
a.bar # => NoMethodError: undefined method `bar' for "":String

是不是因为'a‘现在是实例,而.extend只对类方法起作用?为什么它会失去我通过.extend赋予字符串的‘新’功能?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-15 06:04:38

Ruby允许以两种方式将模块中的方法添加到类中:extendinclude

使用您提供的模块:

代码语言:javascript
复制
module Foo
  def bar
    puts "foobar"
  end
end

使用extend,这些方法被添加为类方法,并且可以直接在类对象本身上调用:

代码语言:javascript
复制
class Bar
  extend Foo
end

Bar.bar # => "foobar"

或者,您可以在类范围之外调用它:

代码语言:javascript
复制
class Bar
end

Bar.extend Foo

Bar.bar # => "foobar"

include稍有不同。它将添加这些方法作为实例方法。它们只能在类的实例上调用:

代码语言:javascript
复制
class Bar
  include Foo
end

Bar.bar # NoMethodError
a = Bar.new
a.bar # => "foobar"

关键区别在于,我们首先必须创建一个实例a,然后才能调用该实例方法。

正如sepp2k所指出的,extend可以在任何对象上调用,而不仅仅是类对象。例如,您可以这样做:

代码语言:javascript
复制
class Bar
end

a = Bar.new
a.extend Foo
a.bar # => "foobar"

但是,只会将bar添加到单实例a。如果我们创建了一个新实例,您将无法调用它。

代码语言:javascript
复制
b = Bar.new
b.bar # => MethodNotFoundError
票数 6
EN

Stack Overflow用户

发布于 2011-12-15 06:02:52

在Ruby语言中,String类是一个对象,通过执行String.extend( Foo ),您可以为String类对象创建一个单例类,并在其中包含模块Foo(这意味着您正在向String类对象添加类方法,因此可以调用String.bar)。句号。

a.bar无法工作,因为没有实例方法栏。

不,您还没有通过扩展将new赋给String。

票数 0
EN

Stack Overflow用户

发布于 2011-12-15 06:03:03

Object#extend方法将参数模块定义的方法添加到接收器。

您必须记住,扩展类本身就是一个对象(类型为Class),因此当您使用它作为接收器调用“String”时,该类对象(String)本身就会获得新方法。

因此,在您的第一个示例String.extend(Foo)中,将函数"bar“添加到String类实例。也就是说,“String”现在是阴影类(又称单例类)的一个实例方法,因此对象String(它是一个类)现在具有方法"bar“。这与向String类添加类方法(例如def String.bar; puts 'foobar'; end)具有大致相同的效果,因此它对String类型的实例没有影响。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8512089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档