奇怪的Ruby类初始化逻辑?

前端之家收集整理的这篇文章主要介绍了奇怪的Ruby类初始化逻辑?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在我的应用程序中集成的一些开源代码包含一些包含该效果代码的类:
class SomeClass < SomeParentClass

  def self.new(options = {})
    super().tap { |o|
      # do something with `o` according to `options`
    }
  end

  def initialize(options = {})
    # initialize some data according to `options`
  end

end

据我所知,self.new和initialize都做同样的事情 – 后者“在施工期间”和前者“施工后”,它看起来像一个可怕的模式使用 – 为什么分裂对象初始化为两部分,其中一部分显然是“错误思考(tm)”?

解决方法

理想情况下,我想看看super()里面有什么.点击{| o |阻止,因为虽然这看起来像是不好的做法,但也许在调用initialize之前或之后需要进行一些交互.

如果没有上下文,你可能只是在看一些有效的东西,但在Ruby中并不算是好习惯.

但是,单独的self.new和initialize方法方法可能允许框架设计器实现框架的子类可用部分,并且仍然确保框架所需的设置完成,而不需要特别使用super()的稍微笨拙的文档.如果最终用户仅通过子类MyClass<获得他们期望的功能,那么文档和更干净的API会稍微容易一些. FrameworkClass并没有一些额外的注意事项:

When you implement the subclass initialize,remember to put super at the start,otherwise the magic won’t work

. . .我个人认为这个设计有问题,但我认为至少会有明确的动机.

可能有更深层次的Ruby语言使代码自定义self.new块中运行 – 例如,它可能允许构造函数在返回之前切换或更改特定对象(甚至返回不同类的对象).但是,我很少看到这样的事情在实践中完成,几乎总有一些其他方法来实现这些代码的目标而无需定制新的.

注释中引发的自定义/不同Class.new方法的示例:

> Struct.new,可以选择获取类名并返回该动态创建的类的对象.
> In-table inheritance for ActiveRecord,允许最终用户从表中加载未知类的对象并接收正确的对象.

后者可以通过不同的ORM设计来避免继承(尽管所有这些方案都有优点/缺点).

第一个(Structs)是语言的核心,因此必须像现在这样工作(尽管设计者可以选择不同的方法名称).

原文链接:https://www.f2er.com/ruby/269978.html

猜你在找的Ruby相关文章