Skip to content

Commit a2db2d4

Browse files
Earlopainbyroot
authored andcommitted
[Feature #21781] Add ENV.fetch_values
Specs/Implementation inspired by methods on hash/env that already exist.
1 parent 1008a46 commit a2db2d4

2 files changed

Lines changed: 89 additions & 0 deletions

File tree

hash.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5355,6 +5355,42 @@ env_fetch(int argc, VALUE *argv, VALUE _)
53555355
return env;
53565356
}
53575357

5358+
/*
5359+
* call-seq:
5360+
* ENV.fetch_values(*names) -> array of values
5361+
* ENV.fetch_values(*names) {|name| ... } -> array of values
5362+
*
5363+
* Returns an Array containing the environment variable values associated with
5364+
* the given names:
5365+
* ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5366+
* ENV.fetch_values('foo', 'baz') # => ["0", "2"]
5367+
*
5368+
* Otherwise if a block is given yields +name+ to
5369+
* the block and returns the block's return value:
5370+
* ENV.fetch_values('foo', 'bam') {|key| key.to_s} # => ["0", "bam"]
5371+
*
5372+
* Raises KeyError if +name+ is valid, but not found and block is not given:
5373+
* ENV.fetch_values('foo', 'bam') # Raises KeyError (key not found: "bam")
5374+
*
5375+
* Returns an empty Array if no names given.
5376+
*
5377+
* Raises an exception if any name is invalid.
5378+
* See {Invalid Names and Values}[rdoc-ref:ENV@Invalid+Names+and+Values].
5379+
*/
5380+
5381+
static VALUE
5382+
env_fetch_values(int argc, VALUE *argv, VALUE ehash)
5383+
{
5384+
VALUE result = rb_ary_new2(argc);
5385+
long i;
5386+
5387+
for (i=0; i<argc; i++) {
5388+
rb_ary_push(result, env_fetch(1, &argv[i], ehash));
5389+
}
5390+
5391+
return result;
5392+
}
5393+
53585394
#if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
53595395
#elif defined __sun
53605396
static int
@@ -7577,6 +7613,7 @@ Init_Hash(void)
75777613
* - ::clone: Raises an exception.
75787614
* - ::except: Returns a hash of all name/value pairs except those given.
75797615
* - ::fetch: Returns the value for the given name.
7616+
* - ::fetch_values: Returns array containing the values associated with given names.
75807617
* - ::inspect: Returns the contents of +ENV+ as a string.
75817618
* - ::invert: Returns a hash whose keys are the +ENV+ values,
75827619
and whose values are the corresponding +ENV+ names.
@@ -7612,6 +7649,7 @@ Init_Hash(void)
76127649

76137650
rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
76147651
rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);
7652+
rb_define_singleton_method(envtbl, "fetch_values", env_fetch_values, -1);
76157653
rb_define_singleton_method(envtbl, "[]=", env_aset_m, 2);
76167654
rb_define_singleton_method(envtbl, "store", env_aset_m, 2);
76177655
rb_define_singleton_method(envtbl, "each", env_each_pair, 0);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
require_relative '../../spec_helper'
2+
require_relative 'fixtures/common'
3+
4+
ruby_version_is "4.1" do
5+
describe "ENV.fetch_values" do
6+
before :each do
7+
@saved_foo = ENV["foo"]
8+
@saved_bar = ENV["bar"]
9+
ENV.delete("foo")
10+
ENV.delete("bar")
11+
end
12+
13+
after :each do
14+
ENV["foo"] = @saved_foo
15+
ENV["bar"] = @saved_bar
16+
end
17+
18+
it "returns an array of the values corresponding to the given keys" do
19+
ENV["foo"] = "oof"
20+
ENV["bar"] = "rab"
21+
ENV.fetch_values("bar", "foo").should == ["rab", "oof"]
22+
end
23+
24+
it "returns the default value from block" do
25+
ENV["foo"] = "oof"
26+
ENV.fetch_values("bar") { |key| "`#{key}' is not found" }.should == ["`bar' is not found"]
27+
ENV.fetch_values("bar", "foo") { |key| "`#{key}' is not found" }.should == ["`bar' is not found", "oof"]
28+
end
29+
30+
it "returns an empty array if no keys specified" do
31+
ENV.fetch_values.should == []
32+
end
33+
34+
it "raises KeyError when there is no matching key" do
35+
ENV["foo"] = "oof"
36+
ENV["bar"] = "rab"
37+
-> {
38+
ENV.fetch_values("bar", "y", "foo", "z")
39+
}.should raise_error(KeyError, 'key not found: "y"')
40+
end
41+
42+
it "uses the locale encoding" do
43+
ENV.fetch_values(ENV.keys.first).first.encoding.should == ENVSpecs.encoding
44+
end
45+
46+
it "raises TypeError when a key is not coercible to String" do
47+
ENV["foo"] = "oof"
48+
-> { ENV.fetch_values("foo", Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
49+
end
50+
end
51+
end

0 commit comments

Comments
 (0)