考虑像
这样的Ruby代码class Row < Hash
def count_of_columns
self.keys.length
end
end
c['Col 1'] = 1
c['Col 2'] = 2
puts c.count_of_columns
# 2
和这样的JavaScript代码:
function Row() {}
Row.prototype.column_count = function() {
return Object.keys(this).length
}
class Row { // has Object as prototype
column_count() {
return Object.keys(this).length
}
}
尽管这些对象在两种不同语言中的使用方式相似,但为什么说ruby builtins的子类化很棘手?我已经看到了“Beware Subclassing Ruby Builtins&#39;”中提到的一些设计注意事项,如果您不在程序中的运行时类型上进行分支,则可能没有这些问题。
是否还有其他原因让人们分享您为什么不直接从Ruby中的内置函数派生出来?具体的东西..谢谢..
答案 0 :(得分:1)
当您对内置子类化时,您开始假设您的子类的行为与内置类似,但是当内置函数返回内置的另一个实例时,您希望它返回子类的另一个实例。但这只会在您提前考虑这种情况并定义方法时才会发生。处理这种情况的方法越多,您对子类的期望越多,导致您在子类中重新实现的方法列表越来越多。
例如,考虑一下您的Row实现。当你在你的行上拨打#select
时,你会发生什么?它应该返回Row
的另一个实例吗?如果您想要这种行为,那么您需要实现它。但是如果你得到那种行为,那么也许你希望#reject
也返回Row
的实例,以及......和... ......(虽然看到评论,有时你会得到你期望的实例!)
我认为一般来说,更好的解决方案是使用内置功能作为“数据”和一些使用适当方法保存数据的域概念。不要让外人操纵你的数据。
为了进一步阅读,您可以了解为什么Rails 5将其ActionController :: Parameters从继承Hash转换为包含Hash的独立对象。我找不到描述所涉及的所有内容的有用链接,因此here's讨论了一个初始拉取请求。