pervasives 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -4,8 +4,8 @@ NAME
4
4
 
5
5
  SYNOPSIS
6
6
 
7
- access to pristine object state. if you don't metaprogram you probably
8
- don't need it
7
+ access to pristine object state. if you don't metaprogram or write
8
+ debuggers you probably don't need it.
9
9
 
10
10
  INSTALL
11
11
 
@@ -16,6 +16,18 @@ URIS
16
16
  http://rubyforge.org/projects/codeforpeople/
17
17
  http://codeforpeople.com/lib/ruby
18
18
 
19
+ HISTORY
20
+
21
+ 1.1.0
22
+
23
+ added Pervasives.call method, refactored a bit, updated samples, updated
24
+ tests for new api
25
+
26
+ 1.0.0
27
+
28
+ is NOT backward compatible with any other pervasives version. the new
29
+ library is __greatly__ simplified
30
+
19
31
  SAMPLES
20
32
 
21
33
  <========< samples/a.rb >========>
@@ -23,60 +35,31 @@ SAMPLES
23
35
  ~ > cat samples/a.rb
24
36
 
25
37
  #
26
- # Pervasives allows objects' method to be accessed in a pristine state, even
27
- # when some effort has been made to derride them
38
+ # Pervasives allows an object's methods to be accessed in a pristine state,
39
+ # even when some effort has been made to derride them
28
40
  #
29
41
  require 'pervasives'
30
42
 
31
- class OpenStruct
43
+ class BlankSlate
32
44
  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
45
  end
53
46
 
54
- os = OpenStruct.new
55
-
56
- os.object_id = 42
57
- os.send = 42
58
- os.instance_eval = 42
47
+ bs = BlankSlate.new
59
48
 
60
- p os
49
+ p Pervasives(bs).methods #=> ["__object_pervasive__", "__id__", "__send__", "__pervasive__"]
61
50
 
62
- p os.object_id
63
- p Pervasives.object_id(os)
51
+ p Pervasives(bs).is_a?(BlankSlate) #=> true
64
52
 
65
- p os.send
66
- p Pervasives.send(os, "key=", "value")
53
+ p Pervasives(bs).instance_eval{ @a = 42 } #=> 42
67
54
 
68
- p os.instance_eval
69
- p Pervasives.instance_eval(os){ @table }
55
+ p Pervasives(bs).instance_variables #=> ["@a"]
70
56
 
71
57
  ~ > ruby samples/a.rb
72
58
 
73
- {"instance_eval"=>42, "send"=>42, "object_id"=>42}
74
- 42
75
- 174950
59
+ ["__pervasive__", "__id__", "__send__"]
60
+ true
76
61
  42
77
- "value"
78
- 42
79
- {"instance_eval"=>42, "send"=>42, "key"=>"value", "object_id"=>42}
62
+ ["@a"]
80
63
 
81
64
 
82
65
  <========< samples/b.rb >========>
@@ -84,28 +67,24 @@ SAMPLES
84
67
  ~ > cat samples/b.rb
85
68
 
86
69
  #
87
- # sometimes it may be more convenient to use a Pervasives::Proxy object
88
- # insteand of using Pervasives directly
70
+ # the special method __pervasive__ is added to all objects - it can be used to
71
+ # access the pristine state
89
72
  #
90
73
  require 'pervasives'
91
74
 
92
- class BlankSlate
93
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
94
-
95
- def object_id() 42 end
75
+ class C
76
+ def instance_eval(*a, &b) raise end
96
77
  end
97
78
 
98
- bs = BlankSlate.new
79
+ c = C.new
99
80
 
100
- proxy = Pervasives::Proxy.new bs
81
+ c.__pervasive__(:instance_eval){ @a = 42 }
101
82
 
102
- p bs.object_id
103
- p proxy.object_id
83
+ p c.instance_variables #=> ["@a"]
104
84
 
105
85
  ~ > ruby samples/b.rb
106
86
 
107
- 42
108
- 177470
87
+ ["@a"]
109
88
 
110
89
 
111
90
  <========< samples/c.rb >========>
@@ -113,24 +92,32 @@ SAMPLES
113
92
  ~ > cat samples/c.rb
114
93
 
115
94
  #
116
- # the special '__' method accesses an object's Pervasives::Proxy
95
+ # even if hackery removes the __pervasive__ method you can still call a
96
+ # pristine method on an object
117
97
  #
118
98
  require 'pervasives'
119
99
 
120
- class BlankSlate
121
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
122
- def object_id() 42 end
100
+ class VeryBlankSlate
101
+ instance_methods.each{ |m| undef_method m }
123
102
  end
124
103
 
