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