支持完整方法链的Ruby Extended Array类

时间:2019-07-04 05:46:22

标签: arrays ruby oop inheritance

简短:

是否有一种方法可以创建名为Array的扩展A类,该类支持带有mapsortsort_by和新方法{ {1}}并不会伤害word类吗?

示例:

Array

长话:

我解决了kata,并创建了使用新的 [ A.new(a).word, A.new(a).sort.word, A.new(a).sort_by(&:-@).word, A.new(a).map(&:chr).sort.map(&:ord).word ] 方法扩展Array类的代码:

word

然后我认为为此类基类添加方法不是一个好主意。我尝试实现一个新类,该类继承了class Array def word [*self[0..1],*self[-2..-1]].map(&:chr).join end end def sort_transform(a) [ a.word, a.sort.word, a.sort_by(&:-@).word, a.map(&:chr).sort.map(&:ord).word ].join ?- end 的所有行为。

Array

此加法破坏了我的代码,因为class A < Array def word [*self[0..1],*self[-2..-1]].map(&:chr).join end end mapsort返回了一个sort_by实例:Array。并且Array无法理解A.new([1,2,3]).sort.class # Array方法。而不是word,我必须将部分链封装到A.new(a).sort.word构造函数中:A.new。这肯定会破坏方法链。

是否可以将A.new(a.sort).word扩展为这样的纯方法链; Array

当我尝试编写此行时: A类<数组

A.new(a).sort.word

这给我带来了def word [*self[0..1],*self[-2..-1]].map(&:chr).join end def sort A.new(self.sort) end end 终于在写完这行代码之后,我找到了一种避免深度堆栈的方法:将self转换为main.rb:8:in 'sort': stack level too deep (SystemStackError),然后再次将其转换为Array

A

那么这是实现这种扩展的唯一方法吗?

1 个答案:

答案 0 :(得分:4)

如果您想猴子修补核心类,但您认为它很棘手,则应记住,仅针对这种情况进行了改进。

module ArrayWithWord
  refine Array do
    def word
      [*self[0..1],*self[-2..-1]].map(&:chr).join
    end
  end
end

class WordTest
  using ArrayWithWord

  # [].word works here
  def self.sort_transform(a)
    [
      a.word,
      a.sort.word,
      a.sort_by(&:-@).word,
      a.map(&:chr).sort.map(&:ord).word
    ].join ?-
  end
end

WordTest.sort_transform(%w(foo bar baz quux))
# => "fbbq-bbfq-bbfq-bbfq"

# [].word doesn't work here
[].word
# => NoMethodError (undefined method `word' for []:Array)