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.
@@ -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
- constructor
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'
@@ -1,4 +1,4 @@
1
- CONSTRUCTOR_VERSION = '1.0.1' #:nodoc:#
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
- self.class_eval "attr_accessor " + attrs.map {|x| ":#{x.to_s}"}.join(',')
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
@@ -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
- constructor :computer, :accessors => true
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.1
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: 2008-05-08 00:00:00 -04:00
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: 1.5.1
23
+ version: 2.3.3
23
24
  version:
24
- description: "== DESCRIPTION: Declarative means to define object properties by passing a hash to the constructor, which will set the corresponding ivars."
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/projects/atomicobjectrb/
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.1.1
71
+ rubygems_version: 1.3.5
65
72
  signing_key:
66
- specification_version: 2
73
+ specification_version: 3
67
74
  summary: Declarative, named constructor arguments.
68
75
  test_files: []
69
76