structure 0.23.1 → 0.24.0

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.
@@ -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: