Class: IMW::Resource
- Inherits:
-
Object
- Object
- IMW::Resource
- Defined in:
- lib/imw/resource.rb
Overview
A resource can be anything addressable via a URI. Examples include local files, remote files, webpages, &c.
The IMW::Resource class takes a URI as input and then dynamically extends itself with appropriate modules from IMW. As an example, calling
my_archive = IMW::Resource.new('/path/to/my/archive.tar.bz2')
would return an IMW::Resource extended by IMW::Archives::Tarbz2 (among other modules) which therefore has methods for extracting, listing, and appending to the archive.
Modules are so extended based on handlers defined in the imw/resources
directory and accessible via IMW::Resource.handlers. You can define your own handlers by defining the constant IMW::Resource::USER_DEFINED_HANDLERS in your configuration file.
The modules extending a particular IMW::Resource instance can be listed as follows
my_archive.modules #=> [IMW::Local::Base, IMW::Local::File, IMW::Local::Compressible, IMW::Archives::Tarbz2]
By default, resources are opened for reading. Passing in the appropriate :mode
option changes this:
IMW::Resource.new('/path/to/my_new_file', :mode => 'w')
If the :skip_modules
option is passed in then the resource will not extend itself with any modules and will essentially only retain the bare functionality of a URI. This can be useful when subclassing IMW::Resource or dealing with a very strange kind of resource.
Read the documentation for modules in IMW::Resources to learn more about the various behaviors an IMW::Resource can acquire.
You can also instantiate an IMW::Resource using IMW.open, which accepts all the same arguments as IMW::Resource.new.
Instance Attribute Summary collapse
-
#mode ⇒ Object
The mode in which to access this resource.
-
#resource_options ⇒ Object
A copy of the options passed to this resource on initialization.
Attributes included from Utils::HasURI
Instance Method Summary collapse
-
#close ⇒ Object
Close this resource.
-
#initialize(uri, options = {}) ⇒ IMW::Resource
constructor
Create a new resource representing
uri
. -
#method_missing(method, *args) ⇒ Object
If
method
begins with the stringsis
,on
, orvia
and ends with a question mark then we interpret it as a question this resource doesn’t know how to answer – so we have it answerfalse
. -
#reopen ⇒ IMW::Resource
Open a copy of this resource.
-
#should_exist!(message = nil) ⇒ Object
Raise an error unless this resource exists.
Methods included from Utils::DynamicallyExtendable
#extend, #extend_appropriately!, included, #modules
Methods included from Metadata::Schematized
Methods included from Utils::HasURI
#basename, #dirname, #extension, #extname, #fragment, #name, #password, #scheme, #stripped_uri, #to_s, #user
Constructor Details
#initialize(uri, options = {}) ⇒ IMW::Resource
Create a new resource representing uri
.
IMW will automatically extend the resulting IMW::Resource instance with modules appropriate for the given URI:
r = IMW::Resource.new("http://www.infochimps.com")
r.modules
=> [IMW::Schemes::Remote::Base, IMW::Schemes::Remote::RemoteFile, IMW::Schemes::HTTP, IMW::Formats::Html]
You can prevent this altogether by passing in :no_modules
:
r = IMW::Resource.new("http://www.infochimps.com", :no_modules => true)
r.modules
=> []
And you can exert more fine-grained control with the :use_modules
and :skip_modules
options, see IMW::Resource.extend_instance! for details.
80 81 82 83 84 85 86 |
# File 'lib/imw/resource.rb', line 80 def initialize uri, ={} self.uri = uri self. = self.mode = [:mode] || 'r' self.schema = [:schema] if [:schema] extend_appropriately!() end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
If method
begins with the strings is
, on
, or via
and ends with a question mark then we interpret it as a question this resource doesn’t know how to answer – so we have it answer false
.
As an example, consider the following loop:
IMW.open('/tmp').all_contents.each do |obj|
if obj.is_archive?
# ... do something
end
end
When obj
is initialized and it _isn’t_ an archive, then it doesn’t know about the is_archive?
method – but it should therefore answer false anyway.
This lets a basic text file answer questions about whether it’s an archive (or on S3, or accessed via some user-defined scheme, &c.) without needing to know anything about archives (or S3 or the user-defined scheme).
150 151 152 153 154 155 156 157 |
# File 'lib/imw/resource.rb', line 150 def method_missing method, *args if args.empty? && method.to_s =~ /(is|on|via)_.*\?$/ # querying for a boolean response so answer false return false else raise IMW::NoMethodError, "undefined method `#{method}' for #{self}, extended by #{modules.join(', ')}" end end |
Instance Attribute Details
#mode ⇒ Object
The mode in which to access this resource.
49 50 51 |
# File 'lib/imw/resource.rb', line 49 def mode @mode end |
#resource_options ⇒ Object
A copy of the options passed to this resource on initialization.
52 53 54 |
# File 'lib/imw/resource.rb', line 52 def @resource_options end |
Instance Method Details
#close ⇒ Object
Close this resource.
Modules should hook into super() as they need to redefine this method.
116 117 |
# File 'lib/imw/resource.rb', line 116 def close end |
#reopen ⇒ IMW::Resource
Open a copy of this resource.
This is useful when wanting to reset file handles. Though – be warned – it does not close any file handles itself…
125 126 127 |
# File 'lib/imw/resource.rb', line 125 def reopen IMW.open(uri.to_s) end |
#should_exist!(message = nil) ⇒ Object
Raise an error unless this resource exists.
105 106 107 108 109 110 |
# File 'lib/imw/resource.rb', line 105 def should_exist!(=nil) raise IMW::Error.new([, "No path defined for #{self.inspect} extended by #{modules.join(' ')}"].compact.join(', ')) unless respond_to?(:path) raise IMW::Error.new([, "No exist? method defined for #{self.inspect} extended by #{modules.join(' ')}"].compact.join(', ')) unless respond_to?(:exist?) raise IMW::PathError.new([, "#{path} does not exist"].compact.join(', ')) unless exist? self end |