structure 0.23.1 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,8 +4,8 @@ rescue NameError
4
4
  require 'json'
5
5
  end
6
6
 
7
- # Structure is a key/value container. On the most basic level, it
8
- # mirrors the functionality of OpenStruct:
7
+ # Structure is a key/value container. On the most basic level, it mirrors the
8
+ # functionality of OpenStruct:
9
9
  #
10
10
  # require 'structure'
11
11
  #
@@ -42,7 +42,7 @@ end
42
42
  #
43
43
  # class Price < Structure
44
44
  # field :cents, Integer
45
- # field :currency, :default => "USD"
45
+ # field :currency, String, :default => "USD"
46
46
  # end
47
47
  #
48
48
  # hash = { "cents" => "100" }
@@ -51,11 +51,12 @@ end
51
51
  # puts price.cents # -> 100
52
52
  # puts price.currency # -> "USD"
53
53
  #
54
- # Alternatively, define a proc to cast or otherwise manipulate assigned
55
- # values:
54
+ # Alternatively, define a proc to cast or otherwise manipulate values and
55
+ # assign defaults:
56
56
  #
57
57
  # class Product < Structure
58
58
  # field :sku, lambda(&:upcase)
59
+ # field :created_at, String, :default => lambda { Time.now.to_s }
59
60
  # end
60
61
  #
61
62
  # product = Product.new(:sku => 'foo-bar')
@@ -96,13 +97,20 @@ class Structure
96
97
  :default => default }
97
98
  end
98
99
 
99
- # Syntactic sugar to create a typed field that defaults to an empty
100
- # array.
100
+ alias key field
101
+
102
+ # Syntactic sugar to create a typed field that defaults to an empty array.
101
103
  # @param key the name of the field
102
104
  def many(key)
103
105
  field(key, Array, :default => [])
104
106
  end
105
107
 
108
+ # Syntactic sugar to create a field that stands in for another structure.
109
+ # @param key the name of the field
110
+ def one(key)
111
+ field(key, lambda { |v| v.is_a?(Structure) ? v : Structure.new(v) })
112
+ end
113
+
106
114
  private
107
115
 
108
116
  def inherited(child)
@@ -115,11 +123,13 @@ class Structure
115
123
  # Creates a new structure.
116
124
  # @param [Hash] hsh an optional hash to populate fields
117
125
  def initialize(hsh = {})
118
- # It may have improved performance if I had defined these methods
119
- # on the class level, but I decided to privilege consistency here.
120
- # Who wouldn't?
121
126
  @table = blueprint.inject({}) do |a, (k, v)|
122
- default = v[:default].dup rescue v[:default]
127
+ default = if v[:default].is_a? Proc
128
+ v[:default].call
129
+ else
130
+ v[:default].dup rescue v[:default]
131
+ end
132
+
123
133
  a.merge new_field(k, v[:type]) => default
124
134
  end
125
135
 
@@ -147,8 +157,7 @@ class Structure
147
157
  end
148
158
 
149
159
  # Provides marshalling support for use by the Marshal library.
150
- # @param [Hash] hsh a hash of keys and values to populate the
151
- # structure
160
+ # @param [Hash] hsh a hash of keys and values to populate the structure
152
161
  def marshal_load(hsh)
153
162
  hsh.each do |k, v|
154
163
  self.send("#{new_field(k)}=", v)
@@ -1,3 +1,3 @@
1
1
  class Structure
2
- VERSION = '0.23.1'
2
+ VERSION = '0.24.0'
3
3
  end
@@ -5,8 +5,10 @@ class Product < Structure
5
5
  field :sku, lambda(&:upcase)
6
6
  field :cents, Integer
7
7
  field :currency, String, :default => 'USD'
8
- field :in_stock, :default => true
8
+ key :in_stock, :default => true
9
+ field :created_on, :default => lambda { Date.today }
9
10
  many :related
11
+ one :manufacturer
10
12
  end
11
13
 
12
14
  class Foo < Structure
@@ -46,6 +48,7 @@ class TestStructureWithFields < MiniTest::Unit::TestCase
46
48
  assert_equal 'USD', @product.currency
47
49
  assert_equal true, @product.in_stock
48
50
  assert_equal [], @product.related
51
+ assert_kind_of Date, @product.created_on
49
52
  end
50
53
 
51
54
  def test_recursive_hashes
@@ -64,4 +67,14 @@ class TestStructureWithFields < MiniTest::Unit::TestCase
64
67
  assert_equal [related], @product.related
65
68
  assert_equal [], @product.related.first.related
66
69
  end
70
+
71
+ def test_one_to_one
72
+ hsh = { :name => 'Manufacturer' }
73
+
74
+ @product.manufacturer = Structure.new(hsh)
75
+ assert_equal 'Manufacturer', @product.manufacturer.name
76
+
77
+ @product.manufacturer = hsh
78
+ assert_equal 'Manufacturer', @product.manufacturer.name
79
+ end
67
80
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: structure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.1
4
+ version: 0.24.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-08 00:00:00.000000000 Z
12
+ date: 2012-01-16 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Structure is a key/value container.
15
15
  email:
@@ -44,18 +44,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
44
  - - ! '>='
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
- segments:
48
- - 0
49
- hash: 2719962180742855248
50
47
  required_rubygems_version: !ruby/object:Gem::Requirement
51
48
  none: false
52
49
  requirements:
53
50
  - - ! '>='
54
51
  - !ruby/object:Gem::Version
55
52
  version: '0'
56
- segments:
57
- - 0
58
- hash: 2719962180742855248
59
53
  requirements: []
60
54
  rubyforge_project: structure
61
55
  rubygems_version: 1.8.11
@@ -66,3 +60,4 @@ test_files:
66
60
  - test/helper.rb
67
61
  - test/structure_test.rb
68
62
  - test/structure_with_fields_test.rb
63
+ has_rdoc: