Imagine the following code:
class SimpleLetter
def values
("a" .. "z").to_a
end
def ===(other)
values.include?(other)
end
end
class Vowel < SimpleLetter
def values
["a","e","i","o","u"]
end
end
class Consonant < SimpleLetter
def values
super - Vowel.new.values
end
end
objects = ("a" .. "f").to_a + (1 .. 5).to_a
objects.each do |letter|
case letter
when Vowel.new
puts "#{letter} it's a vowel"
when Consonant.new
puts "#{letter} it's a consonant"
else
puts "#{letter} it's something else"
end
end
I could have chosen any other classes instead, I am just using them as an example. I like Scala's match
and extractors a lot, and I figured this could be a nice way of writing the same thing in Ruby. Is there a better way of writing the above without having to instantiate new objects just so I could call their ===
method?
Just to avoid unnecessary posts, yes, I know I could do this:
case letter
when ["a","e","i","o","u"].include?(letter)
# ...
end
You could use class methods instead of instance methods:
class SimpleLetter
def self.values
("a" .. "z").to_a
end
def self.===(other)
values.include?(other)
end
end
class Vowel < SimpleLetter
def self.values
["a","e","i","o","u"]
end
end
class Consonant < SimpleLetter
def self.values
super - Vowel.values
end
end
objects = ("a" .. "f").to_a + (1 .. 5).to_a
objects.each do |letter|
case letter
when Vowel
puts "#{letter} it's a vowel"
when Consonant
puts "#{letter} it's a consonant"
else
puts "#{letter} it's something else"
end
end