125
- bs = BlankSlate.new
104
+ vbs = VeryBlankSlate.new
105
+
106
+ begin
107
+ vbs.__pervasive__
108
+ rescue
109
+ 'nope not even that'
110
+ end
111
+
112
+ Pervasives.call(vbs, :instance_eval){ @a = 42 }
126
113
 
127
- p bs.object_id
128
- p __(bs){ object_id }
114
+ p Pervasives.call(vbs, :instance_variables) #=> ["@a"]
129
115
 
130
116
  ~ > ruby samples/c.rb
131
117
 
132
- 42
133
- 177540
118
+ samples/c.rb:8: warning: undefining `__id__' may cause serious problem
119
+ samples/c.rb:8: warning: undefining `__send__' may cause serious problem
120
+ ["@a"]
134
121
 
135
122
 
136
123
  <========< samples/d.rb >========>
@@ -138,22 +125,21 @@ SAMPLES
138
125
  ~ > cat samples/d.rb
139
126
 
140
127
  #
141
- # it all works for classes too
128
+ # of course it works for classes and modules too
142
129
  #
143
130
  require 'pervasives'
144
131
 
145
132
  class C
146
133
  def self.new() raise end
147
- def inspect() 42 end
134
+
135
+ def inspect() 42.inspect end
148
136
  end
149
137
 
150
- p( Pervasives.new(C) )
151
- p( Pervasives::Proxy.new(C).new )
152
- p( __(C).new )
138
+ c = C.__pervasive__ :new
139
+
140
+ p c #=> 42
153
141
 
154
142
  ~ > ruby samples/d.rb
155
143
 
156
144
  42
157
- 42
158
- 42
159
145
 
@@ -4,8 +4,8 @@ NAME
4
4
 
5
5
  SYNOPSIS
6
6
 
7
- access to pristine object state. if you don't metaprogram you probably
8
- don't need it
7
+ access to pristine object state. if you don't metaprogram or write
8
+ debuggers you probably don't need it.
9
9
 
10
10
  INSTALL
11
11
 
@@ -18,6 +18,11 @@ URIS
18
18
 
19
19
  HISTORY
20
20
 
21
+ 1.1.0
22
+
23
+ added Pervasives.call method, refactored a bit, updated samples, updated
24
+ tests for new api
25
+
21
26
  1.0.0
22
27
 
23
28
  is NOT backward compatible with any other pervasives version. the new
@@ -0,0 +1,52 @@
1
+ module Pervasives
2
+ VERSION = "1.1.0"
3
+ def self.version() VERSION end
4
+
5
+ Methods = Hash.new{|h,k| h[k] = {}}
6
+
7
+ [Class, Module, Object].each do |type|
8
+ type.instance_methods.each do |m|
9
+ Methods[type]["#{ m }"] = type.instance_method m
10
+ end
11
+ end
12
+
13
+ def self.call o, m, *a, &b
14
+ list =
15
+ case o
16
+ when Class then [Class, Module, Object]
17
+ when Module then [Module, Object]
18
+ when Object then [Object]
19
+ end
20
+ type = list.detect{|type| Methods[type]["#{ m }"]}
21
+ m = Methods[type]["#{ m }"]
22
+ ( m ).bind( o ).call( *a, &b )
23
+ end
24
+
25
+ class ::Object
26
+ def __pervasive__ m, *a, &b
27
+ Pervasives.call self, m, *a, &b
28
+ end
29
+ end
30
+
31
+ class Proxy
32
+ instance_methods.each{|m| undef_method m unless m[%r/__/]}
33
+
34
+ def initialize obj
35
+ @obj = obj
36
+ end
37
+
38
+ def method_missing m, *a, &b
39
+ Pervasives.call @obj, m, *a, &b
40
+ end
41
+ end
42
+
43
+ def self.new *a, &b
44
+ Proxy.new *a, &b
45
+ end
46
+
47
+ class ::Object
48
+ def Pervasives *a, &b
49
+ Proxy.new *a, &b
50
+ end
51
+ end
52
+ end
@@ -1,32 +1,52 @@
1
1
  module Pervasives
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  def self.version() VERSION end
4
- class ::Class
5
- def __pervasive__ m, *a, &b
6
- (( Class.instance_method(m) rescue Module.instance_method(m) rescue Object.instance_method(m) )).bind(self).call(*a, &b)
4
+
5
+ Methods = Hash.new{|h,k| h[k] = {}}
6
+
7
+ [Class, Module, Object].each do |type|
8
+ type.instance_methods.each do |m|
9
+ Methods[type]["#{ m }"] = type.instance_method m
7
10
  end
8
11
  end
