public
Created

Lunacy? Or OO?

  • Download Gist
gistfile1.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
# 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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.