Skip to content

Instantly share code, notes, and snippets.

@practicingruby
Created February 11, 2013 15:27
Show Gist options
  • Save practicingruby/4755113 to your computer and use it in GitHub Desktop.
Save practicingruby/4755113 to your computer and use it in GitHub Desktop.
## INHERIT from a base class
# -----------------------------------------
class Product < ActiveRecord::Base
belongs_to :category
def self.lookup(item_code)
where(:item_code => item_code).first
end
end
## INCLUDE a module into a class
# -----------------------------------------
class Order
include Enumerable
def initialize(products)
@products = product
end
def each
@products.each { |e| yield(e) }
end
def total_price
reduce { |s,e| s + e.price }
end
end
# EXTEND an individual object with a module
# -----------------------------------------
module Shopper
def add_to_cart(product)
cart << product
end
private
def cart
@cart ||= []
end
end
# Usage:
current_user.extend(Shopper)
current_user.add_to_cart(product)
# PATCH a class definition
# -----------------------------------------
class Numeric
BASE_CURRENCY = "USD"
# NOTE: This is a terrible idea, don't actually do it!
def in_currency(target)
Currency.new(self, BASE_CURRENCY, target)
end
end
# usage
p 10.in_currency("GBP") #=> 6.36
# EVAL some code in the context of another object
# -------------------------------------------------
FactoryGirl.define do
factory :product do
name "Super crusher 5000"
description "The best product ever"
price 500
end
end
# ...
# build() returns a saved Product instance
product = FactoryGirl.build(:product)
p product.price #=> 500
# DECORATE an object using a dynamic proxy
# -------------------------------------------------
require "delegate"
class InternationalProduct < DelegateClass(Product)
BASE_CURRENCY = "USD"
def initialize(product, currency)
@product = product
@currency = currency
super(@product)
end
def price
Currency.convert(@product.price, @currency, BASE_CURRENCY)
end
end
# Usage:
product = InternationalProduct.new(Product.find(1337), "GBP")
p product.description # delegates to Product
p product.price # uses InternationalProduct's definition
## COMPOSE objects using simple aggregation techniques
# -------------------------------------------------
class SalesReport
def initialize(products)
@products = products
end
def summary
"Your order:\n\n" +
@products.map { |e| "* #{e.name}: #{e.price}" }.join("\n")
end
end
@ivdmeer
Copy link

ivdmeer commented Feb 13, 2013

I'm currently reading you document 2013-02-12-code-reuse-in-ruby.pdf which I found at Rubyflow. Thanks for these examples they really help :-)

@mottalrd
Copy link

Amazing job, thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment