Skip to content

Instantly share code, notes, and snippets.

@wobh
Last active March 10, 2016 19:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wobh/dd853f97dfe851831af9 to your computer and use it in GitHub Desktop.
Save wobh/dd853f97dfe851831af9 to your computer and use it in GitHub Desktop.
StreamPrinter
# Stream of consciousness development. Copy/Paste into pry or irb.
require 'stringio'
def stream_print(stream, object)
stream << object.to_str if object.respond_to?(:to_str)
stream
end
io = StringIO.new
ar = %w(foo bar baz qux 1 2 3)
ar.reduce(io) { |str, obj| stream_print(str, obj); str << "\n" }
puts io.string
io = StringIO.new
ar[2] = nil
ar.reduce(io) { |str, obj| stream_print(str, obj); str << "\n" }
puts io.string
def stream_print(stream, object)
case
when object.nil?
stream.puts
when object.respond_to?(:to_str)
stream.puts(object.to_str)
else
nil
end
stream
end
io = $stdout
ar.reduce(io) { |str, obj| stream_print(str, obj) }
# MOAR POWOR!
require 'forwardable'
class StreamPrinter
extend Forwardable
def_delegators :@content, :respond_to?, :to_str, :to_s
attr_reader :content
def initialize(content)
@content = content
end
def printable?
respond_to?(:to_str)
end
def print(stream)
stream.puts(to_str) if printable?
stream
end
def method_missing(*args, &block)
StreamPrinter.new(content.public_send(*args, &block))
rescue NoMethodError
StreamPrinter.new(nil)
end
end
ar.map { |obj| StreamPrinter.new(obj) }.
reduce(io) { |str, obj| obj.print(str) }
Contact = Struct.new(:name, :address, :phone, :email) do
def to_str
"#{name}\n#{address}\n#{phone}\n,#{email}"
end
end
Name = Struct.new(:first_name, :last_name) do
def to_str
"#{first_name} #{last_name}"
end
end
Address = Struct.new(:street_address, :city, :state, :zip) do
def to_str
"#{street_address}\n#{city}, #{state} #{zip}"
end
end
StreetAddress = Struct.new(:number, :street_name, :sub_address) do
def to_str
"#{number} #{street_name}" + (" #{sub_address}" || "")
end
end
def print_mailbox_label(stream, contact)
printer = StreamPrinter.new(contact)
return stream unless ( printer.name.last_name.printable? &&
printer.address.street_address.sub_address.printable? )
printer.name.last_name.print(stream)
printer.address.street_address.sub_address.print(stream)
stream
end
io = StringIO.new
contact = Contact.new(
Name.new("Bibble", "Bobble"),
Address.new(
StreetAddress.new("45", "W Hamshire Ln", "5")))
print_mailbox_label(io, contact)
# The cycle continues ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment