attributes 3.7.0 → 4.0.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 +51 -16
- data/README.tmpl +32 -4
- data/a.rb +29 -0
- data/lib/attributes-4.0.0.rb +110 -0
- data/lib/attributes.rb +57 -70
- data/samples/a.rb +6 -7
- data/samples/b.rb +9 -3
- data/samples/c.rb +1 -1
- metadata +4 -3
- data/lib/attributes-3.7.0.rb +0 -123
data/README
CHANGED
@@ -11,17 +11,45 @@ URIS
|
|
11
11
|
SYNOPSIS
|
12
12
|
attributes.rb provides a set of attr_* like method with several user
|
13
13
|
friendly additions. attributes.rb is similar to the traits.rb package but
|
14
|
-
sacrifices a few features for simplicity of implementation
|
15
|
-
only 42 lines of code.
|
14
|
+
sacrifices a few features for simplicity of implementation.
|
16
15
|
|
17
|
-
the
|
16
|
+
the implementation of attributes.rb borrows many of the best ideas from the
|
18
17
|
metakoans.rb ruby quiz
|
19
18
|
|
20
19
|
http://www.rubyquiz.com/quiz67.html
|
21
20
|
|
22
|
-
in particular the solutions of Christian Neukirchen and Florian Gross
|
21
|
+
in particular the solutions of Christian Neukirchen and Florian Gross along
|
22
|
+
with concepts from the original traits lib
|
23
|
+
|
24
|
+
key features provided by attributes are
|
25
|
+
|
26
|
+
- ability to specify default values for attrs and definition time. values
|
27
|
+
can be literal objects or blocks, which are evaluated in the context of
|
28
|
+
self to initialize the variable
|
29
|
+
|
30
|
+
- classes remember which attributes they've defined and this information is
|
31
|
+
available to client code
|
32
|
+
|
33
|
+
- a whole suite of methods is defined by calls to #attributes including
|
34
|
+
getter, setter, query (var?) and banger (var! - which forces
|
35
|
+
re-initialization from the default value)
|
36
|
+
|
37
|
+
- ability to define multiple attributes at once using key => value pairs
|
38
|
+
|
39
|
+
- fast lookup of whether or not a class has defined a certain attribute
|
40
|
+
|
41
|
+
- attributes can be defined on objects on a per singleton basis as well
|
42
|
+
|
43
|
+
- getters acts as setters if an argument is given to them
|
44
|
+
|
45
|
+
all this in < 100 lines of code
|
23
46
|
|
24
47
|
HISTORY
|
48
|
+
4.0.0
|
49
|
+
- removed dependancy on, and bundle of, pervasives
|
50
|
+
- faster. as fast as normal method definition.
|
51
|
+
- faster lookup for MyClass.attributes.include?('foobar')
|
52
|
+
|
25
53
|
3.7.0
|
26
54
|
small patch to use 'instance_variable_defined?' instead of defined?
|
27
55
|
keyword
|
@@ -42,8 +70,7 @@ SAMPLES
|
|
42
70
|
~ > cat samples/a.rb
|
43
71
|
|
44
72
|
#
|
45
|
-
# basic usage is like attr, but note that attribute defines
|
46
|
-
# getter, setter, and query
|
73
|
+
# basic usage is like attr, but note that attribute defines a suite of methods
|
47
74
|
#
|
48
75
|
require 'attributes'
|
49
76
|
|
@@ -53,16 +80,16 @@ SAMPLES
|
|
53
80
|
|
54
81
|
c = C.new
|
55
82
|
|
56
|
-
c.a = 42
|
57
|
-
p c.a
|
58
|
-
p 'forty-two' if c.a?
|
83
|
+
c.a = 42
|
84
|
+
p c.a #=> 42
|
85
|
+
p 'forty-two' if c.a? #=> 'forty-two'
|
59
86
|
|
60
87
|
#
|
61
|
-
#
|
88
|
+
# attributes works on object too
|
62
89
|
#
|
63
90
|
o = Object.new
|
64
91
|
o.attribute 'answer' => 42
|
65
|
-
p o.answer
|
92
|
+
p o.answer #=> 42
|
66
93
|
|
67
94
|
~ > ruby samples/a.rb
|
68
95
|
|
@@ -78,7 +105,9 @@ SAMPLES
|
|
78
105
|
#
|
79
106
|
# default values may be given either directly or as a block which will be
|
80
107
|
# evaluated in the context of self. in both cases (value or block) the
|
81
|
-
# default is set only once and only if needed - it's a lazy evaluation.
|
108
|
+
# default is set only once and only if needed - it's a lazy evaluation. the
|
109
|
+
# 'banger' method can be used to re-initialize a variable at any point whether
|
110
|
+
# or not it's already been initialized.
|
82
111
|
#
|
83
112
|
require 'attributes'
|
84
113
|
|
@@ -88,14 +117,20 @@ SAMPLES
|
|
88
117
|
end
|
89
118
|
|
90
119
|
c = C.new
|
120
|
+
p c.a #=> 42
|
121
|
+
p c.b #=> 42.0
|
91
122
|
|
92
|
-
|
93
|
-
p c.
|
123
|
+
c.a = 43
|
124
|
+
p c.a #=> 43
|
125
|
+
c.a!
|
126
|
+
p c.a #=> 42
|
94
127
|
|
95
128
|
~ > ruby samples/b.rb
|
96
129
|
|
97
130
|
42
|
98
131
|
42.0
|
132
|
+
43
|
133
|
+
42
|
99
134
|
|
100
135
|
|
101
136
|
<========< samples/c.rb >========>
|
@@ -113,7 +148,7 @@ SAMPLES
|
|
113
148
|
|
114
149
|
c = C.new
|
115
150
|
c.x = c.y + c.z
|
116
|
-
p c.x
|
151
|
+
p c.x #=> 42
|
117
152
|
|
118
153
|
~ > ruby samples/c.rb
|
119
154
|
|
@@ -191,5 +226,5 @@ SAMPLES
|
|
191
226
|
|
192
227
|
~ > ruby samples/e.rb
|
193
228
|
|
194
|
-
#<Config:
|
229
|
+
#<Config:0x20080 @port=80, @host="codeforpeople.org">
|
195
230
|
|
data/README.tmpl
CHANGED
@@ -11,17 +11,45 @@ URIS
|
|
11
11
|
SYNOPSIS
|
12
12
|
attributes.rb provides a set of attr_* like method with several user
|
13
13
|
friendly additions. attributes.rb is similar to the traits.rb package but
|
14
|
-
sacrifices a few features for simplicity of implementation
|
15
|
-
only 42 lines of code.
|
14
|
+
sacrifices a few features for simplicity of implementation.
|
16
15
|
|
17
|
-
the
|
16
|
+
the implementation of attributes.rb borrows many of the best ideas from the
|
18
17
|
metakoans.rb ruby quiz
|
19
18
|
|
20
19
|
http://www.rubyquiz.com/quiz67.html
|
21
20
|
|
22
|
-
in particular the solutions of Christian Neukirchen and Florian Gross
|
21
|
+
in particular the solutions of Christian Neukirchen and Florian Gross along
|
22
|
+
with concepts from the original traits lib
|
23
|
+
|
24
|
+
key features provided by attributes are
|
25
|
+
|
26
|
+
- ability to specify default values for attrs and definition time. values
|
27
|
+
can be literal objects or blocks, which are evaluated in the context of
|
28
|
+
self to initialize the variable
|
29
|
+
|
30
|
+
- classes remember which attributes they've defined and this information is
|
31
|
+
available to client code
|
32
|
+
|
33
|
+
- a whole suite of methods is defined by calls to #attributes including
|
34
|
+
getter, setter, query (var?) and banger (var! - which forces
|
35
|
+
re-initialization from the default value)
|
36
|
+
|
37
|
+
- ability to define multiple attributes at once using key => value pairs
|
38
|
+
|
39
|
+
- fast lookup of whether or not a class has defined a certain attribute
|
40
|
+
|
41
|
+
- attributes can be defined on objects on a per singleton basis as well
|
42
|
+
|
43
|
+
- getters acts as setters if an argument is given to them
|
44
|
+
|
45
|
+
all this in < 100 lines of code
|
23
46
|
|
24
47
|
HISTORY
|
48
|
+
4.0.0
|
49
|
+
- removed dependancy on, and bundle of, pervasives
|
50
|
+
- faster. as fast as normal method definition.
|
51
|
+
- faster lookup for MyClass.attributes.include?('foobar')
|
52
|
+
|
25
53
|
3.7.0
|
26
54
|
small patch to use 'instance_variable_defined?' instead of defined?
|
27
55
|
keyword
|
data/a.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'attributes'
|
2
|
+
|
3
|
+
module M
|
4
|
+
p(( attribute 'a' => 42 ))
|
5
|
+
p(( attribute('b'){ "forty-two (#{ self })" } ))
|
6
|
+
end
|
7
|
+
p M.attributes
|
8
|
+
p M.attributes.include?('a')
|
9
|
+
p M.attributes.include?('b')
|
10
|
+
p M.attributes.include?('c')
|
11
|
+
|
12
|
+
class C
|
13
|
+
include M
|
14
|
+
end
|
15
|
+
p C.new.a
|
16
|
+
p C.new.b
|
17
|
+
p C.attributes
|
18
|
+
p C.attributes.include?('a')
|
19
|
+
p C.attributes.include?('b')
|
20
|
+
p C.attributes.include?('c')
|
21
|
+
|
22
|
+
class B < C
|
23
|
+
end
|
24
|
+
p B.new.a
|
25
|
+
p B.new.b
|
26
|
+
p B.attributes
|
27
|
+
p B.attributes.include?('a')
|
28
|
+
p B.attributes.include?('b')
|
29
|
+
p B.attributes.include?('c')
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Attributes
|
2
|
+
Attributes::VERSION = '4.0.0' unless defined? Attributes::VERSION
|
3
|
+
def self.version() Attributes::VERSION end
|
4
|
+
|
5
|
+
class List < ::Array
|
6
|
+
def << element
|
7
|
+
super
|
8
|
+
self
|
9
|
+
ensure
|
10
|
+
uniq!
|
11
|
+
index!
|
12
|
+
end
|
13
|
+
def index!
|
14
|
+
@index ||= Hash.new
|
15
|
+
each{|element| @index[element] = true}
|
16
|
+
end
|
17
|
+
def include? element
|
18
|
+
@index ||= Hash.new
|
19
|
+
@index[element] ? true : false
|
20
|
+
end
|
21
|
+
def initializers
|
22
|
+
@initializers ||= Hash.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def attributes *a, &b
|
27
|
+
unless a.empty?
|
28
|
+
returned = Hash.new
|
29
|
+
|
30
|
+
hashes, names = a.partition{|x| Hash === x}
|
31
|
+
names_and_defaults = {}
|
32
|
+
hashes.each{|h| names_and_defaults.update h}
|
33
|
+
names.flatten.compact.each{|name| names_and_defaults.update name => nil}
|
34
|
+
|
35
|
+
initializers = __attributes__.initializers
|
36
|
+
|
37
|
+
names_and_defaults.each do |name, default|
|
38
|
+
raise NameError, "bad instance variable name '@#{ name }'" if "@#{ name }" =~ %r/[!?=]$/o
|
39
|
+
name = name.to_s
|
40
|
+
|
41
|
+
initialize = b || lambda { default }
|
42
|
+
initializer = lambda do |this|
|
43
|
+
Object.instance_method('instance_eval').bind(this).call &initialize
|
44
|
+
end
|
45
|
+
initializer_id = initializer.object_id
|
46
|
+
__attributes__.initializers[name] = initializer
|
47
|
+
|
48
|
+
module_eval <<-code
|
49
|
+
def #{ name }=(value)
|
50
|
+
@#{ name } = value
|
51
|
+
end
|
52
|
+
|
53
|
+
def #{ name }(*value)
|
54
|
+
return self.#{ name } = value.first unless value.empty?
|
55
|
+
#{ name }! unless defined? @#{ name }
|
56
|
+
@#{ name }
|
57
|
+
end
|
58
|
+
|
59
|
+
def #{ name }!
|
60
|
+
initializer = ObjectSpace._id2ref #{ initializer_id }
|
61
|
+
self.#{ name } = initializer.call(self)
|
62
|
+
@#{ name }
|
63
|
+
end
|
64
|
+
|
65
|
+
def #{ name }?
|
66
|
+
defined? @#{ name } and #{ name }
|
67
|
+
end
|
68
|
+
code
|
69
|
+
|
70
|
+
attributes << name
|
71
|
+
returned[name] = initializer
|
72
|
+
end
|
73
|
+
|
74
|
+
returned
|
75
|
+
else
|
76
|
+
begin
|
77
|
+
__attribute_list__
|
78
|
+
rescue NameError
|
79
|
+
singleton_class =
|
80
|
+
class << self
|
81
|
+
self
|
82
|
+
end
|
83
|
+
klass = self
|
84
|
+
singleton_class.module_eval do
|
85
|
+
attribute_list = List.new
|
86
|
+
define_method('attribute_list'){ klass == self ? attribute_list : raise(NameError) }
|
87
|
+
alias_method '__attribute_list__', 'attribute_list'
|
88
|
+
end
|
89
|
+
__attribute_list__
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
%w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
|
95
|
+
end
|
96
|
+
|
97
|
+
class Object
|
98
|
+
def attributes *a, &b
|
99
|
+
sc =
|
100
|
+
class << self
|
101
|
+
self
|
102
|
+
end
|
103
|
+
sc.attributes *a, &b
|
104
|
+
end
|
105
|
+
%w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
|
106
|
+
end
|
107
|
+
|
108
|
+
class Module
|
109
|
+
include Attributes
|
110
|
+
end
|
data/lib/attributes.rb
CHANGED
@@ -1,46 +1,77 @@
|
|
1
1
|
module Attributes
|
2
|
-
VERSION = '
|
3
|
-
def self.version() VERSION end
|
2
|
+
Attributes::VERSION = '4.0.0' unless defined? Attributes::VERSION
|
3
|
+
def self.version() Attributes::VERSION end
|
4
|
+
|
5
|
+
class List < ::Array
|
6
|
+
def << element
|
7
|
+
super
|
8
|
+
self
|
9
|
+
ensure
|
10
|
+
uniq!
|
11
|
+
index!
|
12
|
+
end
|
13
|
+
def index!
|
14
|
+
@index ||= Hash.new
|
15
|
+
each{|element| @index[element] = true}
|
16
|
+
end
|
17
|
+
def include? element
|
18
|
+
@index ||= Hash.new
|
19
|
+
@index[element] ? true : false
|
20
|
+
end
|
21
|
+
def initializers
|
22
|
+
@initializers ||= Hash.new
|
23
|
+
end
|
24
|
+
end
|
4
25
|
|
5
26
|
def attributes *a, &b
|
6
27
|
unless a.empty?
|
7
|
-
|
28
|
+
returned = Hash.new
|
8
29
|
|
30
|
+
hashes, names = a.partition{|x| Hash === x}
|
9
31
|
names_and_defaults = {}
|
10
32
|
hashes.each{|h| names_and_defaults.update h}
|
11
33
|
names.flatten.compact.each{|name| names_and_defaults.update name => nil}
|
12
34
|
|
13
|
-
|
14
|
-
init = b || lambda { default }
|
15
|
-
ivar, getter, setter, query, banger =
|
16
|
-
"@#{ name }", "#{ name }", "#{ name }=", "#{ name }?", "#{ name }!"
|
35
|
+
initializers = __attributes__.initializers
|
17
36
|
|
18
|
-
|
37
|
+
names_and_defaults.each do |name, default|
|
38
|
+
raise NameError, "bad instance variable name '@#{ name }'" if "@#{ name }" =~ %r/[!?=]$/o
|
39
|
+
name = name.to_s
|
19
40
|
|
20
|
-
|
21
|
-
|
41
|
+
initialize = b || lambda { default }
|
42
|
+
initializer = lambda do |this|
|
43
|
+
Object.instance_method('instance_eval').bind(this).call &initialize
|
22
44
|
end
|
45
|
+
initializer_id = initializer.object_id
|
46
|
+
__attributes__.initializers[name] = initializer
|
23
47
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
else
|
28
|
-
defined = __pervasive__('instance_variable_defined?', "#{ ivar }")
|
29
|
-
__pervasive__('send', setter, __pervasive__('instance_eval', &init)) unless defined
|
30
|
-
__pervasive__('instance_variable_get', ivar)
|
48
|
+
module_eval <<-code
|
49
|
+
def #{ name }=(value)
|
50
|
+
@#{ name } = value
|
31
51
|
end
|
32
|
-
end
|
33
52
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
53
|
+
def #{ name }(*value)
|
54
|
+
return self.#{ name } = value.first unless value.empty?
|
55
|
+
#{ name }! unless defined? @#{ name }
|
56
|
+
@#{ name }
|
57
|
+
end
|
58
|
+
|
59
|
+
def #{ name }!
|
60
|
+
initializer = ObjectSpace._id2ref #{ initializer_id }
|
61
|
+
self.#{ name } = initializer.call(self)
|
62
|
+
@#{ name }
|
63
|
+
end
|
38
64
|
|
39
|
-
|
65
|
+
def #{ name }?
|
66
|
+
defined? @#{ name } and #{ name }
|
67
|
+
end
|
68
|
+
code
|
40
69
|
|
41
|
-
|
42
|
-
|
70
|
+
attributes << name
|
71
|
+
returned[name] = initializer
|
43
72
|
end
|
73
|
+
|
74
|
+
returned
|
44
75
|
else
|
45
76
|
begin
|
46
77
|
__attribute_list__
|
@@ -51,7 +82,7 @@ module Attributes
|
|
51
82
|
end
|
52
83
|
klass = self
|
53
84
|
singleton_class.module_eval do
|
54
|
-
attribute_list =
|
85
|
+
attribute_list = List.new
|
55
86
|
define_method('attribute_list'){ klass == self ? attribute_list : raise(NameError) }
|
56
87
|
alias_method '__attribute_list__', 'attribute_list'
|
57
88
|
end
|
@@ -77,47 +108,3 @@ end
|
|
77
108
|
class Module
|
78
109
|
include Attributes
|
79
110
|
end
|
80
|
-
|
81
|
-
BEGIN {
|
82
|
-
unless defined? Pervasives
|
83
|
-
begin
|
84
|
-
require 'pervasives'
|
85
|
-
rescue LoadError
|
86
|
-
module Pervasives
|
87
|
-
VERSION = "1.0.0"
|
88
|
-
def self.version() VERSION end
|
89
|
-
class ::Class
|
90
|
-
def __pervasive__ m, *a, &b
|
91
|
-
(( Class.instance_method(m) rescue
|
92
|
-
Module.instance_method(m) rescue
|
93
|
-
Object.instance_method(m) )).bind(self).call(*a, &b)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
class ::Module
|
97
|
-
def __pervasive__ m, *a, &b
|
98
|
-
(( Module.instance_method(m) rescue
|
99
|
-
Object.instance_method(m) )).bind(self).call(*a, &b)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
class ::Object
|
103
|
-
def __pervasive__ m, *a, &b
|
104
|
-
(( Object.instance_method(m) )).bind(self).call(*a, &b)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
class Proxy
|
109
|
-
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
110
|
-
def initialize obj
|
111
|
-
@obj = obj
|
112
|
-
end
|
113
|
-
def method_missing m, *a, &b
|
114
|
-
@obj.__pervasive__ m, *a, &b
|
115
|
-
end
|
116
|
-
def __obj__
|
117
|
-
@obj
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
}
|
data/samples/a.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# basic usage is like attr, but note that attribute defines
|
3
|
-
# getter, setter, and query
|
2
|
+
# basic usage is like attr, but note that attribute defines a suite of methods
|
4
3
|
#
|
5
4
|
require 'attributes'
|
6
5
|
|
@@ -10,13 +9,13 @@
|
|
10
9
|
|
11
10
|
c = C.new
|
12
11
|
|
13
|
-
c.a = 42
|
14
|
-
p c.a
|
15
|
-
p 'forty-two' if c.a?
|
12
|
+
c.a = 42
|
13
|
+
p c.a #=> 42
|
14
|
+
p 'forty-two' if c.a? #=> 'forty-two'
|
16
15
|
|
17
16
|
#
|
18
|
-
#
|
17
|
+
# attributes works on object too
|
19
18
|
#
|
20
19
|
o = Object.new
|
21
20
|
o.attribute 'answer' => 42
|
22
|
-
p o.answer
|
21
|
+
p o.answer #=> 42
|
data/samples/b.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
#
|
2
2
|
# default values may be given either directly or as a block which will be
|
3
3
|
# evaluated in the context of self. in both cases (value or block) the
|
4
|
-
# default is set only once and only if needed - it's a lazy evaluation.
|
4
|
+
# default is set only once and only if needed - it's a lazy evaluation. the
|
5
|
+
# 'banger' method can be used to re-initialize a variable at any point whether
|
6
|
+
# or not it's already been initialized.
|
5
7
|
#
|
6
8
|
require 'attributes'
|
7
9
|
|
@@ -11,6 +13,10 @@
|
|
11
13
|
end
|
12
14
|
|
13
15
|
c = C.new
|
16
|
+
p c.a #=> 42
|
17
|
+
p c.b #=> 42.0
|
14
18
|
|
15
|
-
|
16
|
-
p c.
|
19
|
+
c.a = 43
|
20
|
+
p c.a #=> 43
|
21
|
+
c.a!
|
22
|
+
p c.a #=> 42
|
data/samples/c.rb
CHANGED
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: attributes
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version:
|
7
|
-
date: 2007-
|
6
|
+
version: 4.0.0
|
7
|
+
date: 2007-10-10 00:00:00 -06:00
|
8
8
|
summary: attributes
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,11 +29,12 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- Ara T. Howard
|
31
31
|
files:
|
32
|
+
- a.rb
|
32
33
|
- gemspec.rb
|
33
34
|
- gen_readme.rb
|
34
35
|
- install.rb
|
35
36
|
- lib
|
36
|
-
- lib/attributes-
|
37
|
+
- lib/attributes-4.0.0.rb
|
37
38
|
- lib/attributes.rb
|
38
39
|
- README
|
39
40
|
- README.tmpl
|
data/lib/attributes-3.7.0.rb
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
module Attributes
|
2
|
-
VERSION = '3.7.0'
|
3
|
-
def self.version() VERSION end
|
4
|
-
|
5
|
-
def attributes *a, &b
|
6
|
-
unless a.empty?
|
7
|
-
hashes, names = a.partition{|x| Hash === x}
|
8
|
-
|
9
|
-
names_and_defaults = {}
|
10
|
-
hashes.each{|h| names_and_defaults.update h}
|
11
|
-
names.flatten.compact.each{|name| names_and_defaults.update name => nil}
|
12
|
-
|
13
|
-
names_and_defaults.each do |name, default|
|
14
|
-
init = b || lambda { default }
|
15
|
-
ivar, getter, setter, query, banger =
|
16
|
-
"@#{ name }", "#{ name }", "#{ name }=", "#{ name }?", "#{ name }!"
|
17
|
-
|
18
|
-
raise NameError, "bad instance variable name '#{ ivar }'" if ivar =~ %r/[!?=]$/o
|
19
|
-
|
20
|
-
define_method(setter) do |value|
|
21
|
-
__pervasive__('instance_variable_set', ivar, value)
|
22
|
-
end
|
23
|
-
|
24
|
-
define_method(getter) do |*value|
|
25
|
-
unless value.empty?
|
26
|
-
__pervasive__('send', setter, value.shift)
|
27
|
-
else
|
28
|
-
defined = __pervasive__('instance_variable_defined?', "#{ ivar }")
|
29
|
-
__pervasive__('send', setter, __pervasive__('instance_eval', &init)) unless defined
|
30
|
-
__pervasive__('instance_variable_get', ivar)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
define_method(banger) do
|
35
|
-
__pervasive__('send', setter, __pervasive__('instance_eval', &init))
|
36
|
-
__pervasive__('instance_variable_get', ivar)
|
37
|
-
end
|
38
|
-
|
39
|
-
alias_method query, getter
|
40
|
-
|
41
|
-
(attributes << name.to_s).uniq!
|
42
|
-
attributes
|
43
|
-
end
|
44
|
-
else
|
45
|
-
begin
|
46
|
-
__attribute_list__
|
47
|
-
rescue NameError
|
48
|
-
singleton_class =
|
49
|
-
class << self
|
50
|
-
self
|
51
|
-
end
|
52
|
-
klass = self
|
53
|
-
singleton_class.module_eval do
|
54
|
-
attribute_list = []
|
55
|
-
define_method('attribute_list'){ klass == self ? attribute_list : raise(NameError) }
|
56
|
-
alias_method '__attribute_list__', 'attribute_list'
|
57
|
-
end
|
58
|
-
__attribute_list__
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
%w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
|
64
|
-
end
|
65
|
-
|
66
|
-
class Object
|
67
|
-
def attributes *a, &b
|
68
|
-
sc =
|
69
|
-
class << self
|
70
|
-
self
|
71
|
-
end
|
72
|
-
sc.attributes *a, &b
|
73
|
-
end
|
74
|
-
%w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
|
75
|
-
end
|
76
|
-
|
77
|
-
class Module
|
78
|
-
include Attributes
|
79
|
-
end
|
80
|
-
|
81
|
-
BEGIN {
|
82
|
-
unless defined? Pervasives
|
83
|
-
begin
|
84
|
-
require 'pervasives'
|
85
|
-
rescue LoadError
|
86
|
-
module Pervasives
|
87
|
-
VERSION = "1.0.0"
|
88
|
-
def self.version() VERSION end
|
89
|
-
class ::Class
|
90
|
-
def __pervasive__ m, *a, &b
|
91
|
-
(( Class.instance_method(m) rescue
|
92
|
-
Module.instance_method(m) rescue
|
93
|
-
Object.instance_method(m) )).bind(self).call(*a, &b)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
class ::Module
|
97
|
-
def __pervasive__ m, *a, &b
|
98
|
-
(( Module.instance_method(m) rescue
|
99
|
-
Object.instance_method(m) )).bind(self).call(*a, &b)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
class ::Object
|
103
|
-
def __pervasive__ m, *a, &b
|
104
|
-
(( Object.instance_method(m) )).bind(self).call(*a, &b)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
class Proxy
|
109
|
-
instance_methods.each{|m| undef_method m unless m[%r/__/]}
|
110
|
-
def initialize obj
|
111
|
-
@obj = obj
|
112
|
-
end
|
113
|
-
def method_missing m, *a, &b
|
114
|
-
@obj.__pervasive__ m, *a, &b
|
115
|
-
end
|
116
|
-
def __obj__
|
117
|
-
@obj
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
}
|