sam-dm-core 0.9.10 → 0.9.11

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.
Files changed (55) hide show
  1. data/.gitignore +18 -0
  2. data/History.txt +10 -0
  3. data/MIT-LICENSE +1 -1
  4. data/Rakefile +4 -4
  5. data/dm-core.gemspec +40 -0
  6. data/lib/dm-core.rb +1 -1
  7. data/lib/dm-core/adapters/data_objects_adapter.rb +2 -2
  8. data/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  9. data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
  10. data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
  11. data/lib/dm-core/adapters/sqlite3_adapter.rb +1 -1
  12. data/lib/dm-core/associations/many_to_one.rb +1 -1
  13. data/lib/dm-core/associations/one_to_many.rb +18 -18
  14. data/lib/dm-core/associations/relationship.rb +9 -3
  15. data/lib/dm-core/associations/relationship_chain.rb +1 -1
  16. data/lib/dm-core/collection.rb +3 -3
  17. data/lib/dm-core/model.rb +5 -4
  18. data/lib/dm-core/resource.rb +11 -5
  19. data/lib/dm-core/version.rb +1 -1
  20. data/script/all +3 -4
  21. data/spec/integration/association_spec.rb +18 -18
  22. data/spec/integration/association_through_spec.rb +4 -4
  23. data/spec/integration/associations/many_to_many_spec.rb +9 -9
  24. data/spec/integration/associations/many_to_one_spec.rb +1 -1
  25. data/spec/integration/associations/one_to_many_spec.rb +3 -3
  26. data/spec/integration/collection_spec.rb +2 -2
  27. data/spec/integration/dependency_queue_spec.rb +1 -1
  28. data/spec/integration/model_spec.rb +1 -1
  29. data/spec/integration/mysql_adapter_spec.rb +1 -1
  30. data/spec/integration/postgres_adapter_spec.rb +16 -16
  31. data/spec/integration/property_spec.rb +10 -6
  32. data/spec/integration/query_spec.rb +4 -4
  33. data/spec/integration/repository_spec.rb +1 -1
  34. data/spec/integration/sqlite3_adapter_spec.rb +7 -7
  35. data/spec/integration/sti_spec.rb +6 -6
  36. data/spec/integration/strategic_eager_loading_spec.rb +14 -11
  37. data/spec/integration/type_spec.rb +10 -6
  38. data/spec/lib/logging_helper.rb +11 -11
  39. data/spec/models/content.rb +16 -0
  40. data/spec/spec_helper.rb +8 -4
  41. data/spec/unit/adapters/data_objects_adapter_spec.rb +9 -5
  42. data/spec/unit/adapters/in_memory_adapter_spec.rb +98 -0
  43. data/spec/unit/adapters/postgres_adapter_spec.rb +5 -5
  44. data/spec/unit/associations/many_to_many_spec.rb +2 -2
  45. data/spec/unit/associations/many_to_one_spec.rb +3 -3
  46. data/spec/unit/associations/one_to_many_spec.rb +2 -2
  47. data/spec/unit/associations/relationship_spec.rb +6 -6
  48. data/spec/unit/associations_spec.rb +21 -21
  49. data/spec/unit/identity_map_spec.rb +3 -3
  50. data/spec/unit/is_spec.rb +7 -7
  51. data/spec/unit/property_spec.rb +7 -7
  52. data/spec/unit/resource_spec.rb +12 -12
  53. data/spec/unit/transaction_spec.rb +1 -1
  54. data/tasks/dm.rb +1 -1
  55. metadata +10 -5
@@ -25,7 +25,7 @@ if HAS_POSTGRES
25
25
  @adapter.stub!(:query).and_return([ 0 ])
26
26
 
27
27
  @original_method = @adapter.class.superclass.instance_method(:upgrade_model_storage)
28
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) {}
28
+ @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { |repository, model| }
29
29
  end
30
30
 
31
31
  after do
@@ -49,7 +49,7 @@ if HAS_POSTGRES
49
49
 
50
50
  it 'should execute the superclass upgrade_model_storage' do
51
51
  rv = mock('inside super')
52
- @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { rv }
52
+ @adapter.class.superclass.send(:define_method, :upgrade_model_storage) { |repository, model| rv }
53
53
  @adapter.upgrade_model_storage(@repository, @model).should == rv
54
54
  end
55
55
  end
@@ -91,7 +91,7 @@ if HAS_POSTGRES
91
91
 
92
92
  it 'should execute the superclass upgrade_model_storage' do
93
93
  rv = mock('inside super')
94
- @adapter.class.superclass.send(:define_method, :create_table_statement) { rv }
94
+ @adapter.class.superclass.send(:define_method, :create_table_statement) { |repository, model| rv }
95
95
  @adapter.create_table_statement(@repository, @model).should == rv
96
96
  end
97
97
  end
@@ -117,13 +117,13 @@ if HAS_POSTGRES
117
117
 
118
118
  it 'should not execute the superclass destroy_model_storage if the storage does not exist' do
119
119
  rv = mock('inside super')
120
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) { rv }
120
+ @adapter.class.superclass.send(:define_method, :destroy_model_storage) { |repository, model| rv }
121
121
  @adapter.destroy_model_storage(@repository, @model).should_not == rv
122
122
  end
123
123
 
124
124
  it 'should execute the superclass destroy_model_storage if the storage exists' do
125
125
  rv = mock('inside super')
126
- @adapter.class.superclass.send(:define_method, :destroy_model_storage) { rv }
126
+ @adapter.class.superclass.send(:define_method, :destroy_model_storage) { |repository, model| rv }
127
127
  @adapter.stub!(:storage_exists?).and_return(true)
128
128
 
129
129
  @adapter.destroy_model_storage(@repository, @model).should == rv
@@ -6,7 +6,7 @@ describe DataMapper::Associations::ManyToMany do
6
6
 
7
7
  it 'should allow a declaration' do
8
8
  lambda do
9
- class Supplier
9
+ class ::Supplier
10
10
  has n, :manufacturers, :through => Resource
11
11
  end
12
12
  end.should_not raise_error
@@ -14,7 +14,7 @@ describe DataMapper::Associations::ManyToMany do
14
14
 
15
15
  it 'should handle models inside modules' do
16
16
  lambda do
17
- module Content
17
+ module ::Content
18
18
  class Dialect
19
19
  has n, :locales, :through => Resource, :class_name => "Language::Locale"
20
20
  end
@@ -6,7 +6,7 @@ describe DataMapper::Associations::ManyToOne do
6
6
 
7
7
  it 'should allow a declaration' do
8
8
  lambda do
9
- class Vehicle
9
+ class ::Vehicle
10
10
  belongs_to :manufacturer
11
11
  end
12
12
  end.should_not raise_error
@@ -102,7 +102,7 @@ describe DataMapper::Associations::ManyToOne::Proxy do
102
102
  end
103
103
 
104
104
  it 'should save the parent' do
105
- @relationship.should_receive(:with_repository).and_yield(@repository)
105
+ @relationship.should_receive(:with_repository).and_yield
106
106
  @parent.should_receive(:save).with(no_args)
107
107
  @association.save
108
108
  end
@@ -112,7 +112,7 @@ describe DataMapper::Associations::ManyToOne::Proxy do
112
112
  child_key.should_receive(:set).and_return(true)
113
113
  parent_key = mock("parent_key")
114
114
  parent_key.should_receive(:get).and_return(1)
115
- @relationship.should_receive(:with_repository).and_yield(@repository)
115
+ @relationship.should_receive(:with_repository).and_yield
116
116
  @relationship.should_receive(:child_key).and_return(child_key)
117
117
  @relationship.should_receive(:parent_key).and_return(parent_key)
118
118
  save_results = mock('save results')
@@ -85,11 +85,11 @@ describe DataMapper::Associations::OneToMany do
85
85
 
86
86
  describe 'proxy accessor' do
87
87
  before :all do
88
- class User
88
+ class ::User
89
89
  include DataMapper::Resource
90
90
  end
91
91
 
92
- class Order
92
+ class ::Order
93
93
  include DataMapper::Resource
94
94
  end
95
95
  end
@@ -8,8 +8,8 @@ describe DataMapper::Associations::Relationship do
8
8
  belongs_to = DataMapper::Associations::Relationship.new(
9
9
  :manufacturer,
10
10
  :mock,
11
- 'Vehicle',
12
- 'Manufacturer',
11
+ Vehicle,
12
+ Manufacturer,
13
13
  { :child_key => [ :manufacturer_id ] }
14
14
  )
15
15
 
@@ -23,8 +23,8 @@ describe DataMapper::Associations::Relationship do
23
23
  belongs_to = DataMapper::Associations::Relationship.new(
24
24
  :manufacturer,
25
25
  :mock,
26
- 'Vehicle',
27
- 'Manufacturer',
26
+ Vehicle,
27
+ Manufacturer,
28
28
  { :child_key => [ :manufacturer_id ], :parent_key => [ :id ] }
29
29
  )
30
30
 
@@ -44,8 +44,8 @@ describe DataMapper::Associations::Relationship do
44
44
  has_many = DataMapper::Associations::Relationship.new(
45
45
  :models,
46
46
  :mock,
47
- 'Vehicle',
48
- 'Manufacturer',
47
+ Vehicle,
48
+ Manufacturer,
49
49
  { :child_key => [:model_id] }
50
50
  )
51
51
 
@@ -13,7 +13,7 @@ describe "DataMapper::Associations" do
13
13
 
14
14
  describe "#many_to_one_relationships" do
15
15
  before :all do
16
- module MTORelationships
16
+ module ::MTORelationships
17
17
  class A
18
18
  include DataMapper::Resource
19
19
  def self.default_repository_name
@@ -46,11 +46,11 @@ describe "DataMapper::Associations" do
46
46
  end
47
47
 
48
48
  describe ".relationships" do
49
- class B
49
+ class ::B
50
50
  include DataMapper::Resource
51
51
  end
52
52
 
53
- class C
53
+ class ::C
54
54
  include DataMapper::Resource
55
55
 
56
56
  repository(:mock) do
@@ -58,15 +58,15 @@ describe "DataMapper::Associations" do
58
58
  end
59
59
  end
60
60
 
61
- class D
61
+ class ::D
62
62
  include DataMapper::Resource
63
63
  has 1, :b
64
64
  end
65
65
 
66
- class E < D
66
+ class ::E < D
67
67
  end
68
68
 
69
- class F < D
69
+ class ::F < D
70
70
  has 1, :a
71
71
  end
72
72
 
@@ -92,7 +92,7 @@ describe "DataMapper::Associations" do
92
92
 
93
93
  it "should allow a declaration" do
94
94
  lambda do
95
- class Manufacturer
95
+ class ::Manufacturer
96
96
  has 1, :halo_car
97
97
  end
98
98
  end.should_not raise_error
@@ -100,7 +100,7 @@ describe "DataMapper::Associations" do
100
100
 
101
101
  it "should not allow a constraint that is not an Integer, Range or Infinity" do
102
102
  lambda do
103
- class Manufacturer
103
+ class ::Manufacturer
104
104
  has '1', :halo_car
105
105
  end
106
106
  end.should raise_error(ArgumentError)
@@ -108,7 +108,7 @@ describe "DataMapper::Associations" do
108
108
 
109
109
  it "should not allow a constraint where the min is larger than the max" do
110
110
  lambda do
111
- class Manufacturer
111
+ class ::Manufacturer
112
112
  has 1..0, :halo_car
113
113
  end
114
114
  end.should raise_error(ArgumentError)
@@ -119,7 +119,7 @@ describe "DataMapper::Associations" do
119
119
  with(:vehicles, Manufacturer, { :min => 1, :max => 2 }).
120
120
  and_return(@relationship)
121
121
 
122
- class Manufacturer
122
+ class ::Manufacturer
123
123
  has(1..2, :vehicles, :min => 5, :max => 10).should == mock_relationship
124
124
  end
125
125
  end
@@ -130,7 +130,7 @@ describe "DataMapper::Associations" do
130
130
  with(:halo_car, Manufacturer, { :min => 1, :max => 1 }).
131
131
  and_return(@relationship)
132
132
 
133
- class Manufacturer
133
+ class ::Manufacturer
134
134
  has(1, :halo_car).should == mock_relationship
135
135
  end
136
136
  end
@@ -140,7 +140,7 @@ describe "DataMapper::Associations" do
140
140
  with(:halo_car, Manufacturer, { :min => 0, :max => 1 }).
141
141
  and_return(@relationship)
142
142
 
143
- class Manufacturer
143
+ class ::Manufacturer
144
144
  has(0..1, :halo_car).should == mock_relationship
145
145
  end
146
146
  end
@@ -150,7 +150,7 @@ describe "DataMapper::Associations" do
150
150
  with(:halo_car, Manufacturer, { :min => 1, :max => 1, :class_name => 'Car' }).
151
151
  and_return(@relationship)
152
152
 
153
- class Manufacturer
153
+ class ::Manufacturer
154
154
  has(1, :halo_car, :class_name => 'Car').should == mock_relationship
155
155
  end
156
156
  end
@@ -162,7 +162,7 @@ describe "DataMapper::Associations" do
162
162
  with(:vehicles, Manufacturer, { :min => 0, :max => @n }).
163
163
  and_return(@relationship)
164
164
 
165
- class Manufacturer
165
+ class ::Manufacturer
166
166
  has(n, :vehicles).should == mock_relationship
167
167
  end
168
168
  end
@@ -172,7 +172,7 @@ describe "DataMapper::Associations" do
172
172
  with(:vehicles, Manufacturer, { :min => 4, :max => 4 }).
173
173
  and_return(@relationship)
174
174
 
175
- class Manufacturer
175
+ class ::Manufacturer
176
176
  has(4, :vehicles).should == mock_relationship
177
177
  end
178
178
  end
@@ -182,7 +182,7 @@ describe "DataMapper::Associations" do
182
182
  with(:vehicles, Manufacturer, { :min => 2, :max => 4 }).
183
183
  and_return(@relationship)
184
184
 
185
- class Manufacturer
185
+ class ::Manufacturer
186
186
  has(2..4, :vehicles).should == mock_relationship
187
187
  end
188
188
  end
@@ -192,7 +192,7 @@ describe "DataMapper::Associations" do
192
192
  with(:vehicles, Manufacturer, { :min => 1, :max => @n, :class_name => 'Car' }).
193
193
  and_return(@relationship)
194
194
 
195
- class Manufacturer
195
+ class ::Manufacturer
196
196
  has(1..n, :vehicles, :class_name => 'Car').should == mock_relationship
197
197
  end
198
198
  end
@@ -200,7 +200,7 @@ describe "DataMapper::Associations" do
200
200
  # do not remove or change this spec.
201
201
  it "should raise an exception when n..n is used for the cardinality" do
202
202
  lambda do
203
- class Manufacturer
203
+ class ::Manufacturer
204
204
  has n..n, :subsidiaries, :class_name => 'Manufacturer'
205
205
  end
206
206
  end.should raise_error(ArgumentError)
@@ -211,7 +211,7 @@ describe "DataMapper::Associations" do
211
211
  with(:suppliers, Vehicle, { :min => 0, :max => @n, :through => :manufacturers }).
212
212
  and_return(@relationship)
213
213
 
214
- class Vehicle
214
+ class ::Vehicle
215
215
  has(n, :suppliers, :through => :manufacturers).should == mock_relationship
216
216
  end
217
217
  end
@@ -224,7 +224,7 @@ describe "DataMapper::Associations" do
224
224
  with(:vehicle, Manufacturer, {}).
225
225
  and_return(@relationship)
226
226
 
227
- class Manufacturer
227
+ class ::Manufacturer
228
228
  belongs_to(:vehicle).should == mock_relationship
229
229
  end
230
230
  end
@@ -234,7 +234,7 @@ describe "DataMapper::Associations" do
234
234
  with(:vehicle, Manufacturer, { :class_name => 'Car' }).
235
235
  and_return(@relationship)
236
236
 
237
- class Manufacturer
237
+ class ::Manufacturer
238
238
  belongs_to(:vehicle, :class_name => 'Car').should == mock_relationship
239
239
  end
240
240
  end
@@ -2,18 +2,18 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
3
  describe "DataMapper::IdentityMap" do
