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
===============================================================================
(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
===============================================================================