Ruby / Input/output

From WhyNotWiki

Jump to: navigation, search

Contents

[edit] How to write to a file

irb -> require 'tmpdir'
    => true

irb -> Dir.tmpdir
    => "/tmp"

irb -> File.open(my_filename = "#{Dir.tmpdir}/my_file", "w") { |file| file.puts "woo!" }
    => nil

irb -> File.open(my_filename, "r") { |file| puts file.gets }
woo!
    => nil

irb -> File.delete(my_filename)
    => 1

[edit] How to find out the location of the "temp" directory

irb -> require 'tmpdir'
    => true

irb -> Dir.tmpdir
    => "/tmp"

irb -> File.open(my_filename = "#{Dir.tmpdir}/my_file", "w") { |file| file.puts "woo!" }
    => nil

irb -> File.open(my_filename, "r") { |file| puts file.gets }
woo!
    => nil

irb -> File.delete(my_filename)
    => 1

[edit] How to read in a file

The quickest and easiest way is probably with

  • File.read -- gets you a single lnong string
  • File.readlines (or IO.readlines -- don't ask me why we have both).
irb -> File.read('foo')
    => "line1\nline2\n"

irb -> File.readlines('foo')
    => ["line1\n", "line2\n"]
irb -> require 'rubygems'
irb -> require 'extensions/symbol'

irb -> f = File.open('foo', 'w') { |f| f.puts 'line1'; f.puts 'line2' }
    => nil

irb -> File.readlines('foo')
    => ["line1\n", "line2\n"]
irb -> File.readlines('foo').map(&:chomp)
    => ["line1", "line2"]

You can also open a file and then read from it, if you want a bit more control...

irb -> f = File.open('foo', 'w') { |f| f.puts 'line1'; f.puts 'line2' }
    => nil

[edit] Writing filters / file processors/transformers in Ruby

[edit] Using ARGF

Here's a "simple" example:

http://eigenclass.org/hiki.rb?eigenclass.org+repainted+1

I used a quick Ruby script to rewrite the CSS stylesheets (making most colors 20% darker), and you're getting a new logo with a 50% probability on each pageview.

Here's the (trivial) code:

#!/usr/bin/env ruby

FACTOR = 0.8

def transform_color(r, g, b)
  case r + g + b
  when 255..600
    [r, g, b].map{|x| (FACTOR * x).to_i}
  else
    [r, g, b]
  end
end

css = ARGF.read
css.gsub!(/#[0-9A-Fa-f]{6}/) do |color|
  "#" + 
    transform_color(*color[1..6].scan(/../).map{|x| Integer("0x#{x}") }).map{|x| "%02X" % x}.join("") 
end

css.gsub!(/#[0-9A-Fa-f]{3}(?=[^0-9A-Fa-f])/) do |color|
  r, g, b = color[1..3].scan(/./).map{|x| Integer("0x#{x}#{x}") }
  "#" + 
    transform_color(r, g, b).map{|x| "%02X" % x}.join("") 
end

puts css

[edit] Using File.open_as_string

Facets

http://facets.rubyforge.org/src/doc/rdoc/core/classes/File.html#M000692

  # Reverse contents of "message"
  File.open_as_string("message") { |str| str.reverse! }
require 'facets/core/file/self/open_as_string'

irb -> FileUtils.touch 'foo'
    => ["foo"]

irb -> File.open_as_string('foo') { |s| puts s }

    => nil

irb -> File.open_as_string('foo') { |s| s = "Initial contents\n" }; puts File.read('foo')

    => nil

irb -> File.open_as_string('foo') { |s| s.replace "Initial contents\n" }; puts File.read('foo')
Initial contents
    => nil

irb -> File.open_as_string('foo') { |s| s += "Another line\n" }; puts File.read('foo')
Initial contents
    => nil

irb -> File.open_as_string('foo') { |s| s << "Another line\n" }; puts File.read('foo')
Initial contents
Another line
    => nil


FileUtils.touch 'foo'
File.open_as_string('foo') { |s| s.replace "Initial
contents\n" } # Don't do s = "..."!
File.open_as_string('foo') { |s| s << "Another line\n"
} # Don't do s += "..."!
File.open_as_string('foo') { |s| s.gsub! /old/, 'new' } # Must use in-place version (gsub!), not gsub

[edit] matches.rb

Practically a one-liner!

$stdin.each_line do |filename|
  puts filename if IO.read(filename.chomp) =~ /#{Regexp.escape(ARGV[0])}/
end

[edit] ARGF

Pickaxe, p. 335 or English library RDoc

An object that provides access to the concatenation of the contents of all the files given as command-line arguments, or $stdin (in the case where there are no arguments). $< supports methods similar to a File object: inmode, close, closed?, each, each_byte, each_line, eof, eof?, file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=, read, readchar, readline, readlines, rewind, seek, skip, tell, to_a, to_i, to_io, to_s, along with the methods in Enumerable. The method file returns a File object for the file currently being read. This may change as $< reads through the files on the command line. Read only.

[edit] How do I check if the output stream has been redirected to a pipe?

I want to output in color if it has not been redirected to a pipe, but not output in color if output has been redirected.

In other words, these should generate two different outputs:

my_script.rb | cat -
my_script.rb

I thought maybe this would be the case when the output has been redirected, but it appears not to be the case: ($> != STDOUT)

What else can I check??

Personal tools