lib/lazydoc/attributes.rb in lazydoc-0.2.0 vs lib/lazydoc/attributes.rb in lazydoc-0.3.0

- old
+ new

@@ -1,53 +1,140 @@ -require 'lazydoc' - module Lazydoc - # Attributes adds methods to declare class-level accessors for Lazydoc + + # Attributes adds methods to declare class-level accessors for constant # attributes. # # # ConstName::key value # class ConstName # extend Lazydoc::Attributes - # # lazy_attr :key # end # # ConstName.source_file # => __FILE__ # ConstName::key.subject # => 'value' # + # ==== Keys and Register + # + # Note that constant attributes parsed from a source file are stored in + # const_attrs, and will ALWAYS be keyed using a string (since the + # 'ConstName::key' syntax specifies a string key). + # + # ConstName.const_attrs['key'] # => ConstName::key + # + # 'Constant Attributes' specified by non-string keys are sometimes used to + # tie comments to a constant that will NOT be resolved from the constant + # attribute syntax. For instance you could register a method like this: + # + # class Sample + # extend Lazydoc::Attributes + # + # const_attrs[:method_one] = register___ + # # this is the method one comment + # def method_one + # end + # end + # + # Sample.lazydoc.resolve + # Sample.const_attrs[:method_one].comment # => "this is the method one comment" + # + # For easier access, you could define a lazy_attr to access the registered + # comment. And in the simplest case, you pair a lazy_register with a + # lazy_attr. + # + # class Paired + # extend Lazydoc::Attributes + # + # lazy_attr(:one, :method_one) + # lazy_attr(:two, :method_two) + # lazy_register(:method_two) + # + # const_attrs[:method_one] = register___ + # # this is the manually-registered method one comment + # def method_one + # end + # + # # this is the lazyily-registered method two comment + # def method_two + # end + # end + # + # Paired.lazydoc.resolve + # Paired.one.comment # => "this is the manually-registered method one comment" + # Paired.two.comment # => "this is the lazyily-registered method two comment" + # module Attributes - # The source_file for self. By default set to the file where - # Attributes extends a class (if you include Attributes, you - # must set source_file manually). + # The source file for the extended class. By default source_file + # is set to the file where Attributes extends the class (if you + # include Attributes, you must set source_file manually). attr_accessor :source_file def self.extended(base) # :nodoc: caller[1] =~ CALLER_REGEXP base.source_file ||= $1 end - - # Returns the lazydoc for source_file - def lazydoc(resolve=true) - lazydoc = Lazydoc[source_file] - lazydoc.resolve if resolve - lazydoc + + # Inherits registered_methods from parent to child. + def inherited(child) + child.registered_methods.merge!(registered_methods) + super end + + # Lazily registers the added method if marked for lazy registration. + def method_added(sym) + if args = registered_methods[sym] + const_attrs[sym] ||= Lazydoc.register_caller(*args) + end + + super + end + + # Returns the constant attributes resolved for the extended class. + def const_attrs + Document[to_s] + end - # Creates a lazy attribute accessor for the specified attribute. - def lazy_attr(key, attribute=key) + # Returns the Document for source_file + def lazydoc + Lazydoc[source_file] + end + + # A hash of (method_name, [comment_class, caller_index]) pairs indicating + # methods to lazily register, and the inputs to Lazydoc.register_caller + # used to register the method. + def registered_methods + @registered_methods ||= {} + end + + # Creates a method that reads and resolves the constant attribute specified + # by key, which should normally be a string (see above for more details). + # If writable is true, a corresponding writer is also created. + def lazy_attr(symbol, key=symbol.to_s, writable=true) + key = case key + when String, Symbol, Numeric, true, false, nil then key.inspect + else "YAML.load(\'#{YAML.dump(key)}\')" + end + instance_eval %Q{ -def #{key} - lazydoc[to_s]['#{attribute}'] ||= Lazydoc::Comment.new -end - -def #{key}=(comment) - Lazydoc[source_file][to_s]['#{attribute}'] = comment +def #{symbol} + comment = const_attrs[#{key}] ||= Subject.new(nil, lazydoc) + comment.kind_of?(Comment) ? comment.resolve : comment end} + + instance_eval(%Q{ +def #{symbol}=(comment) + const_attrs[#{key}] = comment +end}) if writable end - # Registers the next method. - def register_method___(comment_class=Method) - lazydoc(false).register___(comment_class, 1) + # Marks the method for lazy registration. When the method is registered, + # it will be stored in const_attrs by method_name. + def lazy_register(method_name, comment_class=Method, caller_index=1) + registered_methods[method_name.to_sym] = [comment_class, caller_index] + end + + # Registers the next comment (by default as a Method). + def register___(comment_class=Method) + lazydoc.register___(comment_class, 1) end end end