File: README

package info (click to toggle)
ruby-io-like 0.3.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 184 kB
  • sloc: ruby: 514; makefile: 3
file content (150 lines) | stat: -rw-r--r-- 3,973 bytes parent folder | download | duplicates (2)
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.