Skip to content

Instantly share code, notes, and snippets.

@alxlion
Last active August 21, 2020 20:04
Show Gist options
  • Save alxlion/bac8e02c1b7e8581cb699dfbe1da5ecf to your computer and use it in GitHub Desktop.
Save alxlion/bac8e02c1b7e8581cb699dfbe1da5ecf to your computer and use it in GitHub Desktop.
Metaprogramming ruby example
# We create a container class. We only store the product's name at instantiation
class Container
attr :product_name
def initialize(name)
@product_name = name
end
end
# Apples ! Oranges ! All of theses fruits are contained in FruitContainer extending Container
# For simplification we only have one scanner
class FruitContainer < Container
def apples_scanner
puts "Scanning apples..."
end
end
# Potatoes ! Broccoli ! All of vegetables are contained in VegetableContainer extending Container
# For simplification we only have one scanner
class VegetableContainer < Container
def potatoes_scanner
puts "Scanning potatoes..."
end
end
# The Cargo containing all the containers
class Cargo
# The constructor accepting multiple parameters
def initialize(*containers)
containers.each do |container|
# self.class.send is used to define singleton methods for our class
# we could also use define_singleton_method
self.class.send(:define_method, "inspect_#{container.product_name}") do
scanner_name = "#{container.product_name}_scanner"
if container.respond_to?(scanner_name)
container.send(scanner_name)
else
puts "No scanner found."
end
end
end
end
end
potatoes_container = VegetableContainer.new "potatoes"
apples_container = FruitContainer.new "apples"
cargo = Cargo.new(potatoes_container, apples_container)
cargo.inspect_apples
cargo.inspect_potatoes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment