为什么to_a和to_ary在Array的子​​类中表现不同?

时间:2012-04-17 02:05:33

标签: ruby duck-typing

如果您有一个Array的子​​类X,那么执行X#to_a会返回一个数组对象,而执行X#to_ary会返回一个x对象。

虽然我理解to_a的意思是“我可以改成数组”,而to_ary的意思是“我的行为就像一个数组”,我不明白为什么前者实现了改变而后者却没有。

此外,根据Liskov替换原则,是否没有为to_a返回足够的数组的子类?

2 个答案:

答案 0 :(得分:3)

是“因为这被定义为”足够吗?

  

to_a

     

返回self。如果在Array的子类上调用,则将接收器转换为Array对象。

  

to_ary

     

返回self

可能不是,所以我们进入兔子洞。

除了文档明确指出这就是它的方式之外,推理可能只是真正由Matz等人负责。

尽管看起来似乎to_ary is used when implicit type conversions occur。它用于隐式转换似乎也在this feature request中得到了回应。换句话说,如果一个对象响应to_ary,那么它应被视为Array,并在内部以这种方式使用它。因此to_a适用于您(明确地)需要Array而不是某个子类的情况。

是的,返回一个子类仍然会满足LSP(假设子类不会决定从根本上改变Array的行为,这样就不会),但原则只是声明子类可以替换它的基类,而不是它需要。不管怎么说,我不太确定这里有什么问题,因为你打电话给to_a你明确要求一个不同的对象(继续上面关于隐含转换的推理),因此你说你不要不想要替代对象类型。

答案 1 :(得分:2)

作为一般规则,隐式转换由解释器自动调用,并且它们仅用于转换非常类似于所需类型但未找到的类型。

然而,显式转换可以在不同的类型上调用,只要有一些方法可以从a点到达b点,即使这涉及到某种极地路线或绕道而行

所以你只需要有更多的自由来实现to_a的飞跃,但我同意 X 似乎应该足够好。