Last active
September 16, 2016 17:09
-
-
Save pricees/f5ec1c14ca479528f1e695367d074097 to your computer and use it in GitHub Desktop.
Basic Null Object for use in the Rubies
This file contains 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
# A simple null object | |
class NullObject < BasicObject | |
def to_ary; nil end # Handle the `puts call to_ary` don't ask | |
# Add the attributes, methods you care to define here | |
# ... | |
# | |
# def name | |
# 'Nully' | |
# end | |
# Let method missing handle the rest | |
def method_missing(name, *args, &block) | |
name_str = name.to_s | |
case | |
when name_str.end_with?('?') | |
false | |
when name_str.end_with?('s') | |
[] | |
else | |
self | |
end | |
end | |
end | |
nully = NullObject.new | |
nully.nullies? # false | |
nully.nullify! # self | |
nully.nullies.empty? # true | |
nully.some_association? # false | |
nully.some_association.optimistic.call # self | |
nully.nullies.each { |x| foo(x) } # nil | |
# | |
# Rails Example | |
# | |
class User < ActiveRecord::Base | |
has_many :campaigns | |
end | |
class Guest < NullObject | |
def campaigns # Expose ActiveRelation methods | |
Campaign.none | |
end | |
end | |
class CampaignTrafficker | |
def initialize(user: nil) | |
@user = user || Guest.new # protect against explicity passing falsy user argument | |
end | |
def send_campaigns! | |
user.campaigns.each { |campaign| campaign.traffic! } | |
end | |
private | |
attr_internal_reader :user | |
end | |
CampaignTrafficker.new(user: User.first).send_campaigns! # might do something | |
CampaignTrafficker.new(user: nil).send_campaigns! # won't do anything do something | |
# | |
# Null objects w/ duck typing | |
# | |
# No more! | |
foo && foo.bar | |
if foo | |
bar | |
end | |
foo.try(:bar).try(:name) | |
# | |
# Ditch the IFs Use NullObjects w/ Duck-Typing | |
# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment