Short:
Есть ли способ создать расширенный класс Array
с именем A
, который поддерживает полную цепочку методов с map
, sort
, sort_by
и новым методом word
и не наносит вреда классу Array
Пример:
[
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
Это дополнение нарушает мой код, потому что map
, sort
, sort_by
возвращает Array
экземпляр: A.new([1,2,3]).sort.class # Array
. И Массив не понимает word
метод. И вместо A.new(a).sort.word
мне нужно заключить часть цепочки в конструктор A.new
: A.new(a.sort).word
. Это определенно разрывает чистую цепочку методов.
Можно ли расширить Array
таким образом, чтобы получить чистые цепочки методов, подобные этой; A.new(a).sort.word
Когда я попытался написать строку так:
класс А <Массив </p>
def word
[*self[0..1],*self[-2..-1]].map(&:chr).join
end
def sort
A.new(self.sort)
end
end
Это приносит мне main.rb:8:in 'sort': stack level too deep (SystemStackError)
Наконец, уже написав эти строки, я нашел способ избежать глубокого стека: преобразовать себя в Array
, а затем снова преобразовать его в A
.
class A < Array
def word
[*self[0..1],*self[-2..-1]].map(&:chr).join
end
def sort
A.new(self.to_a.sort)
end
end
Так это единственный способ реализовать такое расширение?