超越“每个”;和“[]”在我的数组子类中,它可以工作,但是“选择”;似乎忽略了它
我有一个类,我希望“each”生成另一个自定义对象,所以我写了这样的:
class Fq_price_set < Array
...
def [](i)
# instead of returning an array, it returns an Fq_price_rec based on the array at i
Fq_price_rec.new(super(i))
end
def each
c = 0
until c == size
yield self.[](c)
c += 1
end
end
...
end
这有效:当我这样做时
my_price_set.each {|rec| puts rec.class}
,它会显示 Fq_price_rec。同样,
my_price_set.each {|rec| puts rec.mymethod}
输出该方法调用的正确值。
但是当我使用 select 时,例如,
my_price_set.select {|rec| rec.mymethod == 1}
我收到错误消息,“未定义的方法”'mymethod' for Array:... 因此,rec(在'select'中)不是 Fq_price_rec,它是一个数组(Fq_price_rec 是其中的子类) )。我(显然是错误的)认为重写“each”意味着像“select”这样的迭代方法会使用它,即子类的“each”版本。简单的答案是我还必须覆盖“选择”,或者是否有更优雅的解决方案。
是的,我对 Ruby 还很陌生。
TIA
I have a class where I want 'each' to yield another custom object, so I wrote this:
class Fq_price_set < Array
...
def [](i)
# instead of returning an array, it returns an Fq_price_rec based on the array at i
Fq_price_rec.new(super(i))
end
def each
c = 0
until c == size
yield self.[](c)
c += 1
end
end
...
end
This works: when I do
my_price_set.each {|rec| puts rec.class}
it shows Fq_price_rec. Similarly,
my_price_set.each {|rec| puts rec.mymethod}
outputs the proper value for that method call.
But when I use select, e.g.,
my_price_set.select {|rec| rec.mymethod == 1}
I get an error msg, "undefined method" 'mymethod' for Array:... So rec (in 'select') is not an Fq_price_rec, it's an array (of which Fq_price_rec is a subclass). I (obviously mistakenly) thought that overriding 'each' would mean that the iterating methods like 'select' would use it, i.e., the subclass's version of 'each'. Is the simple answer that I must also override 'select', or is there a more elegant solution.
Yes, I'm pretty new at Ruby.
TIA
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么不摆脱从 Array 继承,而只使用
include Enumerable
呢?Why not get rid of inheriting from Array, and just have
include Enumerable
?像这样子类化 Array 效果不太好。原因是很多Array是在Ruby解释器内部用C实现的; Array 实现对 Array 的行为方式做出了某些假设,以避免从 C 实现到 Ruby 领域再返回到 C 的额外往返成本。
特别是
select
的实现如下所示:令您悲伤的部分是:
Ruby 直接访问内部C 数组,无需查看您的版本
[]
运算符。所以你应该听格林先生的话:
Subclassing Array like that doesn't work very well. The reason is that a lot of Array is implemented inside the Ruby interpreter in C; the Array implementation makes certain assumptions about how Array behaves in order to avoid the cost of an extra round trip from the C implementation, into Ruby-land, and back down to C.
In particular, the implementation of
select
looks like this:The part that is giving you grief is this:
Ruby is directly accessing the internal C array without going through your version of the
[]
operator.So you should listen to Mr. Grimm: