Ruby / Input/output
From WhyNotWiki
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
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??
