Created
August 3, 2012 13:34
-
-
Save david/3247739 to your computer and use it in GitHub Desktop.
Lunacy? Or OO?
This file contains hidden or 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
# Deciding how to handle a collection based on its size. | |
# | |
# Inspired by http://silkandspinach.net/2012/07/06/hexagonal-rails-hiding-the-finders/ | |
# | |
# See below for usage | |
module Demux | |
def demux(demux, outputs = nil, &block) | |
if outputs && block_given? | |
raise ArgumentError, "Pass either a block or an object, not both" | |
elsif outputs | |
demux.demux_outputs outputs | |
elsif block_given? | |
demux.demux_block &block | |
else | |
raise ArgumentError, "Pass either a block or an object" | |
end | |
demux | |
end | |
end | |
module SizeDemux | |
include Demux | |
# Inspect collection size and pick the appropriate line. | |
# | |
# Available lines: | |
# * zero - if the collection is empty | |
# * non_zero(collection) - if the collection is not empty | |
# * one(element) - if the collection has a single element | |
# * many(collection) - if the collection has more than one element | |
# | |
# Usage: | |
# | |
# collection.demux_size do |outputs| | |
# outputs.zero { ... } | |
# outputs.non_zero { |collection| ... } | |
# ... | |
# end | |
# | |
# # or | |
# | |
# class Demuxed | |
# def zero | |
# ... | |
# end | |
# | |
# def non_zero(collection) | |
# ... | |
# end | |
# end | |
# | |
# collection.demux_size(Demuxed.new) | |
# | |
def demux_size(outputs = nil, &block) | |
demux(SizeDemux.new(self), outputs, &block) | |
end | |
class SizeDemux | |
LINES = %w(zero non_zero one many) | |
def initialize(collection) | |
@collection = collection | |
end | |
def demux_block | |
yield self | |
end | |
def demux_outputs(outputs) | |
LINES.each do |line| | |
send(line) { |*args| outputs.send(line, *args) } | |
end | |
end | |
def zero | |
yield if @collection.size == 0 | |
end | |
def non_zero | |
yield @collection if @collection.size > 0 | |
end | |
def one | |
yield @collection.first if @collection.size == 1 | |
end | |
def many | |
yield @collection if @collection.size > 1 | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment