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::Resources. As an example, calling
my_archive = IMW::Resource.new('/path/to/my/archive.tar.bz2')
would return an IMW::Resource extended by IMW::Resources::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::Resources#handlers. You can define your own handlers by defining the constant IMW::Resources::USER_DEFINED_HANDLERS in your configuration file.
The modules extending a particular IMW::Resource instance can be listed as follows
my_archive.resource_modules #=> [IMW::Resources::LocalObj, IMW::Resources::LocalFile, IMW::Resources::Compressible, IMW::Resources::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.
Instance Attribute Summary collapse
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#uri ⇒ Object
Returns the value of attribute uri.
Instance Method Summary collapse
-
#basename ⇒ String
The basename of this resource’s path.
-
#dirname ⇒ String
The directory name of this resource’s path.
-
#extend(mod) ⇒ Object
Works just like Object#extend except it keeps track of the modules it has extended, see Resource#resource_modules.
-
#extend_appropriately! ⇒ Object
Extend this resource with modules by passing it through a collection of handlers defined by IMW::Resources#handlers.
-
#extension ⇒ String
Returns the extension (WITHOUT the ‘.’) of this resource’s path.
-
#extname ⇒ String
Returns the extension (INCLUDING the ‘.’) of this resource’s path.
-
#initialize(uri, options = {}) ⇒ Resource
constructor
A new instance of Resource.
-
#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
. -
#name ⇒ String
Returns the basename of the file with its extension removed.
-
#reopen ⇒ IMW::Resource
Open a copy of this resource.
-
#resource_modules ⇒ Array
Return the modules this resource has been extended by.
-
#scheme ⇒ String
The scheme of this resource.
-
#should_exist!(message = nil) ⇒ Object
Raise an error unless this resource exists.
- #to_s ⇒ Object
Constructor Details
#initialize(uri, options = {}) ⇒ Resource
Returns a new instance of Resource.
48 49 50 51 52 |
# File 'lib/imw/resource.rb', line 48 def initialize uri, ={} self.uri = uri @mode = [:mode] || 'r' extend_appropriately! unless [:skip_modules] 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).
181 182 183 184 185 186 187 188 |
# File 'lib/imw/resource.rb', line 181 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 #{resource_modules.join(', ')}" end end |
Instance Attribute Details
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
46 47 48 |
# File 'lib/imw/resource.rb', line 46 def mode @mode end |
#uri ⇒ Object
Returns the value of attribute uri.
46 47 48 |
# File 'lib/imw/resource.rb', line 46 def uri @uri end |
Instance Method Details
#basename ⇒ String
The basename of this resource’s path.
108 109 110 |
# File 'lib/imw/resource.rb', line 108 def basename @basename ||= File.basename(path) end |
#dirname ⇒ String
The directory name of this resource’s path.
101 102 103 |
# File 'lib/imw/resource.rb', line 101 def dirname @dirname ||= File.dirname(path) end |
#extend(mod) ⇒ Object
Works just like Object#extend except it keeps track of the modules it has extended, see Resource#resource_modules.
63 64 65 66 |
# File 'lib/imw/resource.rb', line 63 def extend mod resource_modules << mod super mod end |
#extend_appropriately! ⇒ Object
Extend this resource with modules by passing it through a collection of handlers defined by IMW::Resources#handlers
70 71 72 |
# File 'lib/imw/resource.rb', line 70 def extend_appropriately! IMW::Resources.extend_resource!(self) end |
#extension ⇒ String
Returns the extension (WITHOUT the ‘.’) of this resource’s path.
124 125 126 |
# File 'lib/imw/resource.rb', line 124 def extension @extension ||= extname[1..-1] || '' end |
#extname ⇒ String
Returns the extension (INCLUDING the ‘.’) of this resource’s path. Redefine this in an including class for which this is weird (‘.tar.gz’ I’m talking to you…)
117 118 119 |
# File 'lib/imw/resource.rb', line 117 def extname @extname ||= File.extname(path) end |
#name ⇒ String
133 134 135 |
# File 'lib/imw/resource.rb', line 133 def name @name ||= extname ? basename[0,basename.length - extname.length] : basename 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…
156 157 158 |
# File 'lib/imw/resource.rb', line 156 def reopen IMW.open(self.uri.to_s) end |
#resource_modules ⇒ Array
Return the modules this resource has been extended by.
57 58 59 |
# File 'lib/imw/resource.rb', line 57 def resource_modules @resource_modules ||= [] end |
#scheme ⇒ String
The scheme of this resource. Will be nil
for local resources.
94 95 96 |
# File 'lib/imw/resource.rb', line 94 def scheme @scheme ||= uri.scheme end |
#should_exist!(message = nil) ⇒ Object
Raise an error unless this resource exists.
144 145 146 147 148 |
# File 'lib/imw/resource.rb', line 144 def should_exist!(=nil) raise IMW::Error.new([, "No path defined for #{self.inspect} extended by #{resource_modules.join(' ')}"].compact.join(', ')) unless respond_to?(:path) raise IMW::Error.new([, "No exist? method defined for #{self.inspect} extended by #{resource_modules.join(' ')}"].compact.join(', ')) unless respond_to?(:exist?) raise IMW::PathError.new([, "#{path} does not exist"].compact.join(', ')) unless exist? end |
#to_s ⇒ Object
137 138 139 |
# File 'lib/imw/resource.rb', line 137 def to_s uri.to_s end |