pervasives 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +159 -0
- data/README.tmpl +21 -0
- data/gemspec.rb +23 -0
- data/gen_readme.rb +32 -0
- data/install.rb +206 -0
- data/lib/pervasives-0.0.1.rb +61 -0
- data/lib/pervasives.rb +61 -0
- data/samples/a.rb +45 -0
- data/samples/b.rb +18 -0
- data/samples/c.rb +14 -0
- data/samples/d.rb +13 -0
- data/test/pervasives.rb +81 -0
- metadata +54 -0
data/README
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
NAME
|
|
2
|
+
|
|
3
|
+
pervasives.rb
|
|
4
|
+
|
|
5
|
+
SYNOPSIS
|
|
6
|
+
|
|
7
|
+
access to pristine object state. if you don't metaprogram you probably
|
|
8
|
+
don't need it
|
|
9
|
+
|
|
10
|
+
INSTALL
|
|
11
|
+
|
|
12
|
+
gem install pervasives
|
|
13
|
+
|
|
14
|
+
URIS
|
|
15
|
+
|
|
16
|
+
http://rubyforge.org/projects/codeforpeople/
|
|
17
|
+
http://codeforpeople.com/lib/ruby
|
|
18
|
+
|
|
19
|
+
SAMPLES
|
|
20
|
+
|
|
21
|
+
<========< samples/a.rb >========>
|
|
22
|
+
|
|
23
|
+
~ > cat samples/a.rb
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Pervasives allows objects' method to be accessed in a pristine state, even
|
|
27
|
+
# when some effort has been made to derride them
|
|
28
|
+
#
|
|
29
|
+
require 'pervasives'
|
|
30
|
+
|
|
31
|
+
class OpenStruct
|
|
32
|
+
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
|
33
|
+
|
|
34
|
+
def initialize
|
|
35
|
+
@table = {}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def method_missing m, *a, &b
|
|
39
|
+
case m.to_s
|
|
40
|
+
when %r/[=]$/
|
|
41
|
+
@table[m.to_s.delete('=')] = a.shift
|
|
42
|
+
when %r/[?!]$/
|
|
43
|
+
!!@table[m.to_s.delete('?!')]
|
|
44
|
+
else
|
|
45
|
+
@table[m.to_s]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def inspect
|
|
50
|
+
@table.inspect
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
os = OpenStruct.new
|
|
55
|
+
|
|
56
|
+
os.object_id = 42
|
|
57
|
+
os.send = 42
|
|
58
|
+
os.instance_eval = 42
|
|
59
|
+
|
|
60
|
+
p os
|
|
61
|
+
|
|
62
|
+
p os.object_id
|
|
63
|
+
p Pervasives.object_id(os)
|
|
64
|
+
|
|
65
|
+
p os.send
|
|
66
|
+
p Pervasives.send(os, "key=", "value")
|
|
67
|
+
|
|
68
|
+
p os.instance_eval
|
|
69
|
+
p Pervasives.instance_eval(os){ @table }
|
|
70
|
+
|
|
71
|
+
~ > ruby samples/a.rb
|
|
72
|
+
|
|
73
|
+
{"instance_eval"=>42, "send"=>42, "object_id"=>42}
|
|
74
|
+
42
|
|
75
|
+
-609487514
|
|
76
|
+
42
|
|
77
|
+
"value"
|
|
78
|
+
42
|
|
79
|
+
{"instance_eval"=>42, "send"=>42, "key"=>"value", "object_id"=>42}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
<========< samples/b.rb >========>
|
|
83
|
+
|
|
84
|
+
~ > cat samples/b.rb
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
# sometimes it may be more convenient to use a Pervasives::Proxy object
|
|
88
|
+
# insteand of using Pervasives directly
|
|
89
|
+
#
|
|
90
|
+
require 'pervasives'
|
|
91
|
+
|
|
92
|
+
class BlankSlate
|
|
93
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
|
94
|
+
|
|
95
|
+
def object_id() 42 end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
bs = BlankSlate.new
|
|
99
|
+
|
|
100
|
+
proxy = Pervasives::Proxy.new bs
|
|
101
|
+
|
|
102
|
+
p bs.object_id
|
|
103
|
+
p proxy.object_id
|
|
104
|
+
|
|
105
|
+
~ > ruby samples/b.rb
|
|
106
|
+
|
|
107
|
+
42
|
|
108
|
+
-609489100
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
<========< samples/c.rb >========>
|
|
112
|
+
|
|
113
|
+
~ > cat samples/c.rb
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# the special '__' method accesses an object's Pervasives::Proxy
|
|
117
|
+
#
|
|
118
|
+
require 'pervasives'
|
|
119
|
+
|
|
120
|
+
class BlankSlate
|
|
121
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
|
122
|
+
def object_id() 42 end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
bs = BlankSlate.new
|
|
126
|
+
|
|
127
|
+
p bs.object_id
|
|
128
|
+
p __(bs){ object_id }
|
|
129
|
+
|
|
130
|
+
~ > ruby samples/c.rb
|
|
131
|
+
|
|
132
|
+
42
|
|
133
|
+
-609486982
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
<========< samples/d.rb >========>
|
|
137
|
+
|
|
138
|
+
~ > cat samples/d.rb
|
|
139
|
+
|
|
140
|
+
#
|
|
141
|
+
# it all works for classes too
|
|
142
|
+
#
|
|
143
|
+
require 'pervasives'
|
|
144
|
+
|
|
145
|
+
class C
|
|
146
|
+
def self.new() raise end
|
|
147
|
+
def inspect() 42 end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
p( Pervasives.new(C) )
|
|
151
|
+
p( Pervasives::Proxy.new(C).new )
|
|
152
|
+
p( __(C).new )
|
|
153
|
+
|
|
154
|
+
~ > ruby samples/d.rb
|
|
155
|
+
|
|
156
|
+
42
|
|
157
|
+
42
|
|
158
|
+
42
|
|
159
|
+
|
data/README.tmpl
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
NAME
|
|
2
|
+
|
|
3
|
+
pervasives.rb
|
|
4
|
+
|
|
5
|
+
SYNOPSIS
|
|
6
|
+
|
|
7
|
+
access to pristine object state. if you don't metaprogram you probably
|
|
8
|
+
don't need it
|
|
9
|
+
|
|
10
|
+
INSTALL
|
|
11
|
+
|
|
12
|
+
gem install pervasives
|
|
13
|
+
|
|
14
|
+
URIS
|
|
15
|
+
|
|
16
|
+
http://rubyforge.org/projects/codeforpeople/
|
|
17
|
+
http://codeforpeople.com/lib/ruby
|
|
18
|
+
|
|
19
|
+
SAMPLES
|
|
20
|
+
|
|
21
|
+
@samples
|
data/gemspec.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
|
|
5
|
+
Gem::Specification::new do |spec|
|
|
6
|
+
spec.name = lib
|
|
7
|
+
spec.version = version
|
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
|
9
|
+
spec.summary = lib
|
|
10
|
+
|
|
11
|
+
spec.files = Dir::glob "**/**"
|
|
12
|
+
spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
|
|
13
|
+
|
|
14
|
+
spec.require_path = "lib"
|
|
15
|
+
spec.autorequire = lib
|
|
16
|
+
|
|
17
|
+
spec.has_rdoc = File::exist? "doc"
|
|
18
|
+
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
|
19
|
+
|
|
20
|
+
spec.author = "Ara T. Howard"
|
|
21
|
+
spec.email = "ara.t.howard@noaa.gov"
|
|
22
|
+
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
|
23
|
+
end
|
data/gen_readme.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
$VERBOSE=nil
|
|
4
|
+
|
|
5
|
+
def indent s, n = 2
|
|
6
|
+
ws = ' ' * n
|
|
7
|
+
s.gsub %r/^/, ws
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
template = IO::read 'README.tmpl'
|
|
11
|
+
|
|
12
|
+
samples = ''
|
|
13
|
+
prompt = '~ > '
|
|
14
|
+
|
|
15
|
+
Dir['sample*/*'].sort.each do |sample|
|
|
16
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
|
17
|
+
|
|
18
|
+
cmd = "cat #{ sample }"
|
|
19
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
|
20
|
+
samples << indent(`#{ cmd }`, 4) << "\n"
|
|
21
|
+
|
|
22
|
+
cmd = "ruby #{ sample }"
|
|
23
|
+
samples << indent(prompt + cmd, 2) << "\n\n"
|
|
24
|
+
|
|
25
|
+
cmd = "ruby -Ilib #{ sample }"
|
|
26
|
+
samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#samples.gsub! %r/^/, ' '
|
|
30
|
+
|
|
31
|
+
readme = template.gsub %r/^\s*@samples\s*$/, samples
|
|
32
|
+
print readme
|
data/install.rb
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'rbconfig'
|
|
3
|
+
require 'find'
|
|
4
|
+
require 'ftools'
|
|
5
|
+
require 'tempfile'
|
|
6
|
+
include Config
|
|
7
|
+
|
|
8
|
+
LIBDIR = "lib"
|
|
9
|
+
LIBDIR_MODE = 0644
|
|
10
|
+
|
|
11
|
+
BINDIR = "bin"
|
|
12
|
+
BINDIR_MODE = 0755
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
$srcdir = CONFIG["srcdir"]
|
|
16
|
+
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
|
17
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
|
18
|
+
$archdir = File.join($libdir, CONFIG["arch"])
|
|
19
|
+
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
|
20
|
+
$bindir = CONFIG["bindir"] || CONFIG['BINDIR']
|
|
21
|
+
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
|
|
22
|
+
$ruby_ext = CONFIG['EXEEXT'] || ''
|
|
23
|
+
$ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
|
|
24
|
+
|
|
25
|
+
if !$site_libdir
|
|
26
|
+
$site_libdir = File.join($libdir, "site_ruby")
|
|
27
|
+
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
|
28
|
+
$site_libdir = File.join($site_libdir, $version)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
|
32
|
+
#{{{
|
|
33
|
+
path = []
|
|
34
|
+
dir = []
|
|
35
|
+
Find.find(srcdir) do |f|
|
|
36
|
+
next unless FileTest.file?(f)
|
|
37
|
+
next if (f = f[srcdir.length+1..-1]) == nil
|
|
38
|
+
next if (/CVS$/ =~ File.dirname(f))
|
|
39
|
+
next if f =~ %r/\.lnk/
|
|
40
|
+
path.push f
|
|
41
|
+
dir |= [File.dirname(f)]
|
|
42
|
+
end
|
|
43
|
+
for f in dir
|
|
44
|
+
next if f == "."
|
|
45
|
+
next if f == "CVS"
|
|
46
|
+
File::makedirs(File.join(destdir, f))
|
|
47
|
+
end
|
|
48
|
+
for f in path
|
|
49
|
+
next if (/\~$/ =~ f)
|
|
50
|
+
next if (/^\./ =~ File.basename(f))
|
|
51
|
+
unless bin
|
|
52
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
|
53
|
+
else
|
|
54
|
+
from = File.join(srcdir, f)
|
|
55
|
+
to = File.join(destdir, f)
|
|
56
|
+
shebangify(from) do |sf|
|
|
57
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
|
58
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
|
59
|
+
File::install(sf, to, mode, false)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
#}}}
|
|
64
|
+
end
|
|
65
|
+
def shebangify f
|
|
66
|
+
#{{{
|
|
67
|
+
open(f) do |fd|
|
|
68
|
+
buf = fd.read 42
|
|
69
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
|
70
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
|
71
|
+
begin
|
|
72
|
+
fd.rewind
|
|
73
|
+
ftmp.puts "#!#{ $ruby }"
|
|
74
|
+
while((buf = fd.read(8192)))
|
|
75
|
+
ftmp.write buf
|
|
76
|
+
end
|
|
77
|
+
ftmp.close
|
|
78
|
+
yield ftmp.path
|
|
79
|
+
ensure
|
|
80
|
+
ftmp.close!
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
yield f
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
#}}}
|
|
87
|
+
end
|
|
88
|
+
def ARGV.switch
|
|
89
|
+
#{{{
|
|
90
|
+
return nil if self.empty?
|
|
91
|
+
arg = self.shift
|
|
92
|
+
return nil if arg == '--'
|
|
93
|
+
if arg =~ /^-(.)(.*)/
|
|
94
|
+
return arg if $1 == '-'
|
|
95
|
+
raise 'unknown switch "-"' if $2.index('-')
|
|
96
|
+
self.unshift "-#{$2}" if $2.size > 0
|
|
97
|
+
"-#{$1}"
|
|
98
|
+
else
|
|
99
|
+
self.unshift arg
|
|
100
|
+
nil
|
|
101
|
+
end
|
|
102
|
+
#}}}
|
|
103
|
+
end
|
|
104
|
+
def ARGV.req_arg
|
|
105
|
+
#{{{
|
|
106
|
+
self.shift || raise('missing argument')
|
|
107
|
+
#}}}
|
|
108
|
+
end
|
|
109
|
+
def linkify d, linked = []
|
|
110
|
+
#--{{{
|
|
111
|
+
if test ?d, d
|
|
112
|
+
versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
|
|
113
|
+
versioned.each do |v|
|
|
114
|
+
src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
|
|
115
|
+
lnk = nil
|
|
116
|
+
begin
|
|
117
|
+
if test ?l, dst
|
|
118
|
+
lnk = "#{ dst }.lnk"
|
|
119
|
+
puts "#{ dst } -> #{ lnk }"
|
|
120
|
+
File::rename dst, lnk
|
|
121
|
+
end
|
|
122
|
+
unless test ?e, dst
|
|
123
|
+
puts "#{ src } -> #{ dst }"
|
|
124
|
+
File::copy src, dst
|
|
125
|
+
linked << dst
|
|
126
|
+
end
|
|
127
|
+
ensure
|
|
128
|
+
if lnk
|
|
129
|
+
at_exit do
|
|
130
|
+
puts "#{ lnk } -> #{ dst }"
|
|
131
|
+
File::rename lnk, dst
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
linked
|
|
138
|
+
#--}}}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
#
|
|
143
|
+
# main program
|
|
144
|
+
#
|
|
145
|
+
|
|
146
|
+
libdir = $site_libdir
|
|
147
|
+
bindir = $bindir
|
|
148
|
+
no_linkify = false
|
|
149
|
+
linked = nil
|
|
150
|
+
help = false
|
|
151
|
+
|
|
152
|
+
usage = <<-usage
|
|
153
|
+
#{ File::basename $0 }
|
|
154
|
+
-d, --destdir <destdir>
|
|
155
|
+
-l, --libdir <libdir>
|
|
156
|
+
-b, --bindir <bindir>
|
|
157
|
+
-r, --ruby <ruby>
|
|
158
|
+
-n, --no_linkify
|
|
159
|
+
-s, --sudo
|
|
160
|
+
-h, --help
|
|
161
|
+
usage
|
|
162
|
+
|
|
163
|
+
begin
|
|
164
|
+
while switch = ARGV.switch
|
|
165
|
+
case switch
|
|
166
|
+
when '-d', '--destdir'
|
|
167
|
+
libdir = ARGV.req_arg
|
|
168
|
+
when '-l', '--libdir'
|
|
169
|
+
libdir = ARGV.req_arg
|
|
170
|
+
when '-b', '--bindir'
|
|
171
|
+
bindir = ARGV.req_arg
|
|
172
|
+
when '-r', '--ruby'
|
|
173
|
+
$ruby = ARGV.req_arg
|
|
174
|
+
when '-n', '--no_linkify'
|
|
175
|
+
no_linkify = true
|
|
176
|
+
when '-s', '--sudo'
|
|
177
|
+
sudo = 'sudo'
|
|
178
|
+
when '-h', '--help'
|
|
179
|
+
help = true
|
|
180
|
+
else
|
|
181
|
+
raise "unknown switch #{switch.dump}"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
rescue
|
|
185
|
+
STDERR.puts $!.to_s
|
|
186
|
+
STDERR.puts usage
|
|
187
|
+
exit 1
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if help
|
|
191
|
+
STDOUT.puts usage
|
|
192
|
+
exit
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
unless no_linkify
|
|
196
|
+
linked = linkify('lib') + linkify('bin')
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
|
|
200
|
+
|
|
201
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
|
202
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
|
203
|
+
|
|
204
|
+
if linked
|
|
205
|
+
linked.each{|path| File::rm_f path}
|
|
206
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
class Pervasives
|
|
2
|
+
VERSION = "0.0.1"
|
|
3
|
+
|
|
4
|
+
METHODS = Hash.new{|h,k| h[k] = {}}
|
|
5
|
+
|
|
6
|
+
[Module, Class, Object].each do |type|
|
|
7
|
+
type.instance_methods.each do |mname|
|
|
8
|
+
m = type.instance_method mname
|
|
9
|
+
METHODS[type][mname.to_s] = m
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
mnames = METHODS[Module].keys + METHODS[Class].keys + METHODS[Object].keys
|
|
15
|
+
|
|
16
|
+
mnames.each do |mname|
|
|
17
|
+
next if mname['__']
|
|
18
|
+
module_eval <<-code
|
|
19
|
+
def #{ mname } obj, *argv, &block
|
|
20
|
+
search_path = case obj
|
|
21
|
+
when Class
|
|
22
|
+
[Class, Module, Object]
|
|
23
|
+
when Module
|
|
24
|
+
[Module, Object]
|
|
25
|
+
else
|
|
26
|
+
[Object]
|
|
27
|
+
end
|
|
28
|
+
type = search_path.detect{|type| METHODS[type]['#{ mname }']}
|
|
29
|
+
m = METHODS[type]['#{ mname }']
|
|
30
|
+
m.bind( obj ).call( *argv, &block )
|
|
31
|
+
end
|
|
32
|
+
code
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class Proxy
|
|
37
|
+
alias_method "__class__", "class"
|
|
38
|
+
alias_method "__instance_eval__", "instance_eval"
|
|
39
|
+
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
|
40
|
+
def initialize obj
|
|
41
|
+
@obj = obj
|
|
42
|
+
end
|
|
43
|
+
def method_missing m, *a, &b
|
|
44
|
+
Pervasives.__send__ m, @obj, *a, &b
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
module Kernel
|
|
53
|
+
def __ obj, &b
|
|
54
|
+
proxy = Pervasives::Proxy.new obj
|
|
55
|
+
b ? proxy.__instance_eval__(&b) : proxy
|
|
56
|
+
end
|
|
57
|
+
def __! obj, &b
|
|
58
|
+
proxy = Pervasives::Proxy.new obj
|
|
59
|
+
b ? proxy.__instance_eval__(&b) : proxy
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/pervasives.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
class Pervasives
|
|
2
|
+
VERSION = "0.0.1"
|
|
3
|
+
|
|
4
|
+
METHODS = Hash.new{|h,k| h[k] = {}}
|
|
5
|
+
|
|
6
|
+
[Module, Class, Object].each do |type|
|
|
7
|
+
type.instance_methods.each do |mname|
|
|
8
|
+
m = type.instance_method mname
|
|
9
|
+
METHODS[type][mname.to_s] = m
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
mnames = METHODS[Module].keys + METHODS[Class].keys + METHODS[Object].keys
|
|
15
|
+
|
|
16
|
+
mnames.each do |mname|
|
|
17
|
+
next if mname['__']
|
|
18
|
+
module_eval <<-code
|
|
19
|
+
def #{ mname } obj, *argv, &block
|
|
20
|
+
search_path = case obj
|
|
21
|
+
when Class
|
|
22
|
+
[Class, Module, Object]
|
|
23
|
+
when Module
|
|
24
|
+
[Module, Object]
|
|
25
|
+
else
|
|
26
|
+
[Object]
|
|
27
|
+
end
|
|
28
|
+
type = search_path.detect{|type| METHODS[type]['#{ mname }']}
|
|
29
|
+
m = METHODS[type]['#{ mname }']
|
|
30
|
+
m.bind( obj ).call( *argv, &block )
|
|
31
|
+
end
|
|
32
|
+
code
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class Proxy
|
|
37
|
+
alias_method "__class__", "class"
|
|
38
|
+
alias_method "__instance_eval__", "instance_eval"
|
|
39
|
+
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
|
40
|
+
def initialize obj
|
|
41
|
+
@obj = obj
|
|
42
|
+
end
|
|
43
|
+
def method_missing m, *a, &b
|
|
44
|
+
Pervasives.__send__ m, @obj, *a, &b
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
module Kernel
|
|
53
|
+
def __ obj, &b
|
|
54
|
+
proxy = Pervasives::Proxy.new obj
|
|
55
|
+
b ? proxy.__instance_eval__(&b) : proxy
|
|
56
|
+
end
|
|
57
|
+
def __! obj, &b
|
|
58
|
+
proxy = Pervasives::Proxy.new obj
|
|
59
|
+
b ? proxy.__instance_eval__(&b) : proxy
|
|
60
|
+
end
|
|
61
|
+
end
|
data/samples/a.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Pervasives allows objects' method to be accessed in a pristine state, even
|
|
3
|
+
# when some effort has been made to derride them
|
|
4
|
+
#
|
|
5
|
+
require 'pervasives'
|
|
6
|
+
|
|
7
|
+
class OpenStruct
|
|
8
|
+
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@table = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def method_missing m, *a, &b
|
|
15
|
+
case m.to_s
|
|
16
|
+
when %r/[=]$/
|
|
17
|
+
@table[m.to_s.delete('=')] = a.shift
|
|
18
|
+
when %r/[?!]$/
|
|
19
|
+
!!@table[m.to_s.delete('?!')]
|
|
20
|
+
else
|
|
21
|
+
@table[m.to_s]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def inspect
|
|
26
|
+
@table.inspect
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
os = OpenStruct.new
|
|
31
|
+
|
|
32
|
+
os.object_id = 42
|
|
33
|
+
os.send = 42
|
|
34
|
+
os.instance_eval = 42
|
|
35
|
+
|
|
36
|
+
p os
|
|
37
|
+
|
|
38
|
+
p os.object_id
|
|
39
|
+
p Pervasives.object_id(os)
|
|
40
|
+
|
|
41
|
+
p os.send
|
|
42
|
+
p Pervasives.send(os, "key=", "value")
|
|
43
|
+
|
|
44
|
+
p os.instance_eval
|
|
45
|
+
p Pervasives.instance_eval(os){ @table }
|
data/samples/b.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#
|
|
2
|
+
# sometimes it may be more convenient to use a Pervasives::Proxy object
|
|
3
|
+
# insteand of using Pervasives directly
|
|
4
|
+
#
|
|
5
|
+
require 'pervasives'
|
|
6
|
+
|
|
7
|
+
class BlankSlate
|
|
8
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
|
9
|
+
|
|
10
|
+
def object_id() 42 end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
bs = BlankSlate.new
|
|
14
|
+
|
|
15
|
+
proxy = Pervasives::Proxy.new bs
|
|
16
|
+
|
|
17
|
+
p bs.object_id
|
|
18
|
+
p proxy.object_id
|
data/samples/c.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#
|
|
2
|
+
# the special '__' method accesses an object's Pervasives::Proxy
|
|
3
|
+
#
|
|
4
|
+
require 'pervasives'
|
|
5
|
+
|
|
6
|
+
class BlankSlate
|
|
7
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
|
8
|
+
def object_id() 42 end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
bs = BlankSlate.new
|
|
12
|
+
|
|
13
|
+
p bs.object_id
|
|
14
|
+
p __(bs){ object_id }
|
data/samples/d.rb
ADDED
data/test/pervasives.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
%w( . ./lib ../lib ).each{|lib| $:.unshift lib}
|
|
2
|
+
require 'pervasives'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
class Pervasives::Test < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def test_a_0
|
|
8
|
+
klass = Class.new
|
|
9
|
+
obj = nil
|
|
10
|
+
|
|
11
|
+
assert_nothing_raised{ obj = Pervasives.new klass }
|
|
12
|
+
|
|
13
|
+
assert_equal klass, obj.class
|
|
14
|
+
|
|
15
|
+
assert_nothing_raised{ Pervasives.inspect obj }
|
|
16
|
+
assert_nothing_raised{ Pervasives.send obj, :inspect }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_b_0
|
|
20
|
+
klass = Class.new
|
|
21
|
+
obj = nil
|
|
22
|
+
|
|
23
|
+
klass.module_eval{ def self.new() raise end }
|
|
24
|
+
assert_nothing_raised{ obj = Pervasives.new klass }
|
|
25
|
+
|
|
26
|
+
value = nil
|
|
27
|
+
assert_nothing_raised{ value = Pervasives.class obj }
|
|
28
|
+
assert_equal klass, value
|
|
29
|
+
|
|
30
|
+
klass.module_eval{ def class() raise end}
|
|
31
|
+
assert_nothing_raised{ value = Pervasives.class obj }
|
|
32
|
+
assert_equal klass, value
|
|
33
|
+
|
|
34
|
+
klass.module_eval{ def to_s() raise end}
|
|
35
|
+
assert_nothing_raised{ Pervasives.to_s obj }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_c_0
|
|
39
|
+
klass = Class.new
|
|
40
|
+
obj = nil
|
|
41
|
+
proxy = nil
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
instance_method_list = nil
|
|
45
|
+
klass.module_eval{
|
|
46
|
+
instance_method_list = instance_methods
|
|
47
|
+
instance_methods.each{|m| define_method(m){ raise }}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
assert_nothing_raised{ obj = Pervasives.new klass }
|
|
51
|
+
assert_nothing_raised{ proxy = Pervasives::Proxy.new obj }
|
|
52
|
+
|
|
53
|
+
assert_nothing_raised{ proxy.to_s }
|
|
54
|
+
assert_equal proxy.to_s, Pervasives.to_s(obj)
|
|
55
|
+
assert_equal proxy.object_id, Pervasives.object_id(obj)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_d_0
|
|
59
|
+
klass = Class.new
|
|
60
|
+
obj = nil
|
|
61
|
+
proxy = nil
|
|
62
|
+
|
|
63
|
+
klass.module_eval{
|
|
64
|
+
instance_methods.each{|m| define_method(m){ raise }}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
assert_nothing_raised{ obj = Pervasives.new klass }
|
|
68
|
+
assert_nothing_raised{ proxy = Pervasives::Proxy.new obj }
|
|
69
|
+
|
|
70
|
+
assert_nothing_raised{ __(obj) }
|
|
71
|
+
|
|
72
|
+
assert_equal __(obj).__class__, Pervasives::Proxy
|
|
73
|
+
|
|
74
|
+
assert_nothing_raised{ __(obj){ to_s } }
|
|
75
|
+
assert_equal __(obj){ to_s }, proxy.to_s
|
|
76
|
+
|
|
77
|
+
assert_nothing_raised{ __!(obj){ object_id } }
|
|
78
|
+
assert_equal __!(obj){ object_id }, proxy.object_id
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
rubygems_version: 0.8.11
|
|
3
|
+
specification_version: 1
|
|
4
|
+
name: pervasives
|
|
5
|
+
version: !ruby/object:Gem::Version
|
|
6
|
+
version: 0.0.1
|
|
7
|
+
date: 2007-01-05 00:00:00.000000 -07:00
|
|
8
|
+
summary: pervasives
|
|
9
|
+
require_paths:
|
|
10
|
+
- lib
|
|
11
|
+
email: ara.t.howard@noaa.gov
|
|
12
|
+
homepage: http://codeforpeople.com/lib/ruby/pervasives/
|
|
13
|
+
rubyforge_project:
|
|
14
|
+
description:
|
|
15
|
+
autorequire: pervasives
|
|
16
|
+
default_executable:
|
|
17
|
+
bindir: bin
|
|
18
|
+
has_rdoc: false
|
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
-
|
|
22
|
+
- ">"
|
|
23
|
+
- !ruby/object:Gem::Version
|
|
24
|
+
version: 0.0.0
|
|
25
|
+
version:
|
|
26
|
+
platform: ruby
|
|
27
|
+
signing_key:
|
|
28
|
+
cert_chain:
|
|
29
|
+
authors:
|
|
30
|
+
- Ara T. Howard
|
|
31
|
+
files:
|
|
32
|
+
- lib
|
|
33
|
+
- test
|
|
34
|
+
- gemspec.rb
|
|
35
|
+
- install.rb
|
|
36
|
+
- samples
|
|
37
|
+
- gen_readme.rb
|
|
38
|
+
- README
|
|
39
|
+
- README.tmpl
|
|
40
|
+
- lib/pervasives-0.0.1.rb
|
|
41
|
+
- lib/pervasives.rb
|
|
42
|
+
- test/pervasives.rb
|
|
43
|
+
- samples/a.rb
|
|
44
|
+
- samples/b.rb
|
|
45
|
+
- samples/c.rb
|
|
46
|
+
- samples/d.rb
|
|
47
|
+
test_files:
|
|
48
|
+
- test/pervasives.rb
|
|
49
|
+
rdoc_options: []
|
|
50
|
+
extra_rdoc_files: []
|
|
51
|
+
executables: []
|
|
52
|
+
extensions: []
|
|
53
|
+
requirements: []
|
|
54
|
+
dependencies: []
|