pervasives 1.0.0 → 1.1.0

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