加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby将方法添加到类中

发布时间:2020-12-16 19:34:27 所属栏目:百科 来源:网络整理
导读:假设我有一个班级: class Fooend 要向此类添加方法,我知道2个选项: 重新打开该类并实现该方法: class Foo def bar endend 使用class_eval实现方法: Foo.class_eval { def bar; end} 有什么不同?哪一个更好? 解决方法 实际上,还有一些其他方法可以将新
假设我有一个班级:
class Foo
end

要向此类添加方法,我知道2个选项:

>重新打开该类并实现该方法:

class Foo
  def bar
  end
end

>使用class_eval实现方法:

Foo.class_eval { def bar; end}

有什么不同?哪一个更好?

解决方法

实际上,还有一些其他方法可以将新方法添加到类中.例如,您还可以在模块中定义方法,并将模块混合到原始类中.
module ExtraMethods
  def bar
  end
end

Foo.class_eval { include ExtraMethods }
class Foo
  include ExtraMethods
end

没有真正好或坏.您提到的两种(或三种)方式具有不同的行为,您可能希望根据您的需要(或偏好)使用其中一种或另一种.在大多数情况下,这是主观的.在其他情况下,它实际上取决于您的代码的结构.

重新打开类与使用class_eval之间的主要客观差异是第一个也是类定义,而第二个需要已经定义原始类.

在实践中,在某些情况下重新打开课程可能会导致一些意想不到的副作用.假设您使用一堆方法在文件lib / foo.rb中定义了Foo.然后在config / initializers / extra.rb中重新打开Foo并添加bar方法.

在myclass.rb中,您使用Foo,但不是手动要求lib / foo.rb,而是依赖于自动加载功能.

如果在lib / foo.rb之前加载extra.rb,可能会发生的情况是你的环境中已经定义了Foo类,并且你的代码不会加载lib / foo.rb.你将拥有的是一个Foo类,它只包含你定义的条形扩展,而不是原始的Foo类.

换句话说,如果由于某种原因你重新打开类添加一些方法而不确保首先(或之后)加载完整的原始类定义,如果它依赖于自动加载,你的代码可能会中断.

相反,Foo.class_eval在Foo上调用一个方法,因此它希望在您尝试添加新方法时已经存在原始Foo定义.这可以确保在添加新方法时,已经定义了Foo类.

总之,主要区别在于重新打开类允许您(无论好坏)将方法添加到可能尚未加载的类,而class_eval需要已经定义类.

一般来说,除非我定义命名空间的子类或重新打开我完全控制的类,否则我更喜欢第二种方法,因为在大型代码库中它使代码更易于维护.事实上,如果我扩展第三方类,我通常会使用mixins,这样如果我需要覆盖现有方法,我可以保留完整方法祖先链.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读