fat 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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