lib/imw/resource.rb in imw-0.2.1 vs lib/imw/resource.rb in imw-0.2.2
- old
+ new
@@ -48,15 +48,40 @@
# You can also instantiate an IMW::Resource using IMW.open, which
# accepts all the same arguments as IMW::Resource.new.
class Resource
attr_reader :uri, :mode
-
+
+ # Create a new resource representing +uri+.
+ #
+ # IMW will automatically extend the resulting IMW::Resourcen
+ # instance with modules appropriate to the given URI.
+ #
+ # r = IMW::Resource.new("http://www.infochimps.com")
+ # r.resource_modules
+ # => [IMW::Schemes::Remote::Base, IMW::Schemes::Remote::RemoteFile, IMW::Schemes::HTTP, IMW::Formats::Html]
+ #
+ # You can prevent this altogether by passing in
+ # <tt>:no_modules</tt>:
+ #
+ # r = IMW::Resource.new("http://www.infochimps.com")
+ # r.resource_modules
+ # => [IMW::Schemes::Remote::Base, IMW::Schemes::Remote::RemoteFile, IMW::Schemes::HTTP, IMW::Formats::Html]
+ #
+ # And you can exert more fine-grained control with the
+ # <tt>:use_modules</tt> and <tt>:skip_modules</tt> options, see
+ # IMW::Resource.extend_resource! for details.
+ #
+ # @param [String, Addressable::URI] uri
+ # @param [Hash] options
+ # @option options [true, false] no_modules
+ # @option options [String] mode the mode to open the resource in (will be ignored when inapplicable)
+ # @return [IMW::Resource]
def initialize uri, options={}
self.uri = uri
@mode = options[:mode] || 'r'
- extend_appropriately! unless options[:skip_modules]
+ extend_appropriately!(options) unless options[:no_modules]
end
# Return the modules this resource has been extended by.
#
# @return [Array] the modules this resource has been extended by.
@@ -71,12 +96,14 @@
super mod
end
# Extend this resource with modules by passing it through a
# collection of handlers defined by IMW::Resource.handlers.
- def extend_appropriately!
- self.class.extend_resource!(self)
+ #
+ # Accepts the same options as Resource.extend_resource!.
+ def extend_appropriately! options={}
+ self.class.extend_resource!(self, options)
end
# Set the URI of this resource by parsing the given +uri+ (if
# necessary).
#
@@ -195,22 +222,30 @@
# Iterate through IMW::Resource.handlers and extend the given
# +resource+ with modules whose handler conditions match the
# resource.
#
+ # Passing in <tt>:use_modules</tt> or <tt>:skip_modules</tt>
+ # allows overriding the default behavior of handlers.
+ #
# @param [IMW::Resource] resource the resource to extend
+ # @param [Hash] options
+ # @option options [Array<String,Module>] use_modules a list of modules used regardless of handlers
+ # @option options [Array<String,Module>] skip_modules a list of modules not to be used regardless of handlers
# @return [IMW::Resource] the extended resource
- def self.extend_resource! resource
+ def self.extend_resource! resource, options={}
+ options.reverse_merge!(:use_modules => [], :skip_modules => [])
handlers.each do |mod_name, handler|
case handler
- when Regexp then extend_resource_with_mod_or_string!(resource, mod_name) if handler =~ resource.uri.to_s
- when Proc then extend_resource_with_mod_or_string!(resource, mod_name) if handler.call(resource)
- when TrueClass then extend_resource_with_mod_or_string!(resource, mod_name)
+ when Regexp then extend_resource_with_mod_or_string!(resource, mod_name, options[:skip_modules]) if handler =~ resource.uri.to_s
+ when Proc then extend_resource_with_mod_or_string!(resource, mod_name, options[:skip_modules]) if handler.call(resource)
+ when TrueClass then extend_resource_with_mod_or_string!(resource, mod_name, options[:skip_modules])
else
raise IMW::TypeError("A handler must be Regexp, Proc, or true")
end
end
+ options[:use_modules].each { |mod_name| extend_resource_with_mod_or_string!(resource, mod_name, options[:skip_modules]) }
resource
end
# A list of handlers to match against each new resource.
#
@@ -255,34 +290,18 @@
#
# @param [IMW::Resource] resource the resource to extend
#
# @param [Module, String] mod_or_string the module or string
# representing a module to extend the resource with
- def self.extend_resource_with_mod_or_string! resource, mod_or_string
+ #
+ # @param [Array<Module,String>] skip_modules modules to exclude
+ def self.extend_resource_with_mod_or_string! resource, mod_or_string, skip_modules
+ return if skip_modules.include?(mod_or_string)
if mod_or_string.is_a?(Module)
resource.extend(mod_or_string)
else
- # Given a string "Mod::SubMod::SubSubMod" first split it into
- # its parts ["Mod", "SubMod", "SubSubMod"] and then begin
- # class_eval'ing them in order so that each is class_eval'd in
- # the scope of the one before it.
- #
- # There is almost certainly a better way to do this.
- # mod_names = mod_or_string.to_s.split('::')
- # mods = []
- # mod_names.each_with_index do |name, index|
- # if index == 0
- # mods << IMW.class_eval(name)
- # else
- # begin
- # mods << class_eval(name)
- # rescue NameError
- # mods << mods[index - 1].class_eval(name)
- # end
- # end
- # end
- # resource.extend(mods.last)
- resource.extend(IMW.class_eval(mod_or_string))
+ m = IMW.class_eval(mod_or_string)
+ resource.extend(m) unless skip_modules.include?(m)
end
end
end
end