fat 0.0.3 → 0.0.4

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/ext/fat/fat.c +51 -11
  3. data/fat.gemspec +1 -1
  4. data/test/fat_test.rb +10 -2
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ac96972401cdfcbe6d2ff6f0b694a18058fbfff
4
- data.tar.gz: 34dd46ab23e6a79fc1fe930aedc6a509532fa47f
3
+ metadata.gz: 1fd45ba2047a3be07e832e7fb9a7ba405098b080
4
+ data.tar.gz: b28efdaad73f42987a52f813b6ca6292e23cbfd7
5
5
  SHA512:
6
- metadata.gz: 28ff990d2559cebfd2169f02b6314a96de8de73ea368c1ecc00c44718adc6ba1fb86708f3485b86b8a3e5f10fa71b86bb26a0ac5dea38d27532b67d997f70ecf
7
- data.tar.gz: a38cf3afb91a3bb4fbccd9009df7ab93ae116cef0e1b4ab8fc1a4c0316ce0b39701f67ef39ec71a53f83396fd6c9bc7debf8fc08c56a34f390280f1734e941f2
6
+ metadata.gz: 45feaf74742e8023bf38e02b52667627f49a638ea6d9a6e41715c94665a02d1b5a88b9e36bea854445271d229fc5ee1564d1f6efc5112372a6aa1fe7a375b18e
7
+ data.tar.gz: 234d08f9d9c752fce80a6e3dda850b3abcd2896b8ac83a33ad1ef09031a59b3b4df804eecdcc66bd2d36f76b8c95cc54758eb8c5fee7996fe46ab1fcfd8a2288
@@ -4,16 +4,25 @@ VALUE Fat = Qnil;
4
4
 
5
5
  void Init_fat();
6
6
 
7
+ // Interface methods
7
8
  static VALUE singleton_method_at(int argc, VALUE *argv, VALUE self);
9
+ static VALUE singleton_method_fetch_at(int argc, VALUE *argv, VALUE self);
8
10
  static VALUE method_at(int argc, VALUE *argv, VALUE hash);
11
+ static VALUE method_fetch_at(int argc, VALUE *argv, VALUE hash);
9
12
 
10
- static VALUE fat(VALUE hash, VALUE fields);
11
- void parse_fields(VALUE args, VALUE *fields);
13
+ static VALUE fat(VALUE hash, VALUE fields, int raise_on_nil);
14
+
15
+ // Helpers
16
+ static void parse_fields(VALUE args, VALUE *fields);
17
+ static VALUE fields_upto_index(VALUE fields, int index);
12
18
 
13
19
  void Init_fat(void) {
14
20
  Fat = rb_define_module("Fat");
21
+
15
22
  rb_define_module_function(Fat, "at", singleton_method_at, -1);
23
+ rb_define_module_function(Fat, "fetch_at", singleton_method_fetch_at, -1);
16
24
  rb_define_method(Fat, "at", method_at, -1);
25
+ rb_define_method(Fat, "fetch_at", method_fetch_at, -1);
17
26
  }
18
27
 
