Skip to content

Instantly share code, notes, and snippets.

@elskwid
Created May 24, 2013 21:54
Show Gist options
  • Save elskwid/5646756 to your computer and use it in GitHub Desktop.
Save elskwid/5646756 to your computer and use it in GitHub Desktop.
Playing with structs and Enumerable.find
class SampleContracts
BASE_PATH = "downloads/sample_contracts/"
Contract = Struct.new(:type, :name, :title) do
# Struct responds to .call so it can be used for Enumerable.find(ifnone)
def self.call
new
end
# By adding this method we get a struct that plays nicely with destructuring
alias_method :to_ary, :to_a
def filename
"#{title}.pdf"
end
def path
File.join(BASE_PATH, filename)
end
end
ALL = [
Contract.new(:boat, "Boat", "Boat Rental Agreement"),
Contract.new(:rv, "RV", "RV Rental Agreement"),
Contract.new(:home, "Home", "Home Rental Agreement"),
Contract.new(:atv, "ATV", "ATV Rental Agreement"),
Contract.new(:snowmobile, "Snowmobile", "Snowmobile Rental Agreement"),
Contract.new(:personal_watercraft, "Personal Watercraft", "Watercraft Rental Agreement")
]
def self.all
ALL
end
def self.new_contract
Contract.new
end
def self.each(&block)
all.each(&block)
end
def self.types
all.map(&:type)
end
def self.names
all.map(&:name)
end
def self.titles
all.map(&:title)
end
def self.find(type)
all.find(Contract){ |contract| contract.type == type }
end
def self.alt_find(type)
# Anything that responds to .call - like a method object
all.find(method(:new_contract)){ |contract| contract.type == type }
end
def self.path_for(type)
find(type).path
end
end
puts SampleContracts.all
#<struct SampleContracts::Contract type=:boat, title="Boat Rental Agreement">
#<struct SampleContracts::Contract type=:rv, title="RV Rental Agreement">
#<struct SampleContracts::Contract type=:home, title="Home Rental Agreement">
#<struct SampleContracts::Contract type=:atv, title="ATV Rental Agreement">
#<struct SampleContracts::Contract type=:snowmobile, title="Snowmobile Rental Agreement">
#<struct SampleContracts::Contract type=:personal_watercraft, title="Watercraft Rental Agreement">
puts SampleContracts.titles
# Boat Rental Agreement
# RV Rental Agreement
# Home Rental Agreement
# ATV Rental Agreement
# Snowmobile Rental Agreement
# Watercraft Rental Agreement
SampleContracts.each do |contract|
puts contract.type
end
# boat
# rv
# home
# atv
# snowmobile
# personal_watercraft
SampleContracts.each do |(type, name, title)|
puts "#{type}, #{name}, #{title}"
end
# boat, Boat, Boat Rental Agreement
# rv, RV, RV Rental Agreement
# home, Home, Home Rental Agreement
# atv, ATV, ATV Rental Agreement
# snowmobile, Snowmobile, Snowmobile Rental Agreement
# personal_watercraft, Personal Watercraft, Watercraft Rental Agreement
puts SampleContracts.find(:boat)
#<struct SampleContracts::Contract type=:boat, title="Boat Rental Agreement">
puts SampleContracts.alt_find(:boat)
#<struct SampleContracts::Contract type=:boat, title="Boat Rental Agreement">
puts SampleContracts.find(:missing)
#<struct SampleContracts::Contract type=nil, title=nil>
puts SampleContracts.alt_find(:missing)
#<struct SampleContracts::Contract type=nil, title=nil>
puts SampleContracts.path_for(:home)
# downloads/sample_contracts/Home Rental Agreement.pdf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment