1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
= IO::Like - in the Likeness of IO
The IO::Like module provides all of the methods of typical IO implementations
such as File; most importantly the read, write, and seek series of methods. A
class which includes IO::Like needs to provide only a few methods in order to
enable the higher level methods. Buffering is automatically provided by default
for the methods which normally provide it in IO.
See the documentation for IO::Like for more details regarding the necessary
methods.
== License
Copyright © 2008,2009 Jeremy Bopp <jeremy at bopp dot net>
Licensed under the same terms as Ruby -- See the included LICENSE file for
details
Some parts licensed under the same terms as the rubyspec project -- See the
included LEGAL and LICENSE.rubyspec files for details
== Installation/Removal
Download the GEM file and install it with:
% sudo gem install io-like-VERSION.gem
or directly with:
% sudo gem install io-like
Removal is the same in either case:
% sudo gem uninstall io-like
== Example
More examples can be found in the +examples+ directory of the source
distribution.
A simple ROT13 codec:
gem 'io-like' # Use require_gem for rubygems versions older than 0.9.0.
require 'io/like'
class ROT13Filter
include IO::Like
def self.open(delegate_io)
filter = new(delegate_io)
return filter unless block_given?
begin
yield(filter)
ensure
filter.close unless filter.closed?
end
end
def initialize(delegate_io)
@delegate_io = delegate_io
end
private
def encode_rot13(string)
result = string.dup
0.upto(result.length) do |i|
case result[i]
when 65..90
result[i] = (result[i] - 52) % 26 + 65
when 97..122
result[i] = (result[i] - 84) % 26 + 97
end
end
result
end
def unbuffered_read(length)
encode_rot13(@delegate_io.sysread(length))
end
def unbuffered_seek(offset, whence = IO::SEEK_SET)
@delegate_io.sysseek(offset, whence)
end
def unbuffered_write(string)
@delegate_io.syswrite(encode_rot13(string))
end
end
File.open('normal_file.txt', 'w') do |f|
f.puts('This is a test')
end
File.open('rot13_file.txt', 'w') do |f|
ROT13Filter.open(f) do |rot13|
rot13.puts('This is a test')
end
end
File.open('normal_file.txt') do |f|
ROT13Filter.open(f) do |rot13|
puts(rot13.read) # -> Guvf vf n grfg
end
end
File.open('rot13_file.txt') do |f|
ROT13Filter.open(f) do |rot13|
puts(rot13.read) # -> This is a test
end
end
File.open('normal_file.txt') do |f|
ROT13Filter.open(f) do |rot13|
rot13.pos = 5
puts(rot13.read) # -> vf n grfg
end
end
File.open('rot13_file.txt') do |f|
ROT13Filter.open(f) do |rot13|
rot13.pos = 5
puts(rot13.read) # -> is a test
end
end
File.open('normal_file.txt') do |f|
ROT13Filter.open(f) do |rot13|
ROT13Filter.open(rot13) do |rot26| # ;-)
puts(rot26.read) # -> This is a test
end
end
end
== Known Bugs/Limitations
1. Only up to version 1.8.6 of Ruby's IO interface is implemented. Version
1.8.7 and eventually 1.9.0/2.0.0 support are coming soon.
2. Ruby's finalization capabilities fall a bit short in a few respects, and as a
result, it is impossible to cause the close, close_read, or close_write
methods to be called automatically when an including class is garbage
collected. Define a class open method in the manner of File.open which
guarantees that an appropriate close method will be called after executing a
block. Other than that, be diligent about calling the close methods.
== Contributing
Contributions for bug fixes, documentation, extensions, tests, etc. are
encouraged. Please read the file HACKING for details.
|