Skip to content

Instantly share code, notes, and snippets.

@mrkurt
Created July 29, 2008 23:01
Show Gist options
  • Save mrkurt/3193 to your computer and use it in GitHub Desktop.
Save mrkurt/3193 to your computer and use it in GitHub Desktop.
class Class
def with_attr_reader(*args, &b)
with_attr(:attr_reader, *args, &b)
end
def with_attr_writer(*args, &b)
with_attr(:attr_writer, *args, &b)
end
def with_attr_accessor(*args, &b)
with_attr(:attr_accessor, *args, &b)
end
private
def with_attr(type, *args, &b)
@annotations ||= {}
ann = Annotations.new
ann.instance_eval(&b)
self.send(type, *args)
args.each do |arg|
ann.copy_to(@annotations[arg] ||= {})
ann.run_procs(self, arg)
end
unless respond_to?(:annotations) || @annotations.length == 0
(class << self; self; end).class_eval do
define_method :annotations do
@annotations
end
end
end
end
end
class Annotations
def registered
(@registered ||= {})
end
def copy_to(original)
registered.each do |k, v|
(original[k] ||= []).concat(v)
end
end
def run_procs(context, method)
procs.each { |p| p.call(context, method) }
end
private
def procs
@procs ||= []
end
def register(ann)
if ann.class == Proc
procs.push(ann)
elsif ann.class == Hash
ann.each do |k, v|
(registered[k] ||= []).push(v)
end
end
end
end
class Annotations
def make_awesome(at_what)
register :awesome_at => at_what
end
def make_crappy(at_what)
register :crappy_at => at_what
end
def shadow_attr(name)
register lambda { |context, a|
context.send(:attr_reader, "#{a}_#{name}")
}
end
end
class TestWithAnnotations
with_attr_reader :bird do
make_awesome :flying
make_crappy :swimming
shadow_attr :shadow
shadow_attr :splash
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment