奇怪的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并没有一些额外的注意事项:
. . .我个人认为这个设计有问题,但我认为至少会有明确的动机. 可能有更深层次的Ruby语言使代码在自定义self.new块中运行 – 例如,它可能允许构造函数在返回之前切换或更改特定对象(甚至返回不同类的对象).但是,我很少看到这样的事情在实践中完成,几乎总有一些其他方法来实现这些代码的目标而无需定制新的. 注释中引发的自定义/不同Class.new方法的示例: > Struct.new,可以选择获取类名并返回该动态创建的类的对象. 后者可以通过不同的ORM设计来避免继承(尽管所有这些方案都有优点/缺点). 第一个(Structs)是语言的核心,因此必须像现在这样工作(尽管设计者可以选择不同的方法名称). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |