Skip to content

Instantly share code, notes, and snippets.

@forest
Last active December 21, 2015 04:48
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 forest/6251831 to your computer and use it in GitHub Desktop.
Save forest/6251831 to your computer and use it in GitHub Desktop.
Use OO instead of basic ruby types to represent Rights
ALL_RIGHTS = [
CAN_ACCESS_RESOURCES,
CAN_ACCESS_ORGANIZATIONS,
CAN_CREATE_ORGANIZATIONS,
CAN_ACCESS_SCHOOL_EDITION
]
# ---------------------------
class Rights
extend Forwardable
def_delegators :@rights, :each
def initialize(*rights)
@rights = rights
end
def cache_key
Digest::MD5.hexdigest(@rights.map(&:cache_key).join)
end
end
class Right
attr_accessor :name, :version
def initialize(name, version)
@name = name
@version = version
end
def to_s
name
end
def to_sym
name.to_sym
end
def cache_key
Digest::MD5.hexdigest([name, version].join)
end
end
ALL_RIGHTS = Rights.new(
Right.new('CAN_ACCESS_RESOURCES', 1),
Right.new('CAN_ACCESS_ORGANIZATIONS', 1),
Right.new('CAN_CREATE_ORGANIZATIONS', 1),
Right.new('CAN_ACCESS_SCHOOL_EDITION', 1)
)
# -------- OR ----------------
class Right
def name
self.class.name.split('::').last.underscorize
end
def to_s
name
end
def to_sym
name.to_sym
end
def cache_key
Digest::MD5.hexdigest([name, version].join)
end
end
class CanAccessResources < Right
def version; 1; end
end
ALL_RIGHTS = Rights.new(
CanAccessResources.new
)
# ------------------------------
# The key to working productively in an object-oriented language is to make the type system and polymorphic method dispatch do your work for you. When
# dealing with string (or Symbol) values coming from the "borders" of our code, it can be tempting to simply ensure that they are in the expected set
# of valid values, and leave it at that. However, when we look deeper we may discover a distinct concept struggling to emerge. Representing this concept
# as a class or set of classes can not only make the code less error-prone; it can clarify our understanding of the problem, and improve the design of
# all the classes which deal with that concept. This, in turn, means methods which spend less time reiterating input checks, and more time telling a
# clear story.
# - Avdi (Confident Ruby)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment