[SOLUTION] Whiteout (#34)

A

Ara.T.Howard

my solution tried to strike a balance between being readable and user friendly
(usage message, etc.) and succicntness. the basic idea is that whiteout.rb is
a self modifying program that stores the whited-out files in it's __END__
section as yaml using the expanded path of the original source file as the
key. this has the nice side effect that all sources remain quite readable
within the whiteout.rb __END__ section. eg:


jib:~/tmp > ls
a.rb b.rb whiteout.rb

jib:~/tmp > cat whiteout.rb
#!/usr/bin/env ruby
require 'yaml'

this, prog, *paths = [__FILE__, $0, ARGV].flatten.map{|x| File::expand_path x}
usage = "#{ prog } file [files]+"

f = open this, 'r+'
s, pos = f.gets, f.pos until s =~ /^__END__$/
srcs = YAML::load f

if prog == this
abort usage if paths.empty?
abort "#{ prog } must be writable" unless File::stat(this).writable?
paths.each do |path|
s, b = IO::read(path).split(%r/(^\s*#\s*!.*\n)/o).reverse.first 2
srcs[path] = s
open(path,'w'){|o| o.puts b, "require 'whiteout'\n"}
end
f.seek pos and f << srcs.to_yaml and f.truncate f.pos
else
eval srcs[prog]
end

__END__
---
{}


jib:~/tmp > cat a.rb
#!/usr/bin/env ruby
p 42


jib:~/tmp > cat b.rb
#!/usr/bin/env ruby
p 'forty-two'


jib:~/tmp > ruby a.rb
42


jib:~/tmp > ruby b.rb
"forty-two"


jib:~/tmp > whiteout.rb a.rb b.rb


jib:~/tmp > cat a.rb
#!/usr/bin/env ruby
require 'whiteout'


jib:~/tmp > cat b.rb
#!/usr/bin/env ruby
require 'whiteout'


jib:~/tmp > ruby a.rb
42


jib:~/tmp > ruby b.rb
"forty-two"


jib:~/tmp > cat whiteout.rb
#!/usr/bin/env ruby
require 'yaml'

this, prog, *paths = [__FILE__, $0, ARGV].flatten.map{|x| File::expand_path x}
usage = "#{ prog } file [files]+"

f = open this, 'r+'
s, pos = f.gets, f.pos until s =~ /^__END__$/
srcs = YAML::load f

if prog == this
abort usage if paths.empty?
abort "#{ prog } must be writable" unless File::stat(this).writable?
paths.each do |path|
s, b = IO::read(path).split(%r/(^\s*#\s*!.*\n)/o).reverse.first 2
srcs[path] = s
open(path,'w'){|o| o.puts b, "require 'whiteout'\n"}
end
f.seek pos and f << srcs.to_yaml and f.truncate f.pos
else
eval srcs[prog]
end

__END__
---
"/home/ahoward/tmp/b.rb": "p 'forty-two'\n"
"/home/ahoward/tmp/a.rb": "p 42\n"


all and all quite fun!

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
===============================================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top