Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A Ruby module which provides the interface of IO objects to classes providing a few simple methods.
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
examples
lib/io
spec
.gitignore Initial Checkin
CONTRIBUTORS
GPL
HACKING
LEGAL
LICENSE
LICENSE.rubyspec
MANIFEST Update what should be put into the release package
NEWS
README
Rakefile Added magic encoding comment to all Ruby source files
ruby.1.8.mspec
spec_helper.rb Added magic encoding comment to all Ruby source files

README

= 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 versions 1.8.6 and 1.8.7 of Ruby's IO interface are implemented.
   Version 1.9.1 support is planned.
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.
Something went wrong with that request. Please try again.