4
4
  before(:all) do
5
- class Cow
5
+ class ::Cow
6
6
  include DataMapper::Resource
7
7
  property :id, Integer, :key => true
8
8
  property :name, String
9
9
  end
10
10
 
11
- class Chicken
11
+ class ::Chicken
12
12
  include DataMapper::Resource
13
13
  property :name, String
14
14
  end
15
15
 
16
- class Pig
16
+ class ::Pig
17
17
  include DataMapper::Resource
18
18
  property :id, Integer, :key => true
19
19
  property :composite, Integer, :key => true
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
3
3
  describe "DataMapper::Is" do
4
4
  describe ".is" do
5
5
 
6
- module DataMapper
6
+ module ::DataMapper
7
7
 
8
8
  module Is
9
9
  module Example
@@ -32,17 +32,17 @@ describe "DataMapper::Is" do
32
32
  end # module Model
33
33
  end # module DataMapper
34
34
 
35
- class House
35
+ class ::House
36
36
  include DataMapper::Resource
37
37
  end
38
38
 
39
- class Cabin
39
+ class ::Cabin
40
40
  include DataMapper::Resource
41
41
  end
42
42
 
43
43
  it "should raise error unless it finds the plugin" do
44
44
  lambda do
45
- class House
45
+ class ::House
46
46
  is :no_plugin_by_this_name
47
47
  end
48
48
  end.should raise_error(DataMapper::PluginNotFoundError)
@@ -50,14 +50,14 @@ describe "DataMapper::Is" do
50
50
 
51
51
  it "should call plugin is_* method" do
52
52
  lambda do
53
- class House
53
+ class ::House
54
54
  is :example
55
55
  end
56
56
  end.should_not raise_error
57
57
  end
58
58
 
59
59
  it "should pass through arguments to plugin is_* method" do
60
- class House
60
+ class ::House
61
61
  is :example ,:option1 => :ping, :option2 => :pong
62
62
  end
63
63
 
@@ -68,7 +68,7 @@ describe "DataMapper::Is" do
68
68
  it "should not add class_methods before the plugin is activated" do
69
69
  Cabin.respond_to?(:example_class_method).should be_false
70
70
 
71
- class Cabin
71
+ class ::Cabin
72
72
  is :example
73
73
  end
74
74
 
@@ -3,14 +3,14 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
3
3
  describe DataMapper::Property do
4
4
  before :each do
5
5
  Object.send(:remove_const, :Zoo) if defined?(Zoo)
6
- class Zoo
6
+ class ::Zoo
7
7
  include DataMapper::Resource
8
8
 
9
9
  property :id, DataMapper::Types::Serial
10
10
  end
11
11
 
12
12
  Object.send(:remove_const, :Name) if defined?(Name)
13
- class Name < DataMapper::Type
13
+ class ::Name < DataMapper::Type
14
14
  primitive String
15
15
  track :hash
16
16
 
@@ -28,7 +28,7 @@ describe DataMapper::Property do
28
28
  end
29
29
 
30
30
  Object.send(:remove_const, :Tomato) if defined?(Tomato)
31
- class Tomato
31
+ class ::Tomato
32
32
  include DataMapper::Resource
33
33
  end
34
34
  end
@@ -286,7 +286,7 @@ describe DataMapper::Property do
286
286
 
287
287
  it "should not have key that is lazy" do
288
288
  Zoo.class_eval do
289
- property :id, DataMapper::Types::Text, :key => true
289
+ property :id, String, :lazy => true, :key => true
290
290
  property :name, String, :lazy => true
291
291
  end
292
292
  Zoo.auto_migrate!
@@ -429,8 +429,8 @@ describe DataMapper::Property do
429
429
  Tomato.class_eval <<-RUBY
430
430
  property :botanical_name, String, #{input.inspect}
431
431
  RUBY
432
- Tomato.send("#{output[0]}_instance_methods").should include("botanical_name")
433
- Tomato.send("#{output[1]}_instance_methods").should include("botanical_name=")
432
+ Tomato.send("#{output[0]}_instance_methods").map { |m| m.to_s }.should include("botanical_name")
433
+ Tomato.send("#{output[1]}_instance_methods").map { |m| m.to_s }.should include("botanical_name=")
434
434
  end
