Skip to content

Instantly share code, notes, and snippets.

@niquola
Created July 8, 2013 22:53
Show Gist options
  • Save niquola/5953166 to your computer and use it in GitHub Desktop.
Save niquola/5953166 to your computer and use it in GitHub Desktop.
Strong Concern (explicit manage concern dependencies both ways)
# naive implementation
class TwoWayDelegate
attr :_subject
def initialize(subject)
@_subject = subject
end
def inspect
"TwoWayDelegate <#{methods.sort}>"
end
end
module Concern
def concern(mod, options)
delegator_class = Class.new(TwoWayDelegate)
delegator_class.send(:include, mod)
options[:uses].each do |meth|
delegator_class.send :define_method, meth do |*args, &block|
@_subject.send(meth, *args, &block)
end
end
options[:exports].each do |meth|
define_method meth do |*args, &block|
@_concerns ||= {}
@_concerns[mod.to_s] ||= delegator_class.new(self)
@_concerns[mod.to_s].send(meth,*args, &block)
end
end
end
end
#USAGE
module FullNamed
def full_name
"#{first_name} #{last_name}"
end
end
module AgeAssertions
def young?
if age < 16
true
else
false
end
end
def reproductive?
if age > 16 && age < 70
true
else
false
end
end
end
class Person
extend Concern
attr :first_name
attr :last_name
attr :age
def initialize(first_name, last_name, age)
@first_name, @last_name = first_name, last_name
@age = age
end
concern AgeAssertions,
uses: %w[age],
exports: %w[young? reproductive?]
concern FullNamed,
uses: %w[first_name last_name],
exports: %w[full_name]
end
nicola = Person.new('nicola', 'rhyzhikov', 33)
p nicola.full_name
p nicola.young?
p nicola.reproductive?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment