Skip to content

Instantly share code, notes, and snippets.

@Integralist
Last active August 29, 2015 14:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Integralist/a96cf6d6f01d5d0cce0a to your computer and use it in GitHub Desktop.
Save Integralist/a96cf6d6f01d5d0cce0a to your computer and use it in GitHub Desktop.
Ruby OOP vs FP (examples are from ThoughtBot's Weekly Iteration -> you should subscribe!)
# Examples taken from ThoughtBot's Weekly Iteration
# We need to implement a solution that allows us to cleanly use two separate APIs
# Our fake APIs
PayPal.charge!(auth_code, 25)
Stripe::CreditCard.new(credit_card_token).charge(25)
# Both of the below classes are utilising the principle of polymorphism
# Strategy pattern (passing in object that determines the strategy to be used)
class Payment < Struct.new(:price, :client)
def charge
client.charge(price)
end
end
# Adapter pattern (creates a consistent internal API when using an external API)
class PayPalAdapter < Struct.new(:auth_code)
def charge(amount)
PayPal.charge!(auth_code, amount)
end
end
# Consistent API thanks to Adapter pattern
Payment.new(25, Stripe::CreditCard.new(credit_card_token)).charge
Payment.new(25, PayPalAdapter.new(auth_code)).charge
# The .call() method allows us to execute the provided method
# and pass through an argument to that method.
# In the following code examples we call Payment.new and pass in a method which can be called
class Payment < Struct.new(:price, :client)
def charge
client.call(price)
end
end
# Use .method() to return a Proc which the above charge method can trigger a .call() on
# http://www.ruby-doc.org/core-2.1.1/Method.html
Payment.new(
25,
Stripe::CreditCard.new(credit_card_token).method(:charge)
).charge
# Again use .method() to return a Proc
# This means we can then use Currying to return another Proc
# That returned Proc has its first argument pre-filled with :auth_code
# The above charge method can then trigger .call() on the curried Proc (passing in the remaining argument)
Payment.new(
25,
PayPal.method(:charge!).curry(:auth_code)
).charge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment