Candidate classes for the Subclassed From Core Class smell are classes which inherit from Core Classes like Hash, String and Array.
Inheriting from Core Classes means that you are going to have a bad time debugging (the explanation below is taken from here):
What do you think this code should do?
List = Class.new(Array)
l = List.new
l << 1
l << 2
puts l.reverse.class # => Array
If you said “it prints Array” you’d be right. Let’s talk about a more pernicious issue: Strings.
class MyString < String
def to_s
"lol"
end
end
s = MyString.new
s.concat "Hey"
puts s # => Hey
puts s.to_s # => lol
puts "#{s}" # => Hey
That’s right! With Strings, Ruby doesn’t call #to_s: it puts the value in directly. Generally speaking, subclassing isn’t the right idea here.
Given
class Ary < Array
end
class Str < String
end
Reek would report the Subclassed From Core Class smell for both classes. Instead of subclassing them you want a data structure that uses one of these core classes internally, but isn’t exactly like one. For instance:
require 'forwardable'
class List
extend Forwardable
def_delegators :@list, :<<, :length # and anything else
def initialize(list = [])
@list = list
end
def reverse
List.new(@list.reverse)
end
end
l = List.new
l << 1
l << 2
puts l.reverse.class # => List
Subclassed From Core Class offers the Basic Smell Options.