attributes 3.7.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
}
|