Skip to content

Instantly share code, notes, and snippets.

@thieunv90
Last active December 9, 2019 07:26
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 thieunv90/26235ada6d035fa902fbea36e86ea487 to your computer and use it in GitHub Desktop.
Save thieunv90/26235ada6d035fa902fbea36e86ea487 to your computer and use it in GitHub Desktop.
Tech Debt: Meta-programming & Refactoring
# Before
def check_temperature
if temperature > 30 && (Time.now.hour >= 9 && Time.now.hour <= 17)
air_conditioner.enable!
end
end
# After
def check_temperature
if temperature > 30 && working_hours
air_conditioner.enable!
end
end
def working_hours
Time.now.hour >= 9 && Time.now.hour <= 17
end
# Before
@sold_items = %w( onions garlic potatoes )
def print_report
puts "*** Sales Report for #{Time.new.strftime("%d/%m/%Y")} ***"
@sold_items.each { |i| puts i }
puts "*** End of Sales Report ***"
end
# After
def print_report
print_header
print_items
print_footer
end
def print_header
puts "*** Sales Report for #{current_date} ***"
end
def current_date
Time.new.strftime("%d/%m/%Y")
end
def print_items
@sold_items.each { |i| puts i }
end
def print_footer
puts "*** End of Sales Report ***"
end
# Before
require 'socket'
class MailSender
def initialize
@sent_messages = []
end
def send_message(msg, recipient = "rubyguides.com")
raise ArgumentError, "message too small" if msg.size < 5
formatted_msg = "[New Message] #{msg}"
TCPSocket.open(recipient, 80) do |socket|
socket.write(formatted_msg)
end
@sent_messages << [msg, recipient]
puts "Message sent."
end
end
sender = MailSender.new
sender.send_message("testing")
# After
require 'socket'
class MailSender
def initialize
@sent_messages = []
end
def send_message(msg, recipient = "rubyguides.com")
raise ArgumentError, "message too small" if msg.size < 5
formatted_msg = "[New Message] #{msg}"
TCPSocket.open(recipient, 80) do |socket|
socket.write(formatted_msg)
end
@sent_messages << [msg, recipient]
puts "Message sent."
end
end
sender = MailSender.new
sender.send_message("testing")
# New class
class Message
attr_reader :msg, :recipient
def initialize(msg, recipient = "rubyguides.com")
raise ArgumentError, "message too small" if msg.size < 5
@msg = msg
@recipient = recipient
end
def formatted_msg
"[New Message] #{msg}"
end
end
sender = MailSender.new
msg = Message.new("testing")
sender.deliver_message(msg)
# Bad
if something.isEnabled?
// pretty
// long
// logic
// of
// running
// something
# Good
return unless something.isEnabled?
// same
// long
// logic
// of
// running
// something
# Example 2:
# Bad
def getPayAmount
if self.isDead?
result = deadAmount()
else
if self.isSeparated?
result = separatedAmount()
else
if self.isRetired?
result = retiredAmount()
else
result = normalPayAmount()
end
end
end
return result
end
# Good
def getPayAmount
return deadAmount() if self.isDead?
return separatedAmount() if self.isSeparated?
return retiredAmount() if self.isRetired?
return normalPayAmount()
end
# Before
expect { playlist.destroy }.to change { Playlist.count }.by(-1)
expect { playlist.destroy }.to change { Video.count }.by(0)
# After
expect { playlist.destroy }
.to change { Playlist.count }.by(-1)
.and change { Video.count }.by(0)
RSpec.describe "A compound and matcher" do
let(:string) { "foo bar bazz" }
it "passes when both are true" do
expect(string).to start_with("foo").and end_with("bazz")
end
it "passes when using boolean AND & alias" do
expect(string).to start_with("foo") & end_with("bazz")
end
it "fails when the first matcher fails" do
expect(string).to start_with("bar").and end_with("bazz")
end
it "fails when the second matcher fails" do
expect(string).to start_with("foo").and end_with("bar")
end
end
class TrafficLight
def color
%w[ green yellow red ].shuffle.first
end
end
RSpec.describe TrafficLight, "#color" do
let(:light) { TrafficLight.new }
it "is green, yellow or red" do
expect(light.color).to eq("green").or eq("yellow").or eq("red")
end
it "passes when using boolean OR | alias" do
expect(light.color).to eq("green") | eq("yellow") | eq("red")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment