Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

structs feature - like an attribute with an OpenStruct

  • Loading branch information...
commit fcd628e050073216a2e87a903ef1d136856d6fa8 1 parent eb44f27
@ileitch ileitch authored committed
Showing with 40 additions and 15 deletions.
  1. +12 −0 README
  2. +19 −12 modelling.rb
  3. +9 −3 modelling_test.rb
View
12 README
@@ -17,6 +17,7 @@ modelling a little more concise, these three methods are:
* attributes
* collections
* maps
+ * structs
Attributes simply is an alias for attr_accessor, collections defines accessors
that are arrays, and maps defines hashes. The constructor ensures that each
@@ -37,6 +38,17 @@ map and collection are initalized as [] and {} respectively by default:
car.dealer_locations # => {}
car.telephone_services # => {}
+Structs are as the name suggests, structs. Or more specifically OpenStructs:
+
+ class Car
+ include Modelling
+ structs :features
+ end
+
+ car.features.abs true
+ car.features.air_con true
+ car.features.valves 8
+
TODO: WRITE DOCS FOR NEW CUSTOM INITIALIZERS!!!1 (AND UPDATE DOCS ABOVE,
THEY ARE LIKE OUT OF DATE OR SOMETHING).
i.e. collections :categories => CategoryCollection
View
31 modelling.rb
@@ -1,3 +1,5 @@
+require 'ostruct'
+
module Modelling
class << self
@@ -7,9 +9,10 @@ def append_features(receiver)
bind_attributes_meta_method(receiver)
bind_maps_meta_method(receiver)
bind_collection_meta_method(receiver)
+ build_structs_meta_method(receiver)
bind_default_constructor(receiver)
end
-
+
def generate_accessors(receiver, names, initializer)
receiver.instance_eval do
names.each do |name|
@@ -18,7 +21,7 @@ def generate_accessors(receiver, names, initializer)
end
end
end
-
+
def generate_adhoc_accessors(receiver, names_to_class_or_proc)
receiver.instance_eval do
names_to_class_or_proc.each do |name, class_or_proc|
@@ -28,42 +31,46 @@ def generate_adhoc_accessors(receiver, names_to_class_or_proc)
else
@@members[self][name] = Proc.new { class_or_proc.new }
end
-
+
end
end
end
-
+
private
-
+
def initialize_members_classvar(receiver)
receiver.instance_eval do
@@members ||= {}; @@members[self] ||= {}
end
end
-
+
def bind_meta_method(receiver, name, initializer)
receiver.instance_eval { class << self; self; end }.instance_eval do
define_method name do |*args|
if args.last.is_a?(Hash)
- Modelling.generate_adhoc_accessors(self, args.pop)
+ Modelling.generate_adhoc_accessors(self, args.pop)
end
Modelling.generate_accessors(self, args, initializer)
end
end
end
-
+
def bind_attributes_meta_method(receiver)
bind_meta_method(receiver, :attributes, Proc.new { nil })
end
-
+
def bind_collection_meta_method(receiver)
bind_meta_method(receiver, :collections, Proc.new { Array.new })
end
-
+
def bind_maps_meta_method(receiver)
bind_meta_method(receiver, :maps, Proc.new { Hash.new })
end
-
+
+ def build_structs_meta_method(receiver)
+ bind_meta_method(receiver, :structs, Proc.new { OpenStruct.new })
+ end
+
def bind_default_constructor(receiver)
receiver.class_eval do
def initialize(args = {})
@@ -76,5 +83,5 @@ def initialize(args = {})
end
end
-
+
end
View
12 modelling_test.rb
@@ -32,6 +32,7 @@ class Bike
include Modelling
attributes :manufacturer
maps :stickers
+ structs :features
end
class ModellingTest < Test::Unit::TestCase
@@ -99,18 +100,23 @@ def test_bike_does_not_bunk_on_having_no_collection
def test_bike_has_map_of_stickers
assert_equal({}, Bike.new.stickers)
end
-
+
def test_cars_doors_is_a_my_array
assert_kind_of MyArray, Car.new.doors
end
-
+
def test_sites_users_is_a_my_hash
assert_kind_of MyHash, Site.new.users
end
-
+
def test_can_initialize_with_proc_and_get_reference_to_new_instance
car = Car.new
assert_equal String.new(car.class.to_s), car.name
end
+ def test_bike_has_features
+ bike = Bike.new
+ assert_kind_of OpenStruct, bike.features
+ end
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.