Skip to content

Instantly share code, notes, and snippets.

@dbourguignon
Last active July 9, 2021 01:16
Show Gist options
  • Save dbourguignon/1d7e94daaddd3b2e133ae1fe17aad92f to your computer and use it in GitHub Desktop.
Save dbourguignon/1d7e94daaddd3b2e133ae1fe17aad92f to your computer and use it in GitHub Desktop.
Proc composition in ruby 2.6
require "bigdecimal"
# List of our individual pricing rules
TAX = ->(val) { val + val*0.05 }
FEE = ->(val) { val + 1 }
PREMIUM = ->(val) { val + 10 }
DISCOUNT = ->(val) { val * 0.90 }
ROUND_TO_CENT = ->(val) { val.round(2) }
# One presenter
PRESENT = ->(val) { val.to_f }
# Pre-define some rule set for some pricing scenarios
REGULAR_SET = [FEE, TAX, ROUND_TO_CENT, PRESENT]
PREMIUM_SET = [FEE, PREMIUM, TAX, ROUND_TO_CENT, PRESENT]
DISCOUNTED_SET = [FEE, DISCOUNT, TAX, ROUND_TO_CENT, PRESENT]
def apply_rules(rules:, base_price:)
rules.inject(:>>).call(base_price)
end
amount = BigDecimal(100)
puts "regular: #{apply_rules(rules: REGULAR_SET, base_price: amount)}" # => 106.05
puts "premium: #{apply_rules(rules: PREMIUM_SET, base_price: amount)}" # => 116.55
puts "discounted: #{apply_rules(rules: DISCOUNTED_SET, base_price: amount)}" # => 95.45
# This lambda take one argument and return the same prefixed by "hello "
greet = ->(val) { "hello #{val}" }
# This lambda take one argument and return the upcased version
upper = ->(val) { val.upcase }
# So you can do
puts greet["world"] # => hello world
puts upper["world"] # => WORLD
present = greet >> upper
puts present["world"] # => HELLO WORLD
present = greet << upper
puts present["world"] # => hello WORLD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment