lib/astruct.rb in astruct-1.0.0 vs lib/astruct.rb in astruct-2.7.1
- old
+ new
@@ -1,30 +1,94 @@
-module AltStruct
- attr_reader :table
+require_relative 'astruct/module'
- def initialize(pairs = {})
- @table ||= {}
- for key, value in pairs
- @table.merge! define_accessor key.to_sym, value
- end unless pairs == {}
- end
+#
+# = astruct.rb: AltStruct implementation
+#
+# Author:: Kurtis Rainbolt-Greene
+# Documentation:: Kurtis Rainbolt-Greene
+#
+# AltStruct is an Class and Module (AltStruct::M) that can be used to
+# create hash-like classes. Allowing you to create an object that can
+# dynamically accept accessors and behaves very much like a Hash.
+#
- def define_accessor(key, value)
- define_singleton_method(key) { @table[key] }
- define_singleton_method(:"#{key}=") { |v| @table[key] = v }
- { key => value }.freeze
- end
+#
+# An AltStruct is a data structure, similar to a Hash, that allows the
+# definition of arbitrary attributes with their accompanying values. This is
+# accomplished by using Ruby's metaprogramming to define methods on the class
+# itself.
+#
- def load(pairs)
- for key, value in pairs
- @table.merge! define_accessor key.to_sym, value
- end unless pairs == {}
- end
+#
+# == Examples:
+#
+# require 'astruct'
+#
+# class Profile < AltStruct
+#
+# end
+#
+# person = Profile.new name: "John Smith"
+# person.age = 70
+#
+# puts person.name # => "John Smith"
+# puts person.age # => 70
+# puts person.dump # => { :name => "John Smith", :age => 70 }
+#
- def dump(*keys)
- if keys == [] then @table else @table.keep_if { |k| keys.include? k } end
- end
+#
+# An AltStruct employs a Hash internally to store the methods and values and
+# can even be initialized with one:
+#
+# australia = AltStruct.new country: "Australia", population: 20_000_000
+# puts australia.inspect # => <AltStruct country="Australia", population=20000000>
+#
- def inspect
- "#<#{self.class}:#{object_id} #{dump.map { |k,v| "#{k}=#{v.inspect}" }.join ' '}>"
- end
+#
+# Hash keys with spaces or characters that would normally not be able to use for
+# method calls (e.g. ()[]*) will not be immediately available on the
+# AltStruct object as a method for retrieval or assignment, but can be still be
+# reached through the Object#send method.
+#
+# measurements = AltStruct.new "length (in inches)" => 24
+# measurements.send "length (in inches)" # => 24
+#
+# data_point = AltStruct.new :queued? => true
+# data_point.queued? # => true
+# data_point.send "queued?=", false
+# data_point.queued? # => false
+#
+
+#
+# Removing the presence of a method requires the execution the delete_field
+# or delete (like a hash) method as setting the property value to +nil+
+# will not remove the method.
+#
+# first_pet = AltStruct.new :name => 'Rowdy', :owner => 'John Smith'
+# first_pet.owner = nil
+# second_pet = AltStruct.new :name => 'Rowdy'
+#
+# first_pet == second_pet # -> false
+#
+# first_pet.delete_field(:owner)
+# first_pet == second_pet # -> true
+#
+
+#
+# == Implementation:
+#
+# An AltStruct utilizes Ruby's method lookup structure to and find and define
+# the necessary methods for properties. This is accomplished through the method
+# method_missing and define_method.
+#
+
+#
+# This should be a consideration if there is a concern about the performance of
+# the objects that are created, as there is much more overhead in the setting
+# of these properties compared to using a Hash or a Struct.
+#
+class AltStruct
+ # We include all of the AltStruct::M Module in order to give AltStruct
+ # the same behavior as OpenStruct. It's better, however, to simply
+ # include AltStruct::M into your own class.
+ include AltStruct::M
end