Created
September 27, 2020 23:43
-
-
Save micahboyd/4b553f51cce1efdeaca4b9f759c3114f to your computer and use it in GitHub Desktop.
Exploring case statement features in ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Regular case statement: | |
case question | |
when :yes then 'Yep' | |
when :no then 'Nope' | |
end | |
# what this is calling === with each element in the case statement as an argument. | |
# basically question === :yes, or without the sugar: question.===(:yes) | |
# This allows different objects to have #=== defined in a way that makes sense | |
# for comparing itself with other objects. | |
# Procs too have their own definition of #=== defined to execute the proc. | |
# So proc.====(arg) is essecially the same as proc.call(arg). | |
# This means can do things like this with procs in case statements: | |
case question | |
when maybe then 'Depends' | |
when :yes then 'Yep' | |
when :no then 'Nope' | |
end | |
def maybe | |
-> (answer) { answer == :yes && answer == :no } | |
end | |
# Also because #maybe is just a method you can give it an argument as well: | |
case question | |
when maybe(detail) then 'Hmmmm...' | |
when :yes then 'Yep' | |
when :no then 'Nope' | |
end | |
def maybe(detail) | |
lambda do |answer| | |
answer == :yes && answer == :no || detail == :complicated | |
end | |
end | |
# You can also achive this in a custom class: | |
case question | |
when FirmNo then 'No thank you.' | |
when :yes then 'Yep' | |
when :no then 'Nope' | |
end | |
class FirmNo | |
# you could define self.call to the same effect | |
def self.===(answer) | |
answer == :no + 1 | |
end | |
end | |
# Or in any object that has === defined: | |
case question | |
when distracted then 'What?' | |
when :yes then 'Yep' | |
when :no then 'Nope' | |
end | |
Focus = Struct.new(:listening, keyword_init: true) do | |
def ===(_) | |
listening | |
end | |
end | |
def distracted | |
Focus.new(listening: false) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment