Created
February 11, 2013 15:27
-
-
Save practicingruby/4755113 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
## 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 :-)