constructor 1.0.1 → 1.0.2
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/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
|
|