summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorTimo Schilling <timo@schilling.io>2019-05-04 15:37:38 +0200
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-06-18 22:47:32 +0900
commit82ca8c73034b0a522fd2970ea39edfcd801955fe (patch)
treea510904e4b4aa2f64b7dfa89551de977c574b41a /hash.c
parenta5bc0b8f8ccb31c23223dcbfd6acee3e8390d020 (diff)
Add Hash#except ENV#except [Feature #15822]
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/hash.c b/hash.c
index 742480d974..3babff59f3 100644
--- a/hash.c
+++ b/hash.c
@@ -2824,6 +2824,33 @@ rb_hash_slice(int argc, VALUE *argv, VALUE hash)
/*
* call-seq:
+ * hsh.except(*keys) -> a_hash
+ *
+ * Returns a hash excluding the given keys and their values.
+ *
+ * h = { a: 100, b: 200, c: 300 }
+ * h.except(:a) #=> {:b=>200, :c=>300}
+ * h.except(:b, :c, :d) #=> {:a=>100}
+ */
+
+static VALUE
+rb_hash_except(int argc, VALUE *argv, VALUE hash)
+{
+ int i;
+ VALUE key, result;
+
+ result = rb_obj_dup(hash);
+
+ for (i = 0; i < argc; i++) {
+ key = argv[i];
+ rb_hash_delete(result, key);
+ }
+
+ return result;
+}
+
+/*
+ * call-seq:
* hash.values_at(*keys) -> new_array
*
* Returns a new \Array containing values for the given +keys+:
@@ -6878,6 +6905,29 @@ env_to_h(VALUE _)
}
/*
+ * call-seq:
+ * ENV.except(*keys) -> a_hash
+ *
+ * Returns a hash except the given keys from ENV and their values.
+ *
+ * ENV #=> {"LANG"="en_US.UTF-8", "TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}
+ * ENV.except("TERM","HOME") #=> {"LANG"="en_US.UTF-8"}
+ */
+static VALUE
+env_except(int argc, VALUE *argv, VALUE _)
+{
+ int i;
+ VALUE key, hash = env_to_hash();
+
+ for (i = 0; i < argc; i++) {
+ key = argv[i];
+ rb_hash_delete(hash, key);
+ }
+
+ return hash;
+}
+
+/*
* call-seq:
* ENV.reject { |name, value| block } -> hash of name/value pairs
* ENV.reject -> an_enumerator
@@ -7543,6 +7593,7 @@ Init_Hash(void)
rb_define_method(rb_cHash, "reject", rb_hash_reject, 0);
rb_define_method(rb_cHash, "reject!", rb_hash_reject_bang, 0);
rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
+ rb_define_method(rb_cHash, "except", rb_hash_except, -1);
rb_define_method(rb_cHash, "clear", rb_hash_clear, 0);
rb_define_method(rb_cHash, "invert", rb_hash_invert, 0);
rb_define_method(rb_cHash, "update", rb_hash_update, -1);
@@ -7678,6 +7729,7 @@ Init_Hash(void)
rb_define_singleton_method(envtbl, "delete_if", env_delete_if, 0);
rb_define_singleton_method(envtbl, "keep_if", env_keep_if, 0);
rb_define_singleton_method(envtbl, "slice", env_slice, -1);
+ rb_define_singleton_method(envtbl, "except", env_except, -1);
rb_define_singleton_method(envtbl, "clear", env_clear, 0);
rb_define_singleton_method(envtbl, "reject", env_reject, 0);
rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);