435
435
  end
436
436
 
@@ -466,7 +466,7 @@ describe DataMapper::Property do
466
466
  # end
467
467
 
468
468
  it "should append ? to TrueClass property reader methods" do
469
- class Potato
469
+ class ::Potato
470
470
  include DataMapper::Resource
471
471
  property :id, Integer, :key => true
472
472
  property :fresh, TrueClass
@@ -60,7 +60,7 @@ end
60
60
  describe DataMapper::Resource do
61
61
  before(:each) do
62
62
  Object.send(:remove_const, :Planet) if defined?(Planet)
63
- class Planet
63
+ class ::Planet
64
64
  include DataMapper::Resource
65
65
 
66
66
  storage_names[:legacy] = "dying_planets"
@@ -86,7 +86,7 @@ describe DataMapper::Resource do
86
86
  end
87
87
 
88
88
  Object.send(:remove_const, :Phone) if defined?(Phone)
89
- class Phone
89
+ class ::Phone
90
90
  include DataMapper::Resource
91
91
 
92
92
  property :name, String, :key => true
@@ -94,7 +94,7 @@ describe DataMapper::Resource do
94
94
  end
95
95
 
96
96
  Object.send(:remove_const, :Fruit) if defined?(Fruit)
97
- class Fruit
97
+ class ::Fruit
98
98
  include DataMapper::Resource
99
99
 
100
100
  property :id, Integer, :key => true
@@ -102,7 +102,7 @@ describe DataMapper::Resource do
102
102
  end
103
103
 
104
104
  Object.send(:remove_const, :Grain) if defined?(Grain)
105
- class Grain
105
+ class ::Grain
106
106
  include DataMapper::Resource
107
107
 
108
108
  property :id, Serial
@@ -110,7 +110,7 @@ describe DataMapper::Resource do
110
110
  end
111
111
 
112
112
  Object.send(:remove_const, :Vegetable) if defined?(Vegetable)
113
- class Vegetable
113
+ class ::Vegetable
114
114
  include DataMapper::Resource
115
115
 
116
116
  property :id, Serial
@@ -118,12 +118,12 @@ describe DataMapper::Resource do
118
118
  end
119
119
 
120
120
  Object.send(:remove_const, :Banana) if defined?(Banana)
121
- class Banana < Fruit
121
+ class ::Banana < Fruit
122
122
  property :type, Discriminator
123
123
  end
124
124
 
125
125
  Object.send(:remove_const, :Cyclist) if defined?(Cyclist)
126
- class Cyclist
126
+ class ::Cyclist
127
127
  include DataMapper::Resource
128
128
  property :id, Serial
129
129
  property :victories, Integer
@@ -568,7 +568,7 @@ describe DataMapper::Resource do
568
568
 
569
569
  describe "inheritance" do
570
570
  before(:all) do
571
- class Media
571
+ class ::Media
572
572
  include DataMapper::Resource
573
573
 
574
574
  storage_names[:default] = 'media'
@@ -577,7 +577,7 @@ describe DataMapper::Resource do
577
577
  property :name, String, :key => true
578
578
  end
579
579
 
580
- class NewsPaper < Media
580
+ class ::NewsPaper < Media
581
581
 
582
582
  storage_names[:east_coast] = 'mother'
583
583
 
@@ -600,7 +600,7 @@ describe DataMapper::Resource do
600
600
 
601
601
  describe "Single-table Inheritance" do
602
602
  before(:all) do
603
- class Plant
603
+ class ::Plant
604
604
  include DataMapper::Resource
605
605
 
606
606
  property :id, Integer, :key => true
@@ -615,13 +615,13 @@ describe DataMapper::Resource do
615
615
  end
616
616
  end
617
617
 
618
- class HousePlant < Plant
618
+ class ::HousePlant < Plant
619
619
  def calculate(int)
620
620
  int ** 3
621
621
  end
622
622
  end
623
623
 
624
- class PoisonIvy < Plant
624
+ class ::PoisonIvy < Plant
625
625
  def length=(len)
626
626
  attribute_set(:length, len - 1)
627
627
  end