Skip to content

Instantly share code, notes, and snippets.

@guyboertje
Created March 2, 2012 19:51
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 guyboertje/1960855 to your computer and use it in GitHub Desktop.
Save guyboertje/1960855 to your computer and use it in GitHub Desktop.
DCI: Builder approach
module RoleExtender
def new properties = {}
include_roles nil, properties
end
private
def include_roles roles, properties
instance = allocate()
[roles].flatten.each do |r|
instance.extend r
end if roles
instance.properties = properties if instance.respond_to? :properties=
instance
end
end
module ReaderRoleExtender
include RoleExtender
def as_json_reader props = {}
include_roles JsonReaderRole, props
end
def as_csv_reader props = {}
include_roles CsvReaderRole, props
end
end
module JsonReaderRole
def to_json
#open file and format for json
p "Json"
end
end
module CsvReaderRole
def to_csv
#open file and format for csv
p "Csv"
end
end
class Reader
class << self
include ReaderRoleExtender
end
# regular includes
[].each do |role|
include role
end
attr_reader :file
attr_reader :properties
def properties= props
@file = props.fetch(:file, "")
end
end
jr = Reader.as_json_reader file: "/tmp/foo"
=> #<Reader:0x00000001e12a98 @options={:file=>"/tmp/foo"}>
jr.to_json
"Json"
=> "Json"
jr.to_csv
NoMethodError: undefined method 'to_csv' for #<Reader:0x00000001e12a98 @options={}>
cr = Reader.as_csv_reader file: "/tmp/foo"
=> #<Reader:0x00000001dff178 @options={:file=>"/tmp/foo"}>
cr.to_csv
"Csv"
=> "Csv"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment