constructor 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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