Skip to content

Instantly share code, notes, and snippets.

@joshuaflanagan
Created October 12, 2010 02:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshuaflanagan/621602 to your computer and use it in GitHub Desktop.
Save joshuaflanagan/621602 to your computer and use it in GitHub Desktop.
module Kernel
def maybe(*path)
return path.inject(self) do |obj, method|
return nil if obj.nil?
if method.respond_to? :keys
obj.send(method.first[0], *method.first[1])
else
obj.respond_to?(:keys) ? obj[method] : obj.send(method)
end
end
end
end
class Cart
attr_reader :order
def initialize(order = nil)
@order = order
end
end
class Order
def initialize(lines = [])
@lines = lines
end
def size()
@lines.size
end
def line(index)
@lines[index]
end
end
class OrderLine
attr_reader :product, :qty
def initialize(product, qty=1)
@product = product
@qty = qty
end
end
class Product
attr_reader :name, :details
def initialize(name, details = {})
@name = name
@details = details
end
end
# no objects in call path are nil
cart = Cart.new(Order.new([ OrderLine.new(Product.new("Laptop"), 2), OrderLine.new(Product.new("Desktop"), 3) ]))
puts cart.maybe(:order, :size) # => 2
puts cart.maybe(:order, {:line => [1]}, :product, :name) # => Desktop
# the order is nil
emptyCart = Cart.new
puts emptyCart.maybe(:order, {:line => [1]}, :product, :name) # => nil
# the product on the first line item is nil
emptyLine = Cart.new Order.new([ OrderLine.new(nil) ])
puts emptyLine.maybe(:order, {:line => [0]}, :product, :name) # => nil
# retrieve hash values as well
line = OrderLine.new(Product.new("Keyboard", {:qwerty => true, :keys => 101}), 2)
puts line.maybe(:product, :details, :keys) # => 101
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment