restricted_struct 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 701f39867ce9703612900fe3fc7a02a5546860cd
4
- data.tar.gz: ec33a9f1adf85537047831ad5f52c7d02be8bc1f
3
+ metadata.gz: 4990efc33886647ac9d035269794891b1f4a5e7b
4
+ data.tar.gz: b11ebf6330ea5d3fced870c3c577cd01d61d650b
5
5
  SHA512:
6
- metadata.gz: 97fc5cf511d82388464d41532d3f41a063de18b89891c1c9ac5cbd728e2337e2dc6ce2825dbe156350a65c59ba66eee5dffdb1a2d627d13d195c9ba75e5a4b9c
7
- data.tar.gz: 96fa0f60b0005d2ff5da42137de9bcb8973bafe88e117854209fc532c2db24adb29f89970101f3128bce0a1058062bc0094f8f2dc9b965f95cae0e4bf3d2205b
6
+ metadata.gz: f2e2200102af51fcd8947504095a5c6b596d23f9b30e66913e2c751f15757d84f7858b53693bb55c29ce044193b42cf2d80174674b3c731acc5e2237bb906c79
7
+ data.tar.gz: e9a3d4fa4b02bd90a25170ad38c646c1b47d4838bdcb60644dbfebaa528cb73c0143332ae26128743ac6e664f4c6eeba129cf05c96c01164e6615316a4b7e6c7
data/README.md CHANGED
@@ -42,6 +42,41 @@ end
42
42
 
43
43
  Available access levels: `:private` and `:protected`.
44
44
 
45
+ ### Keyword arguments
46
+
47
+ ```ruby
48
+ class Rectangle < RestrictedStruct.new(:protected, :x1, :y1, :x2, :y2, :color => :white)
49
+ # ...
50
+ end
51
+ ```
52
+
53
+ This will create a struct with 5 fields: x1, y1, x2, y2 and color. But color will default to `:white` if not provided.
54
+ And color can be assigned while instantiating a value of this class either as 5th parameter or as keyword argument, i.e.:
55
+
56
+ ```ruby
57
+ rect = Rectangle[20, 30, 60, 50, :red]
58
+ # is the same as:
59
+ rect = Rectangle[20, 30, 60, 50, :color => :red]
60
+ ```
61
+
62
+ By the way, nothing forbids you from specifying any fields as keyword arguments:
63
+
64
+ ```ruby
65
+ rect = Rectangle[20, 30, :x2 => 60, :y2 => 50]
66
+ # or even all of them:
67
+ rect = Rectangle[:x1 => 20, :y1 => 30, :x2 => 60, :y2 => 50, :color => :black]
68
+ ```
69
+
70
+ Just be careful when specifying the same fields simultaneously as normal params and as part of keyword arguments hash, for example:
71
+
72
+ ```ruby
73
+ rect = Rectangle[20, 30, 60, 50, :x2 => 55]
74
+ # is essentially the same as
75
+ rect = Rectangle[20, 30, 55, 50]
76
+ ```
77
+
78
+ Which means 3rd argument was overwritten by corresponding keyword argument.
79
+
45
80
  ## Contributing
46
81
 
47
82
  1. Fork it ( https://github.com/waterlink/restricted_struct/fork )
@@ -1,2 +1,3 @@
1
1
  require "restricted_struct/definition"
2
+ require "restricted_struct/support"
2
3
  require "restricted_struct/version"
@@ -7,7 +7,20 @@ class RestrictedStruct < Struct
7
7
 
8
8
  class << self
9
9
  def new(access_level, *properties)
10
- super(*properties, &access_restriction(access_level, properties))
10
+ properties, defaults = Support.extract_keyword_args(properties)
11
+ properties.concat(defaults.keys)
12
+ super(*properties, &access_restriction(access_level, properties)).with_defaults(defaults)
13
+ end
14
+
15
+ def defaults
16
+ @defaults ||= {}
17
+ end
18
+
19
+ protected
20
+
21
+ def with_defaults(defaults)
22
+ @defaults = defaults
23
+ self
11
24
  end
12
25
 
13
26
  private
@@ -26,4 +39,15 @@ class RestrictedStruct < Struct
26
39
  properties + properties.map { |name| :"#{name}=" }
27
40
  end
28
41
  end
42
+
43
+ def initialize(*values)
44
+ values, keyword_args = Support.extract_keyword_args(values)
45
+ members.each_with_index do |name, index|
46
+ # 1.8 compatibility
47
+ key = name.to_sym
48
+ values[index] ||= self.class.defaults[key]
49
+ values[index] = keyword_args[key] if keyword_args.has_key?(key)
50
+ end
51
+ super(*values)
52
+ end
29
53
  end
@@ -0,0 +1,9 @@
1
+ module RestrictedStruct::Support
2
+ class << self
3
+ def extract_keyword_args(array)
4
+ array = array.dup
5
+ keyword_args = Hash === array[-1] ? array.pop : {}
6
+ [array, keyword_args]
7
+ end
8
+ end
9
+ end
@@ -1 +1 @@
1
- RestrictedStruct::VERSION = "0.1.0"
1
+ RestrictedStruct::VERSION = "0.2.0"
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = RestrictedStruct::VERSION
9
9
  spec.authors = ["Alexey Fedorov", "Anselm Helbig"]
10
10
  spec.email = ["alexey.fedorov@wimdu.com", "anselm.helbig@wimdu.com"]
11
- spec.summary = %q{Create Struct-s with private or protected attributes}
11
+ spec.summary = %q{Create Struct-s with private or protected attributes. Reduce your boilerplate code to nothing}
12
12
  spec.description = %q{This gem allows to use ruby's Struct, but automatically hides all the attributes as private or protected, which provides higher level of encapsulation.}
13
13
  spec.homepage = ""
14
14
  spec.license = "MIT"
@@ -0,0 +1,25 @@
1
+ RSpec.describe RestrictedStruct::Support do
2
+ describe ".extract_keyword_args" do
3
+ it "splits into list and last parameter if it is a hash" do
4
+ expect(described_class.extract_keyword_args(
5
+ [1, 2, 3, { :color => :red }]
6
+ )).to eq([[1, 2, 3], { :color => :red }])
7
+ end
8
+
9
+ it "last parameter defaults to an empty hash" do
10
+ expect(described_class.extract_keyword_args(
11
+ [1, 2, 3, 4]
12
+ )).to eq([[1, 2, 3, 4], {}])
13
+ end
14
+
15
+ it "list defaults to an empty list if only hash provided" do
16
+ expect(described_class.extract_keyword_args(
17
+ [{ :color => :red }]
18
+ )).to eq([[], { :color => :red }])
19
+ end
20
+
21
+ it "returns empty list and hash if provided array is empty" do
22
+ expect(described_class.extract_keyword_args([])).to eq([[], {}])
23
+ end
24
+ end
25
+ end
@@ -21,6 +21,33 @@ RSpec.describe RestrictedStruct do
21
21
  }.to raise_error(NoMethodError, /#{access_level} method `properties='/)
22
22
  end
23
23
  end
24
+ end
25
+
26
+ describe "keyword arguments" do
27
+ let(:rectangle) { RestrictedStruct.new(:protected, :x1, :y1, :x2, :y2, :color => :white) }
28
+
29
+ it "equals to specified default if omitted" do
30
+ expect(rectangle.new(1, 2, 3, 4)).to eq(rectangle.new(1, 2, 3, 4, :white))
31
+ end
24
32
 
33
+ it "can be overriden by specifying as normal argument" do
34
+ expect(rectangle.new(1, 2, 3, 4, :red)).not_to eq(rectangle.new(1, 2, 3, 4))
35
+ end
36
+
37
+ it "can be overriden by specifying as keyword argument" do
38
+ expect(rectangle.new(1, 2, 3, 4, :color => :red)).not_to eq(rectangle.new(1, 2, 3, 4))
39
+ end
40
+
41
+ it "being specified as keyword argument is equivalent to specifying as normal argument" do
42
+ expect(rectangle.new(1, 2, 3, 4, :red)).to eq(rectangle.new(1, 2, 3, 4, :color => :red))
43
+ end
44
+
45
+ it "can be used instead of normal arguments" do
46
+ expect(rectangle.new(1, 2, :x2 => 3, :y2 => 4)).to eq(rectangle.new(1, 2, 3, 4))
47
+ end
48
+
49
+ it "overrides value of normal argument" do
50
+ expect(rectangle.new(1, 2, 3, 4, :x2 => 5)).to eq(rectangle.new(1, 2, 5, 4))
51
+ end
25
52
  end
26
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restricted_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Fedorov
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-21 00:00:00.000000000 Z
12
+ date: 2015-01-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -57,8 +57,10 @@ files:
57
57
  - Rakefile
58
58
  - lib/restricted_struct.rb
59
59
  - lib/restricted_struct/definition.rb
60
+ - lib/restricted_struct/support.rb
60
61
  - lib/restricted_struct/version.rb
61
62
  - restricted_struct.gemspec
63
+ - spec/restricted_struct/support_spec.rb
62
64
  - spec/restricted_struct_spec.rb
63
65
  - spec/spec_helper.rb
64
66
  homepage: ''
@@ -84,7 +86,9 @@ rubyforge_project:
84
86
  rubygems_version: 2.2.2
85
87
  signing_key:
86
88
  specification_version: 4
87
- summary: Create Struct-s with private or protected attributes
89
+ summary: Create Struct-s with private or protected attributes. Reduce your boilerplate
90
+ code to nothing
88
91
  test_files:
92
+ - spec/restricted_struct/support_spec.rb
89
93
  - spec/restricted_struct_spec.rb
90
94
  - spec/spec_helper.rb