9
- class ::Module
10
- def __pervasive__ m, *a, &b
11
- (( Module.instance_method(m) rescue Object.instance_method(m) )).bind(self).call(*a, &b)
12
- end
12
+
13
+ def self.call o, m, *a, &b
14
+ list =
15
+ case o
16
+ when Class then [Class, Module, Object]
17
+ when Module then [Module, Object]
18
+ when Object then [Object]
19
+ end
20
+ type = list.detect{|type| Methods[type]["#{ m }"]}
21
+ m = Methods[type]["#{ m }"]
22
+ ( m ).bind( o ).call( *a, &b )
13
23
  end
24
+
14
25
  class ::Object
15
26
  def __pervasive__ m, *a, &b
16
- (( Object.instance_method(m) )).bind(self).call(*a, &b)
27
+ Pervasives.call self, m, *a, &b
17
28
  end
18
29
  end
19
30
 
20
31
  class Proxy
21
32
  instance_methods.each{|m| undef_method m unless m[%r/__/]}
33
+
22
34
  def initialize obj
23
35
  @obj = obj
24
36
  end
37
+
25
38
  def method_missing m, *a, &b
26
- @obj.__pervasive__ m, *a, &b
39
+ Pervasives.call @obj, m, *a, &b
27
40
  end
28
- def __obj__
29
- @obj
41
+ end
42
+
43
+ def self.new *a, &b
44
+ Proxy.new *a, &b
45
+ end
46
+
47
+ class ::Object
48
+ def Pervasives *a, &b
49
+ Proxy.new *a, &b
30
50
  end
31
51
  end
32
52
  end
@@ -1,45 +1,19 @@
1
1
  #
2
- # Pervasives allows objects' method to be accessed in a pristine state, even
3
- # when some effort has been made to derride them
2
+ # Pervasives allows an object's methods to be accessed in a pristine state,
3
+ # even when some effort has been made to derride them
4
4
  #
5
5
  require 'pervasives'
6
6
 
7
- class OpenStruct
7
+ class BlankSlate
8
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
9
  end
29
10
 
30
- os = OpenStruct.new
31
-
32
- os.object_id = 42
33
- os.send = 42
34
- os.instance_eval = 42
11
+ bs = BlankSlate.new
35
12
 
36
- p os
13
+ p Pervasives(bs).methods #=> ["__object_pervasive__", "__id__", "__send__", "__pervasive__"]
37
14
 
38
- p os.object_id
39
- p Pervasives.object_id(os)
15
+ p Pervasives(bs).is_a?(BlankSlate) #=> true
40
16
 
41
- p os.send
42
- p Pervasives.send(os, "key=", "value")
17
+ p Pervasives(bs).instance_eval{ @a = 42 } #=> 42
43
18
 
44
- p os.instance_eval
45
- p Pervasives.instance_eval(os){ @table }
19
+ p Pervasives(bs).instance_variables #=> ["@a"]
@@ -1,18 +1,15 @@
1
1
  #
2
- # sometimes it may be more convenient to use a Pervasives::Proxy object
3
- # insteand of using Pervasives directly
2
+ # the special method __pervasive__ is added to all objects - it can be used to
3
+ # access the pristine state
4
4
  #
5
5
  require 'pervasives'
6
6
 
7
- class BlankSlate
8
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
9
-
10
- def object_id() 42 end
7
+ class C
8
+ def instance_eval(*a, &b) raise end
11
9
  end
12
10
 
13
- bs = BlankSlate.new
11
+ c = C.new
14
12
 
15
- proxy = Pervasives::Proxy.new bs
13
+ c.__pervasive__(:instance_eval){ @a = 42 }
16
14
 
17
- p bs.object_id
18
- p proxy.object_id
15
+ p c.instance_variables #=> ["@a"]
@@ -1,14 +1,21 @@
1
1
  #
2
- # the special '__' method accesses an object's Pervasives::Proxy
2
+ # even if hackery removes the __pervasive__ method you can still call a
3
+ # pristine method on an object
3
4
  #
4
5
  require 'pervasives'
5
6
 
6
- class BlankSlate
7
- instance_methods.each { |m| undef_method m unless m =~ /^__/ }
8
- def object_id() 42 end
7
+ class VeryBlankSlate
8
+ instance_methods.each{ |m| undef_method m }
9
9
  end
10
10
 
11
- bs = BlankSlate.new
11
+ vbs = VeryBlankSlate.new
12
12
 
13
- p bs.object_id
14
- p __(bs){ object_id }
13
+ begin
14
+ vbs.__pervasive__
15
+ rescue
16
+ 'nope not even that'
17
+ end
18
+
19
+ Pervasives.call(vbs, :instance_eval){ @a = 42 }
20
+
21
+ p Pervasives.call(vbs, :instance_variables) #=> ["@a"]
@@ -1,13 +1,14 @@
1
1
  #
2
- # it all works for classes too
2
+ # of course it works for classes and modules too
3
3
  #
4
4
  require 'pervasives'
5
5
 
6
6
  class C
7
7
  def self.new() raise end
8
- def inspect() 42 end
8
+
9
+ def inspect() 42.inspect end
9
10
  end
10
11
 
11
- p( Pervasives.new(C) )
12
- p( Pervasives::Proxy.new(C).new )
13
- p( __(C).new )
12
+ c = C.__pervasive__ :new
13
+
14
+ p c #=> 42
@@ -6,33 +6,30 @@ class Pervasives::Test < Test::Unit::TestCase
6
6
 
7
7
  def test_a_0
8
8
  klass = Class.new
9
+ pklass = nil
9
10
  obj = nil
10
11
 
11
- assert_nothing_raised{ obj = Pervasives.new klass }
12
+ assert_nothing_raised{ pklass = Pervasives klass }
13
+ assert_nothing_raised{ obj = pklass.new }
12
14
 
13
15
  assert_equal klass, obj.class
14
-
15
- assert_nothing_raised{ Pervasives.inspect obj }
16
- assert_nothing_raised{ Pervasives.send obj, :inspect }
17
16
  end
18
17
 
18
+
19
19
  def test_b_0
20
20
  klass = Class.new
21
21
  obj = nil
22
+ value = nil
22
23
 
23
24
  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
25
+ assert_nothing_raised{ obj = Pervasives(klass).new }
29
26
 
30
27
  klass.module_eval{ def class() raise end}
31
- assert_nothing_raised{ value = Pervasives.class obj }
28
+ assert_nothing_raised{ value = Pervasives(obj).class }
32
29
  assert_equal klass, value
33
30
 
34
31
  klass.module_eval{ def to_s() raise end}
35
- assert_nothing_raised{ Pervasives.to_s obj }
32
+ assert_nothing_raised{ Pervasives(obj).to_s }
36
33
  end
37
34
 
38
35
  def test_c_0
@@ -41,41 +38,23 @@ class Pervasives::Test < Test::Unit::TestCase
41
38
  proxy = nil
42
39
 
43
40
 
41
+ assert_nothing_raised{ obj = Pervasives(klass).new }
42
+ object_id = obj.object_id
43
+ to_s = obj.to_s
44
+
44
45
  instance_method_list = nil
45
46
  klass.module_eval{
46
47
  instance_method_list = instance_methods
47
48
  instance_methods.each{|m| define_method(m){ raise }}
48
49
  }
49
50
 
50
- assert_nothing_raised{ obj = Pervasives.new klass }
51
- assert_nothing_raised{ proxy = Pervasives::Proxy.new obj }
51
+ assert_nothing_raised{ proxy = Pervasives obj }
52
52
 
53
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
54
+ assert_equal to_s, proxy.to_s
55
+ assert_equal to_s, Pervasives(obj).to_s
56
+ assert_equal object_id, proxy.object_id
57
+ assert_equal object_id, Pervasives(obj).object_id
79
58
  end
80
59
 
81
60
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: pervasives
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2007-09-08 00:00:00 -06:00
6
+ version: 1.1.0
7
+ date: 2007-09-24 00:00:00 -06:00
8
8
  summary: pervasives
9
9
  require_paths:
10
10
  - lib
@@ -33,9 +33,8 @@ files:
33
33
  - gen_readme.rb
34
34
  - install.rb
35
35
  - lib
36
- - lib/pervasives-1.0.0.rb
36
+ - lib/pervasives-1.1.0.rb
37
37
  - lib/pervasives.rb
38
- - pervasives-1.0.0.gem
39
38
  - README
40
39
  - README.tmpl
41
40
  - samples
@@ -1,32 +0,0 @@
1
- module Pervasives
2
- VERSION = "1.0.0"
3
- def self.version() VERSION end
4
- class ::Class
5
- def __pervasive__ m, *a, &b
6
- (( Class.instance_method(m) rescue Module.instance_method(m) rescue Object.instance_method(m) )).bind(self).call(*a, &b)
7
- end
8
- end
9
- class ::Module
10
- def __pervasive__ m, *a, &b
11
- (( Module.instance_method(m) rescue Object.instance_method(m) )).bind(self).call(*a, &b)
12
- end
13
- end
14
- class ::Object
15
- def __pervasive__ m, *a, &b
16
- (( Object.instance_method(m) )).bind(self).call(*a, &b)
17
- end
18
- end
19
-
20
- class Proxy
21
- instance_methods.each{|m| undef_method m unless m[%r/__/]}
22
- def initialize obj
23
- @obj = obj
24
- end
25
- def method_missing m, *a, &b
26
- @obj.__pervasive__ m, *a, &b
27
- end
28
- def __obj__
29
- @obj
30
- end
31
- end
32
- end
File without changes