In the example with monsters, perhaps the issue is that all the different monster types are classes instead of data. For instance, I would instead implement something like
class Monster
attr_reader :type
def initialize(type, likes = {})
@type = type
@likes = likes
end
def likes?(x)
@likes[x.type]
end
end
orc = Monster.new(:orc)
troll = Monster.new(:troll)
elf = Monster.new(:elf)
elf_maiden = Monster.new(:elf_maiden, :elf => true)
puts troll.likes?(elf)
puts elf_maiden.likes?(elf)
If you have 150 subclasses, it is a code smell in the first place, and perhaps by addressing the root problem, issues like the one Steve mentions won't occur in the first place.