constructor 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/README.txt +2 -6
- data/lib/constructor.rb +12 -2
- data/specs/constructor_spec.rb +75 -1
- metadata +14 -7
data/History.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
== 1.0.2 / 2008-05-07
|
2
|
+
|
3
|
+
* An error is raised when constructor keys are passed in that already exist in the super class
|
4
|
+
|
1
5
|
== 1.0.1 / 2007-12-21
|
2
6
|
|
3
7
|
* You can now pass a block to your constructor call; it gets executed after all the ivars get assigned. (This lets you write some initializer code if you need to.)
|
data/README.txt
CHANGED
@@ -1,17 +1,13 @@
|
|
1
|
-
|
1
|
+
== Constructor
|
2
2
|
|
3
|
-
* http://rubyforge.org/projects/atomicobjectrb/
|
4
3
|
* http://atomicobjectrb.rubyforge.org/constructor
|
4
|
+
* http://rubyforge.org/projects/atomicobjectrb/
|
5
5
|
|
6
6
|
== DESCRIPTION:
|
7
7
|
|
8
8
|
Declarative means to define object properties by passing a hash
|
9
9
|
to the constructor, which will set the corresponding ivars.
|
10
10
|
|
11
|
-
== FEATURES/PROBLEMS:
|
12
|
-
|
13
|
-
* Declarative constructor definition and ivar initialization
|
14
|
-
|
15
11
|
== SYNOPSIS:
|
16
12
|
|
17
13
|
require 'constructor'
|
data/lib/constructor.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
CONSTRUCTOR_VERSION = '1.0.
|
1
|
+
CONSTRUCTOR_VERSION = '1.0.2' #:nodoc:#
|
2
2
|
|
3
3
|
class Class #:nodoc:#
|
4
4
|
def constructor(*attrs, &block)
|
@@ -10,11 +10,14 @@ class Class #:nodoc:#
|
|
10
10
|
# Look for embedded options in the listing:
|
11
11
|
opts = attrs.find { |a| a.kind_of?(Hash) and attrs.delete(a) }
|
12
12
|
do_acc = opts.nil? ? false : opts[:accessors] == true
|
13
|
+
do_reader = opts.nil? ? false : opts[:readers] == true
|
13
14
|
require_args = opts.nil? ? true : opts[:strict] != false
|
14
15
|
super_args = opts.nil? ? nil : opts[:super]
|
15
16
|
|
16
17
|
# Incorporate superclass's constructor keys, if our superclass
|
17
18
|
if superclass.constructor_keys
|
19
|
+
similar_keys = superclass.constructor_keys & attrs
|
20
|
+
raise "Base class already has keys #{similar_keys.inspect}" unless similar_keys.empty?
|
18
21
|
attrs = [attrs,superclass.constructor_keys].flatten
|
19
22
|
end
|
20
23
|
# Generate ivar assigner code lines
|
@@ -25,9 +28,16 @@ class Class #:nodoc:#
|
|
25
28
|
|
26
29
|
# If accessors option is on, declare accessors for the attributes:
|
27
30
|
if do_acc
|
28
|
-
|
31
|
+
add_accessors = "attr_accessor " + attrs.reject {|x| superclass.constructor_keys.include?(x.to_sym)}.map {|x| ":#{x.to_s}"}.join(',')
|
32
|
+
#add_accessors = "attr_accessor " + attrs.map {|x| ":#{x.to_s}"}.join(',')
|
33
|
+
self.class_eval add_accessors
|
29
34
|
end
|
30
35
|
|
36
|
+
# If readers option is on, declare readers for the attributes:
|
37
|
+
if do_reader
|
38
|
+
self.class_eval "attr_reader " + attrs.reject {|x| superclass.constructor_keys.include?(x.to_sym)}.map {|x| ":#{x.to_s}"}.join(',')
|
39
|
+
end
|
40
|
+
|
31
41
|
# If user supplied super-constructor hints:
|
32
42
|
super_call = ''
|
33
43
|
if super_args
|
data/specs/constructor_spec.rb
CHANGED
@@ -46,6 +46,31 @@ describe "constructor's accessor option" do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
describe "constructor's reader option" do
|
50
|
+
it 'provides readers for constructor arguments when reader option is true' do
|
51
|
+
fuh = TestingAutoReaders.new(
|
52
|
+
:foo => 'my foo',
|
53
|
+
:why => 'lucky'
|
54
|
+
)
|
55
|
+
fuh.foo.should eql('my foo')
|
56
|
+
fuh.why.should eql('lucky')
|
57
|
+
fuh.to_pretty_pretty.should eql('my foo lucky')
|
58
|
+
|
59
|
+
lambda {fuh.why = 'no way'}.should raise_error(NoMethodError)
|
60
|
+
lambda {fuh.foo = 'uh uh'}.should raise_error(NoMethodError)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does not provide reader for constructor arguments when reader option is false' do
|
64
|
+
fuh = TestingBlockedReaders.new :foo => 'my foo', :why => 'my why'
|
65
|
+
lambda {fuh.foo}.should raise_error(NoMethodError)
|
66
|
+
lambda {fuh.bar}.should raise_error(NoMethodError)
|
67
|
+
fuh.to_pretty_pretty.should eql('my foo my why')
|
68
|
+
|
69
|
+
lambda {fuh.why = 'no way'}.should raise_error(NoMethodError)
|
70
|
+
lambda {fuh.foo = 'uh uh'}.should raise_error(NoMethodError)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
49
74
|
describe 'using constructor with inheritance' do
|
50
75
|
it 'allows for inheritance of constructor arguments using a non-constructor defined subclass' do
|
51
76
|
fuh = SubclassOfTestingClass.new :foo => 'whu?'
|
@@ -116,6 +141,22 @@ describe 'using constructor with inheritance' do
|
|
116
141
|
tsc.c.should eql('what a')
|
117
142
|
tsc.d.should eql('day for')
|
118
143
|
end
|
144
|
+
|
145
|
+
it "raises an error if subclass tries to build a constructor with the keys as its parents" do
|
146
|
+
class1 = constructor_class(Object, :star, :wars)
|
147
|
+
class2 = constructor_class(class1, :space, :balls)
|
148
|
+
lambda { constructor_class(class2, :star, :space, :chewy) }.should raise_error("Base class already has keys [:space, :star]")
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'does not create accessors for superclass constructor arguments' do
|
152
|
+
tas = TestingAccessorSubclass.new(:far => 'thing')
|
153
|
+
tas.respond_to?(:cuteness).should be_false
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'does not create a reader for superclass constructor arguments' do
|
157
|
+
t1 = TestingReaderSubclass.new(:foo => 'thing')
|
158
|
+
t1.respond_to?(:foo).should be_false
|
159
|
+
end
|
119
160
|
end
|
120
161
|
|
121
162
|
describe 'stict mode usage' do
|
@@ -208,6 +249,12 @@ describe 'block yielding' do
|
|
208
249
|
end
|
209
250
|
end
|
210
251
|
|
252
|
+
def constructor_class(base, *keys)
|
253
|
+
Class.new(base) do
|
254
|
+
constructor *keys
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
211
258
|
class TestingClass
|
212
259
|
attr_accessor :foo, :bar, :why, :qux
|
213
260
|
constructor :foo, :bar, :why, :qux, :strict => false
|
@@ -279,6 +326,21 @@ class TestingAutoAccessors
|
|
279
326
|
end
|
280
327
|
end
|
281
328
|
|
329
|
+
class TestingAutoReaders
|
330
|
+
constructor :foo, :why, :readers => true, :strict => false
|
331
|
+
def to_pretty_pretty
|
332
|
+
"#{@foo} #{@why}"
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
class TestingReaderSuperclass
|
337
|
+
constructor :foo
|
338
|
+
end
|
339
|
+
|
340
|
+
class TestingReaderSubclass < TestingReaderSuperclass
|
341
|
+
constructor :bar, :readers => true, :strict => false
|
342
|
+
end
|
343
|
+
|
282
344
|
class TestingSuperConstructorBase
|
283
345
|
attr_reader :a, :b
|
284
346
|
def initialize(a,b)
|
@@ -303,6 +365,10 @@ class TestingSuperConstructor2 < TestingSuperConstructorBase2
|
|
303
365
|
constructor :some, :accessors => true, :super => [], :strict => false
|
304
366
|
end
|
305
367
|
|
368
|
+
class TestingAccessorSubclass < Baby
|
369
|
+
constructor :foo, :accessors => true, :strict => false
|
370
|
+
end
|
371
|
+
|
306
372
|
class TestingBlockedAccessors
|
307
373
|
constructor :foo, :bar, :accessors => false
|
308
374
|
def to_pretty_pretty
|
@@ -310,12 +376,20 @@ class TestingBlockedAccessors
|
|
310
376
|
end
|
311
377
|
end
|
312
378
|
|
379
|
+
class TestingBlockedReaders
|
380
|
+
constructor :foo, :why, :readers => false
|
381
|
+
def to_pretty_pretty
|
382
|
+
"#{@foo} #{@why}"
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
313
386
|
class Papa
|
314
387
|
constructor :car, :saw
|
315
388
|
end
|
316
389
|
|
317
390
|
class Sonny < Papa
|
318
|
-
|
391
|
+
attr_accessor :car, :saw, :computer
|
392
|
+
constructor :computer
|
319
393
|
end
|
320
394
|
|
321
395
|
class Llamma
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: constructor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Atomic Object
|
@@ -9,19 +9,24 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-11-01 01:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hoe
|
17
|
+
type: :development
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - ">="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
23
|
+
version: 2.3.3
|
23
24
|
version:
|
24
|
-
description:
|
25
|
+
description: |-
|
26
|
+
== DESCRIPTION:
|
27
|
+
|
28
|
+
Declarative means to define object properties by passing a hash
|
29
|
+
to the constructor, which will set the corresponding ivars.
|
25
30
|
email: dev@atomicobject.com
|
26
31
|
executables: []
|
27
32
|
|
@@ -39,7 +44,9 @@ files:
|
|
39
44
|
- lib/constructor.rb
|
40
45
|
- specs/constructor_spec.rb
|
41
46
|
has_rdoc: true
|
42
|
-
homepage: http://rubyforge.org/
|
47
|
+
homepage: http://atomicobjectrb.rubyforge.org/constructor
|
48
|
+
licenses: []
|
49
|
+
|
43
50
|
post_install_message:
|
44
51
|
rdoc_options:
|
45
52
|
- --main
|
@@ -61,9 +68,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
68
|
requirements: []
|
62
69
|
|
63
70
|
rubyforge_project: atomicobjectrb
|
64
|
-
rubygems_version: 1.
|
71
|
+
rubygems_version: 1.3.5
|
65
72
|
signing_key:
|
66
|
-
specification_version:
|
73
|
+
specification_version: 3
|
67
74
|
summary: Declarative, named constructor arguments.
|
68
75
|
test_files: []
|
69
76
|
|