19
28
  static VALUE singleton_method_at(int argc, VALUE *argv, VALUE self) {
@@ -25,7 +34,19 @@ static VALUE singleton_method_at(int argc, VALUE *argv, VALUE self) {
25
34
  VALUE fields;
26
35
  parse_fields(args, &fields);
27
36
 
28
- return fat(hash, fields);
37
+ return fat(hash, fields, 0);
38
+ }
39
+
40
+ static VALUE singleton_method_fetch_at(int argc, VALUE *argv, VALUE self) {
41
+ VALUE hash;
42
+ VALUE args;
43
+
44
+ rb_scan_args(argc, argv, "1*", &hash, &args);
45
+
46
+ VALUE fields;
47
+ parse_fields(args, &fields);
48
+
49
+ return fat(hash, fields, 1);
29
50
  }
30
51
 
31
52
  static VALUE method_at(int argc, VALUE *argv, VALUE hash) {
@@ -35,16 +56,32 @@ static VALUE method_at(int argc, VALUE *argv, VALUE hash) {
35
56
  VALUE fields;
36
57
  parse_fields(args, &fields);
37
58
 
38
- return fat(hash, fields);
59
+ return fat(hash, fields, 0);
39
60
  }
40
61
 
41
- static VALUE fat(VALUE hash, VALUE fields) {
62
+ static VALUE method_fetch_at(int argc, VALUE *argv, VALUE hash) {
63
+ VALUE args;
64
+ rb_scan_args(argc, argv, "*", &args);
65
+
66
+ VALUE fields;
67
+ parse_fields(args, &fields);
68
+
69
+ return fat(hash, fields, 1);
70
+ }
71
+
72
+ static VALUE fat(VALUE hash, VALUE fields, int raise_on_nil) {
42
73
  VALUE value = hash;
74
+
43
75
  for (int i = 0; i < RARRAY_LEN(fields); i++) {
44
- value = rb_hash_aref(value, RARRAY_PTR(fields)[i]);
76
+ VALUE key = RARRAY_PTR(fields)[i];
77
+ value = rb_hash_aref(value, key);
45
78
 
46
79
  if (value == Qnil) {
47
- return Qnil;
80
+ if (raise_on_nil == 1) {
81
+ rb_raise(rb_eKeyError, "No value found at %s", RSTRING_PTR(fields_upto_index(fields, i)));
82
+ } else {
83
+ return Qnil;
84
+ }
48
85
  }
49
86
 
50
87
  if (TYPE(value) != T_HASH) {
@@ -55,16 +92,19 @@ static VALUE fat(VALUE hash, VALUE fields) {
55
92
  return value;
56
93
  }
57
94
 
58
- void parse_fields(VALUE args, VALUE *fields) {
95
+ static void parse_fields(VALUE args, VALUE *fields) {
59
96
  if (RARRAY_LEN(args) == 1) {
60
97
  VALUE chain = RARRAY_PTR(args)[0];
61
98
 
62
99
  StringValue(chain);
63
- const char* dot = ".";
64
-
65
- *fields = rb_str_split(chain, dot);
100
+ *fields = rb_str_split(chain, ".");
66
101
  } else {
67
102
  *fields = args;
68
103
  }
69
104
  }
70
105
 
106
+ static VALUE fields_upto_index(VALUE fields, int index) {
107
+ VALUE range = rb_range_new(INT2FIX(0), INT2FIX(index), 0);
108
+ VALUE slice = rb_funcall(fields, rb_intern("slice"), 1, range);
109
+ return rb_ary_join(slice, rb_str_new2("."));
110
+ }
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "fat"
3
- s.version = "0.0.3"
3
+ s.version = "0.0.4"
4
4
  s.summary = "C extension to find values in nested hashes without pain"
5
5
  s.description = s.summary
6
6
  s.authors = ["Lucas Tolchinsky"]
@@ -14,8 +14,10 @@ scope do
14
14
 
15
15
  test "honor key type" do |hash|
16
16
  assert_equal nil, Fat.at(hash, "foo", :not, :found)
17
+ assert_raise { Fat.fetch_at(hash, "foo", :not, :found) }
17
18
 
18
19
  assert_equal :found, Fat.at(hash, :foo, "bar", :baz)
20
+ assert_equal :found, Fat.fetch_at(hash, :foo, "bar", :baz)
19
21
  end
20
22
  end
21
23
 
@@ -32,8 +34,10 @@ scope do
32
34
 
33
35
  test "namespaced string keys" do |hash|
34
36
  assert_equal nil, Fat.at(hash, "foo.not.found")
37
+ assert_raise { Fat.fetch_at(hash, "foo.not.found") }
35
38
 
36
39
  assert_equal :found, Fat.at(hash, "foo.bar.baz")
40
+ assert_equal :found, Fat.fetch_at(hash, "foo.bar.baz")
37
41
  end
38
42
  end
39
43
 
@@ -46,7 +50,7 @@ scope do
46
50
  assert Hash.new.respond_to?(:at)
47
51
  end
48
52
 
49
- test "uses both interfaces" do
53
+ test "honor Fat interface" do
50
54
  hash = {
51
55
  "foo" => {
52
56
  "bar" => {
@@ -57,6 +61,9 @@ scope do
57
61
 
58
62
  assert_equal :found, hash.at("foo", "bar", "baz")
59
63
  assert_equal :found, hash.at("foo.bar.baz")
64
+
65
+ assert_equal :found, hash.fetch_at("foo", "bar", "baz")
66
+ assert_equal :found, hash.fetch_at("foo.bar.baz")
60
67
  end
61
68
  end
62
69
 
@@ -72,8 +79,9 @@ scope do
72
79
  }
73
80
  end
74
81
 
75
- test "break if a key doesn't hold a hash" do |hash|
82
+ test "break and return if a value is not a hash" do |hash|
76
83
  assert_equal :wat, Fat.at(hash, "foo.not_a_hash.baz")
84
+ assert_equal :wat, Fat.fetch_at(hash, "foo.not_a_hash.baz")
77
85
  end
78
86
  end
79
87
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lucas Tolchinsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-30 00:00:00.000000000 Z
11
+ date: 2014-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cutest