The properties module class is used in a class to define persistent attributes. That is those attributes that will be saved to the database. It inserts read/write accessors into the class for each property.
It also inserts a read only accessor for a property named ':id' automatically. The 'id' replaces 'oid' in the old code and is used as a unique object identifier for use in a database or serializing via yaml. We never want to accidently write to this variable.
Properties are lazily evaluated. If you declare a property you will get the accessors but it won't go into the properties table until you attempt to reference it. (Note the property :b in the following sample is never seen because we don't use it. It does exist though)
The properties are stored in a hash table on the object called @props. No instance variables are defined for any of the properties! So if you use the @ to access one you will get nil, and if you think you use in assigning with @, you are creating a new instance variable.
A sample program and output follows:
$:.unshift "lib" require 'flexmock' require 'yaml' require 'db/properties' require 'pp' # This is just code to fake out properties.rb into thinking # there is a database. It hands out new id numbers in sequence. # $nextid = 0 $engine = FlexMock.new $engine.mock_handle(:world) {$engine} $engine.mock_handle(:db) {$engine} $engine.mock_handle(:getid) {$nextid += 1} class A property :a, :b, :c def initialize @x = 1 @y = "I'm not saved" self.a = "save me" self.c = 929287 puts "Our database id is: " + id.to_s puts "Dump out object" pp self puts "correctly assign a value to a (note use of self in assignment!)" self.a = "HI!" puts "Dump our object" pp self puts "The following would be a mistake)" @c = 777 puts "Dump our object" pp self puts "use a value" pp a, b, c end end A.new puts "++++++++++++" puts "another A object - id should change" A.new puts "Finally lets create another new object and dump it with YAML" puts YAML::dump(A.new)
The output:
Our database id is: 1 Dump out object #<A:0x2e85100 @props={:id=>1, :c=>929287, :a=>"save me"}, @x=1, @y="I'm not saved"> correctly assign a value to a (note use of self in assignment!) Dump our object #<A:0x2e85100 @props={:id=>1, :c=>929287, :a=>"HI!"}, @x=1, @y="I'm not saved"> The following would be a mistake) Dump our object #<A:0x2e85100 @c=777, @props={:id=>1, :c=>929287, :a=>"HI!"}, @x=1, @y="I'm not saved"> use a value "HI!" nil 929287 ++++++++++++ another A object - id should change Our database id is: 2 Dump out object #<A:0x2e75c68 @props={:id=>2, :c=>929287, :a=>"save me"}, @x=1, @y="I'm not saved"> correctly assign a value to a (note use of self in assignment!) Dump our object #<A:0x2e75c68 @props={:id=>2, :c=>929287, :a=>"HI!"}, @x=1, @y="I'm not saved"> The following would be a mistake) Dump our object #<A:0x2e75c68 @c=777, @props={:id=>2, :c=>929287, :a=>"HI!"}, @x=1, @y="I'm not saved"> use a value "HI!" nil 929287 Finally lets create another new object and dump it with YAML Our database id is: 3 Dump out object #<A:0x2e6cf50 @props={:id=>3, :c=>929287, :a=>"save me"}, @x=1, @y="I'm not saved"> correctly assign a value to a (note use of self in assignment!) Dump our object #<A:0x2e6cf50 @props={:id=>3, :c=>929287, :a=>"HI!"}, @x=1, @y="I'm not saved"> The following would be a mistake) Dump our object #<A:0x2e6cf50 @c=777, @props={:id=>3, :c=>929287, :a=>"HI!"}, @x=1, @y="I'm not saved"> use a value "HI!" nil 929287 --- !ruby/object:A props: :id: 3 :c: 929287 :a: HI! Loaded suite C:/work/teensymud/trunk/testprops Started Finished in 0.0 seconds. 0 tests, 0 assertions, 0 failures, 0 errors Tool completed successfully