123456789_123456789_123456789_123456789_123456789_

Class: ENV

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::Enumerable
Inherits: Object
Defined in: hash.c,
hash.c

Overview

ENV is a hash-like accessor for environment variables.

Interaction with the Operating System

The ENV object interacts with the operating system’s environment variables:

  • When you get the value for a name in ENV, the value is retrieved from among the current environment variables.

  • When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.

  • When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.

Names and Values

Generally, a name or value is a ::String.

Valid Names and Values

Each name or value must be one of the following:

  • A String.

  • An object that responds to #to_str by returning a ::String, in which case that ::String will be used as the name or value.

Invalid Names and Values

A new name:

  • May not be the empty string:

    ENV[''] = '0'
    # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
  • May not contain character "=":

    ENV['='] = '0'
    # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))

A new name or value:

  • May not be a non-String that does not respond to #to_str:

    ENV['foo'] = Object.new
    # Raises TypeError (no implicit conversion of Object into String)
    ENV[Object.new] = '0'
    # Raises TypeError (no implicit conversion of Object into String)
  • May not contain the NUL character "\0":

    ENV['foo'] = "\0"
    # Raises ArgumentError (bad environment variable value: contains null byte)
    ENV["\0"] == '0'
    # Raises ArgumentError (bad environment variable name: contains null byte)
  • May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:

    ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
    # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
    ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
    # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)

About Ordering

ENV enumerates its name/value pairs in the order found in the operating system’s environment variables. Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.

This will be seen in:

  • A Hash returned by an ENV method.

  • An Enumerator returned by an ENV method.

  • An Array returned by .keys, .values, or .to_a.

  • The String returned by .inspect.

  • The Array returned by .shift.

  • The name returned by .key.

About the Examples

Some methods in ENV return ENV itself. Typically, there are many environment variables. It’s not useful to display a large ENV in the examples here, so most example snippets begin by resetting the contents of ENV:

  • .replace replaces ENV with a new collection of entries.

  • .clear empties ENV.

What’s Here

First, what’s elsewhere. Class ENV:

  • Inherits from [class Object](Object.html#class-Object-label-What-27s+Here).

  • Extends [module Enumerable](Enumerable.html#module-Enumerable-label-What-27s+Here),

Here, class ENV provides methods that are useful for:

Methods for Querying

  • ::[]

    Returns the value for the given environment variable name if it exists:

  • ::empty?

    Returns whether ENV is empty.

  • .has_value?, ::value?

    Returns whether the given value is in ENV.

  • .include?, .has_key?, .key?, ::member?

    Returns whether the given name

    is in \ENV.
  • ::key

    Returns the name of the first entry with the given value.

  • .size, ::length

    Returns the number of entries.

  • ::value?

    Returns whether any entry has the given value.

Methods for Assigning

  • .[]=, ::store

    Creates, updates, or deletes the named environment variable.

  • ::clear

    Removes every environment variable; returns ENV:

  • .update, ::merge!

    Adds to ENV each key/value pair in the given hash.

  • ::replace

    Replaces the entire content of the ENV with the name/value pairs in the given hash.

Methods for Deleting

  • ::delete

    Deletes the named environment variable name if it exists.

  • ::delete_if

    Deletes entries selected by the block.

  • ::keep_if

    Deletes entries not selected by the block.

  • ::reject!

    Similar to #delete_if, but returns nil if no change was made.

  • .select!, ::filter!

    Deletes entries selected by the block.

  • ::shift

    Removes and returns the first entry.

Methods for Iterating

  • .each, ::each_pair

    Calls the block with each name/value pair.

  • ::each_key

    Calls the block with each name.

  • ::each_value

    Calls the block with each value.

Methods for Converting

  • ::assoc

    Returns a 2-element array containing the name and value of the named environment variable if it exists:

  • ::clone

    Returns ENV (and issues a warning).

  • ::except

    Returns a hash of all name/value pairs except those given.

  • ::fetch

    Returns the value for the given name.

  • ::inspect

    Returns the contents of ENV as a string.

  • ::invert

    Returns a hash whose keys are the ENV values,

    and whose values are the corresponding ENV names.
  • ::keys

    Returns an array of all names.

  • ::rassoc

    Returns the name and value of the first found entry that has the given value.

  • ::reject

    Returns a hash of those entries not rejected by the block.

  • .select, ::filter

    Returns a hash of name/value pairs selected by the block.

  • ::slice

    Returns a hash of the given names and their corresponding values.

  • ::to_a

    Returns the entries as an array of 2-element Arrays.

  • ::to_h

    Returns a hash of entries selected by the block.

  • ::to_hash

    Returns a hash of all entries.

  • ::to_s

    Returns the string 'ENV'.

  • ::values

    Returns all values as an array.

  • ::values_at

    Returns an array of the values for the given name.

More Methods

  • ::dup

    Raises an exception.

  • ::freeze

    Raises an exception.

  • ::rehash

    Returns nil, without modifying ENV.

Class Attribute Summary

  • .empty? ⇒ Boolean readonly

    Returns true when there are no environment variables, false otherwise:

Class Method Summary

::Enumerable - Extended

all?

Returns whether every element meets a given criterion.

any?

Returns whether any element meets a given criterion.

chain

Returns an enumerator object generated from this enumerator and given enumerables.

chunk

Each element in the returned enumerator is a 2-element array consisting of:

chunk_while

Creates an enumerator for each chunked elements.

collect

Alias for Enumerable#map.

collect_concat
compact

Returns an array of all non-nil elements:

count

Returns the count of elements, based on an argument or block criterion, if given.

cycle

When called with positive integer argument n and a block, calls the block with each element, then does so again, until it has done so n times; returns nil:

detect

Alias for Enumerable#find.

drop

For positive integer n, returns an array containing all but the first n elements:

drop_while

Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements after that point:

each_cons

Calls the block with each successive overlapped n-tuple of elements; returns self:

each_entry

Calls the given block with each element, converting multiple values from yield to an array; returns self:

each_slice

Calls the block with each successive disjoint n-tuple of elements; returns self:

each_with_index

With a block given, calls the block with each element and its index; returns self:

each_with_object

Calls the block once for each element, passing both the element and the given object:

entries

Alias for Enumerable#to_a.

filter

Returns an array containing elements selected by the block.

filter_map

Returns an array containing truthy elements returned by the block.

find

Returns the first element for which the block returns a truthy value.

find_all
find_index

Returns the index of the first element that meets a specified criterion, or nil if no such element is found.

first

Returns the first element or elements.

flat_map

Returns an array of flattened objects returned by the block.

grep

Returns an array of objects based elements of self that match the given pattern.

grep_v

Returns an array of objects based on elements of self that don’t match the given pattern.

group_by

With a block given returns a hash:

include?
inject

Returns an object formed from operands via either:

lazy

Returns an ::Enumerator::Lazy, which redefines most ::Enumerable methods to postpone enumeration and enumerate values only on an as-needed basis.

map

Returns an array of objects returned by the block.

max

Returns the element with the maximum element according to a given criterion.

max_by

Returns the elements for which the block returns the maximum values.

member?

Returns whether for any element object == element:

min

Returns the element with the minimum element according to a given criterion.

min_by

Returns the elements for which the block returns the minimum values.

minmax

Returns a 2-element array containing the minimum and maximum elements according to a given criterion.

minmax_by

Returns a 2-element array containing the elements for which the block returns minimum and maximum values:

none?

Returns whether no element meets a given criterion.

one?

Returns whether exactly one element meets a given criterion.

partition

With a block given, returns an array of two arrays:

reduce
reject

Returns an array of objects rejected by the block.

reverse_each

With a block given, calls the block with each element, but in reverse order; returns self:

select
slice_after

Creates an enumerator for each chunked elements.

slice_before

With argument pattern, returns an enumerator that uses the pattern to partition elements into arrays (“slices”).

slice_when

Creates an enumerator for each chunked elements.

sort

Returns an array containing the sorted elements of self.

sort_by

With a block given, returns an array of elements of self, sorted according to the value returned by the block for each element.

sum

With no block given, returns the sum of initial_value and the elements:

take

For non-negative integer n, returns the first n elements:

take_while

Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements up to that point:

tally

Returns a hash containing the counts of equal elements:

to_a

Returns an array containing the items in self:

to_h

When self consists of 2-element arrays, returns a hash each of whose entries is the key-value pair formed from one of those arrays:

uniq

With no block, returns a new array containing only unique elements; the array has no two elements e0 and e1 such that e0.eql?(e1):

zip

With no block given, returns a new array new_array of size self.size whose elements are arrays.

Class Attribute Details

.empty?Boolean (readonly)

Returns true when there are no environment variables, false otherwise:

ENV.clear
ENV.empty? # => true
ENV['foo'] = '0'
ENV.empty? # => false
[ GitHub ]

  
# File 'hash.c', line 6098

static VALUE
env_empty_p(VALUE _)
{
    bool empty = true;

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);
        if (env[0] != 0) {
            empty = false;
        }
	FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    return RBOOL(empty);
}

Class Method Details

.[](name) ⇒ value

Returns the value for the environment variable name if it exists:

ENV['foo'] = '0'
ENV['foo'] # => "0"

Returns nil if the named variable does not exist.

Raises an exception if name is invalid. See Invalid Names and Values.

[ GitHub ]

  
# File 'hash.c', line 5014

static VALUE
rb_f_getenv(VALUE obj, VALUE name)
{
    const char *nam = env_name(name);
    VALUE env = getenv_with_lock(nam);
    return env;
}

.[]=(name, value) ⇒ value .store(name, value) ⇒ value
Also known as: .store

.store is an alias for []=.

Creates, updates, or deletes the named environment variable, returning the value. Both name and value may be instances of ::String. See Valid Names and Values.

  • If the named environment variable does not exist:

    • If value is nil, does nothing.

      ENV.clear
      ENV['foo'] = nil # => nil
      ENV.include?('foo') # => false
      ENV.store('bar', nil) # => nil
      ENV.include?('bar') # => false
    • If value is not nil, creates the environment variable with name and value:

      # Create 'foo' using ENV.[]=.
      ENV['foo'] = '0' # => '0'
      ENV['foo'] # => '0'
      # Create 'bar' using ENV.store.
      ENV.store('bar', '1') # => '1'
      ENV['bar'] # => '1'
  • If the named environment variable exists:

    • If value is not nil, updates the environment variable with value value:

      # Update 'foo' using ENV.[]=.
      ENV['foo'] = '2' # => '2'
      ENV['foo'] # => '2'
      # Update 'bar' using ENV.store.
      ENV.store('bar', '3') # => '3'
      ENV['bar'] # => '3'
    • If value is nil, deletes the environment variable:

      # Delete 'foo' using ENV.[]=.
      ENV['foo'] = nil # => nil
      ENV.include?('foo') # => false
      # Delete 'bar' using ENV.store.
      ENV.store('bar', nil) # => nil
      ENV.include?('bar') # => false

Raises an exception if name or value is invalid. See Invalid Names and Values.

[ GitHub ]

  
# File 'hash.c', line 5402

static VALUE
env_aset_m(VALUE obj, VALUE nm, VALUE val)
{
    return env_aset(nm, val);
}

.assoc(name) ⇒ Array, value

Returns a 2-element ::Array containing the name and value of the environment variable for name if it exists:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.assoc('foo') # => ['foo', '0']

Returns nil if name is a valid ::String and there is no such environment variable.

Returns nil if name is the empty ::String or is a ::String containing character '='.

Raises an exception if name is a ::String containing the NUL character "\0":

ENV.assoc("\0") # Raises ArgumentError (bad environment variable name: contains null byte)

Raises an exception if name has an encoding that is not ASCII-compatible:

ENV.assoc("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
# Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)

Raises an exception if name is not a ::String:

ENV.assoc(Object.new) # TypeError (no implicit conversion of Object into String)
[ GitHub ]

  
# File 'hash.c', line 6168

static VALUE
env_assoc(VALUE env, VALUE key)
{
    const char *s = env_name(key);
    VALUE e = getenv_with_lock(s);

    if (!NIL_P(e)) {
        return rb_assoc_new(key, e);
    }
    else {
        return Qnil;
    }
}

.clearENV

Removes every environment variable; returns ENV:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.size # => 2
ENV.clear # => ENV
ENV.size # => 0
[ GitHub ]

  
# File 'hash.c', line 5950

static VALUE
env_clear(VALUE _)
{
    return rb_env_clear();
}

.clone(freeze: nil) ⇒ ENV

Returns ENV itself, and warns because ENV is a wrapper for the process-wide environment variables and a clone is useless. If .freeze keyword is given and not nil or false, raises ::ArgumentError. If .freeze keyword is given and true, raises ::TypeError, as ENV storage cannot be frozen.

[ GitHub ]

  
# File 'hash.c', line 6653

static VALUE
env_clone(int argc, VALUE *argv, VALUE obj)
{
    if (argc) {
        VALUE opt, kwfreeze;
        if (rb_scan_args(argc, argv, "0:", &opt) < argc) {
            kwfreeze = rb_get_freeze_opt(1, &opt);
            if (RTEST(kwfreeze)) {
                rb_raise(rb_eTypeError, "cannot freeze ENV");
            }
        }
    }

    rb_warn_deprecated("ENV.clone", "ENV.to_h");
    return envtbl;
}

.delete(name) ⇒ value .delete(name) {|name| ... } ⇒ value .delete(missing_name) ⇒ nil .delete(missing_name) {|name| ... } ⇒ block_value

Deletes the environment variable with name if it exists and returns its value:

ENV['foo'] = '0'
ENV.delete('foo') # => '0'

If a block is not given and the named environment variable does not exist, returns nil.

If a block given and the environment variable does not exist, yields name to the block and returns the value of the block:

ENV.delete('foo') { |name| name * 2 } # => "foofoo"

If a block given and the environment variable exists, deletes the environment variable and returns its value (ignoring the block):

ENV['foo'] = '0'
ENV.delete('foo') { |name| raise 'ignored' } # => "0"

Raises an exception if name is invalid. See Invalid Names and Values.

[ GitHub ]

  
# File 'hash.c', line 4992

static VALUE
env_delete_m(VALUE obj, VALUE name)
{
    VALUE val;

    val = env_delete(name);
    if (NIL_P(val) && rb_block_given_p()) val = rb_yield(name);
    return val;
}

.delete_if {|name, value| ... } ⇒ ENV .delete_ifEnumerator

Yields each environment variable name and its value as a 2-element ::Array, deleting each environment variable for which the block returns a truthy value, and returning ENV (regardless of whether any deletions):

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.delete_if { |name, value| name.start_with?('b') } # => ENV
ENV # => {"foo"=>"0"}
ENV.delete_if { |name, value| name.start_with?('b') } # => ENV

Returns an ::Enumerator if no block given:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
e = ENV.delete_if # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:delete_if!>
e.each { |name, value| name.start_with?('b') } # => ENV
ENV # => {"foo"=>"0"}
e.each { |name, value| name.start_with?('b') } # => ENV
[ GitHub ]

  
# File 'hash.c', line 5721

static VALUE
env_delete_if(VALUE ehash)
{
    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    env_reject_bang(ehash);
    return envtbl;
}

.dup(# raises TypeError)

Raises TypeError, because ENV is a singleton object. Use #to_h to get a copy of ENV data as a hash.

[ GitHub ]

  
# File 'hash.c', line 6678

static VALUE
env_dup(VALUE obj)
{
    rb_raise(rb_eTypeError, "Cannot dup ENV, use ENV.to_h to get a copy of ENV as a hash");
}

.each {|name, value| ... } ⇒ ENV .eachEnumerator .each_pair {|name, value| ... } ⇒ ENV .each_pairEnumerator
Also known as: .each_pair

Yields each environment variable name and its value as a 2-element Array:

h = {}
ENV.each_pair { |name, value| h[name] = value } # => ENV
h # => {"bar"=>"1", "foo"=>"0"}

Returns an ::Enumerator if no block given:

h = {}
e = ENV.each_pair # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_pair>
e.each { |name, value| h[name] = value } # => ENV
h # => {"bar"=>"1", "foo"=>"0"}
[ GitHub ]

  
# File 'hash.c', line 5616

static VALUE
env_each_pair(VALUE ehash)
{
    long i;

    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);

    VALUE ary = rb_ary_new();

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);

        while (*env) {
            char *s = strchr(*env, '=');
            if (s) {
                rb_ary_push(ary, env_str_new(*env, s-*env));
                rb_ary_push(ary, env_str_new2(s+1));
            }
            env++;
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    if (rb_block_pair_yield_optimizable()) {
        for (i=0; i<RARRAY_LEN(ary); i+=2) {
	    rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
	}
    }
    else {
	for (i=0; i<RARRAY_LEN(ary); i+=2) {
	    rb_yield(rb_assoc_new(RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1)));
	}
    }

    return ehash;
}

.each_key {|name| ... } ⇒ ENV .each_keyEnumerator

Yields each environment variable name:

ENV.replace('foo' => '0', 'bar' => '1') # => ENV
names = []
ENV.each_key { |name| names.push(name) } # => ENV
names # => ["bar", "foo"]

Returns an ::Enumerator if no block given:

e = ENV.each_key # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_key>
names = []
e.each { |name| names.push(name) } # => ENV
names # => ["bar", "foo"]
[ GitHub ]

  
# File 'hash.c', line 5512

static VALUE
env_each_key(VALUE ehash)
{
    VALUE keys;
    long i;

    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    keys = env_keys(FALSE);
    for (i=0; i<RARRAY_LEN(keys); i++) {
	rb_yield(RARRAY_AREF(keys, i));
    }
    return ehash;
}

.each {|name, value| ... } ⇒ ENV .eachEnumerator .each_pair {|name, value| ... } ⇒ ENV .each_pairEnumerator

Alias for .each.

.each_value {|value| ... } ⇒ ENV .each_valueEnumerator

Yields each environment variable value:

ENV.replace('foo' => '0', 'bar' => '1') # => ENV
values = []
ENV.each_value { |value| values.push(value) } # => ENV
values # => ["1", "0"]

Returns an ::Enumerator if no block given:

e = ENV.each_value # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_value>
values = []
e.each { |value| values.push(value) } # => ENV
values # => ["1", "0"]
[ GitHub ]

  
# File 'hash.c', line 5584

static VALUE
env_each_value(VALUE ehash)
{
    VALUE values;
    long i;

    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    values = env_values();
    for (i=0; i<RARRAY_LEN(values); i++) {
	rb_yield(RARRAY_AREF(values, i));
    }
    return ehash;
}

.except(*keys) ⇒ 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"}
[ GitHub ]

  
# File 'hash.c', line 6398

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;
}

.fetch(name) ⇒ value .fetch(name, default) ⇒ value .fetch(name) {|name| ... } ⇒ value

If name is the name of an environment variable, returns its value:

ENV['foo'] = '0'
ENV.fetch('foo') # => '0'

Otherwise if a block is given (but not a default value), yields name to the block and returns the block’s return value:

ENV.fetch('foo') { |name| :need_not_return_a_string } # => :need_not_return_a_string

Otherwise if a default value is given (but not a block), returns the default value:

ENV.delete('foo')
ENV.fetch('foo', :default_need_not_be_a_string) # => :default_need_not_be_a_string

If the environment variable does not exist and both default and block are given, issues a warning (“warning: block supersedes default value argument”), yields name to the block, and returns the block’s return value:

ENV.fetch('foo', :default) { |name| :block_return } # => :block_return

Raises KeyError if name is valid, but not found, and neither default value nor block is given:

ENV.fetch('foo') # Raises KeyError (key not found: "foo")

Raises an exception if name is invalid. See Invalid Names and Values.

[ GitHub ]

  
# File 'hash.c', line 5047

static VALUE
env_fetch(int argc, VALUE *argv, VALUE _)
{
    VALUE key;
    long block_given;
    const char *nam;
    VALUE env;

    rb_check_arity(argc, 1, 2);
    key = argv[0];
    block_given = rb_block_given_p();
    if (block_given && argc == 2) {
	rb_warn("block supersedes default value argument");
    }
    nam = env_name(key);
    env = getenv_with_lock(nam);

    if (NIL_P(env)) {
	if (block_given) return rb_yield(key);
	if (argc == 1) {
	    rb_key_err_raise(rb_sprintf("key not found: \"%"PRIsVALUE"\"", key), envtbl, key);
	}
	return argv[1];
    }
    return env;
}

.select {|name, value| ... } ⇒ hash of name/value pairs .selectEnumerator .filter {|name, value| ... } ⇒ hash of name/value pairs .filterEnumerator
Also known as: .select

filter is an alias for .select.

Yields each environment variable name and its value as a 2-element ::Array, returning a ::Hash of the names and values for which the block returns a truthy value:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.select { |name, value| name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
ENV.filter { |name, value| name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}

Returns an ::Enumerator if no block given:

e = ENV.select # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:select>
e.each { |name, value | name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
e = ENV.filter # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:filter>
e.each { |name, value | name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
[ GitHub ]

  
# File 'hash.c', line 5780

static VALUE
env_select(VALUE ehash)
{
    VALUE result;
    VALUE keys;
    long i;

    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    result = rb_hash_new();
    keys = env_keys(FALSE);
    for (i = 0; i < RARRAY_LEN(keys); ++i) {
	VALUE key = RARRAY_AREF(keys, i);
	VALUE val = rb_f_getenv(Qnil, key);
	if (!NIL_P(val)) {
	    if (RTEST(rb_yield_values(2, key, val))) {
		rb_hash_aset(result, key, val);
	    }
	}
    }
    RB_GC_GUARD(keys);

    return result;
}

.select! {|name, value| ... } ⇒ ENV? .select!Enumerator .filter! {|name, value| ... } ⇒ ENV? .filter!Enumerator
Also known as: .select!

filter! is an alias for .select!.

Yields each environment variable name and its value as a 2-element ::Array, deleting each entry for which the block returns false or nil, and returning ENV if any deletions made, or nil otherwise:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.select! { |name, value| name.start_with?('b') } # => ENV
ENV # => {"bar"=>"1", "baz"=>"2"}
ENV.select! { |name, value| true } # => nil

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.filter! { |name, value| name.start_with?('b') } # => ENV
ENV # => {"bar"=>"1", "baz"=>"2"}
ENV.filter! { |name, value| true } # => nil

Returns an ::Enumerator if no block given:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
e = ENV.select! # => #<Enumerator: {"bar"=>"1", "baz"=>"2"}:select!>
e.each { |name, value| name.start_with?('b') } # => ENV
ENV # => {"bar"=>"1", "baz"=>"2"}
e.each { |name, value| true } # => nil

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
e = ENV.filter! # => #<Enumerator: {"bar"=>"1", "baz"=>"2"}:filter!>
e.each { |name, value| name.start_with?('b') } # => ENV
ENV # => {"bar"=>"1", "baz"=>"2"}
e.each { |name, value| true } # => nil
[ GitHub ]

  
# File 'hash.c', line 5841

static VALUE
env_select_bang(VALUE ehash)
{
    VALUE keys;
    long i;
    int del = 0;

    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    keys = env_keys(FALSE);
    RBASIC_CLEAR_CLASS(keys);
    for (i=0; i<RARRAY_LEN(keys); i++) {
	VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
	if (!NIL_P(val)) {
	    if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
                env_delete(RARRAY_AREF(keys, i));
		del++;
	    }
	}
    }
    RB_GC_GUARD(keys);
    if (del == 0) return Qnil;
    return envtbl;
}

.freeze

Raises an exception:

ENV.freeze # Raises TypeError (cannot freeze ENV)
[ GitHub ]

  
# File 'hash.c', line 6441

static VALUE
env_freeze(VALUE self)
{
    rb_raise(rb_eTypeError, "cannot freeze ENV");
    UNREACHABLE_RETURN(self);
}

.include?(name) ⇒ Boolean .has_key?(name) ⇒ Boolean .member?(name) ⇒ Boolean .key?(name) ⇒ Boolean

Alias for .key?.

.value?(value) ⇒ Boolean .has_value?(value) ⇒ Boolean

Alias for .value?.

.include?(name) ⇒ Boolean .has_key?(name) ⇒ Boolean .member?(name) ⇒ Boolean .key?(name) ⇒ Boolean

Alias for .key?.

.inspectString

Returns the contents of the environment as a ::String:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.inspect # => "{\"bar\"=>\"1\", \"foo\"=>\"0\"}"
[ GitHub ]

  
# File 'hash.c', line 5977

static VALUE
env_inspect(VALUE _)
{
    VALUE i;
    VALUE str = rb_str_buf_new2("{");

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);
        while (*env) {
            char *s = strchr(*env, '=');

            if (env != environ) {
                rb_str_buf_cat2(str, ", ");
            }
            if (s) {
                rb_str_buf_cat2(str, "\"");
                rb_str_buf_cat(str, *env, s-*env);
                rb_str_buf_cat2(str, "\"=>");
                i = rb_inspect(rb_str_new2(s+1));
                rb_str_buf_append(str, i);
            }
            env++;
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    rb_str_buf_cat2(str, "}");

    return str;
}

.inverthash of value/name pairs

Returns a ::Hash whose keys are the ENV values, and whose values are the corresponding ENV names:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.invert # => {"1"=>"bar", "0"=>"foo"}

For a duplicate ENV value, overwrites the hash entry:

ENV.replace('foo' => '0', 'bar' => '0')
ENV.invert # => {"0"=>"foo"}

Note that the order of the ENV processing is OS-dependent, which means that the order of overwriting is also OS-dependent. See About Ordering.

[ GitHub ]

  
# File 'hash.c', line 6507

static VALUE
env_invert(VALUE _)
{
    return rb_hash_invert(env_to_hash());
}

.keep_if {|name, value| ... } ⇒ ENV .keep_ifEnumerator

Yields each environment variable name and its value as a 2-element ::Array, deleting each environment variable for which the block returns false or nil, and returning ENV:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.keep_if { |name, value| name.start_with?('b') } # => ENV
ENV # => {"bar"=>"1", "baz"=>"2"}

Returns an ::Enumerator if no block given:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
e = ENV.keep_if # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:keep_if>
e.each { |name, value| name.start_with?('b') } # => ENV
ENV # => {"bar"=>"1", "baz"=>"2"}
[ GitHub ]

  
# File 'hash.c', line 5883

static VALUE
env_keep_if(VALUE ehash)
{
    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    env_select_bang(ehash);
    return envtbl;
}

.key(value) ⇒ name?

Returns the name of the first environment variable with value, if it exists:

ENV.replace('foo' => '0', 'bar' => '0')
ENV.key('0') # => "foo"

The order in which environment variables are examined is OS-dependent. See About Ordering.

Returns nil if there is no such value.

Raises an exception if value is invalid:

ENV.key(Object.new) # raises TypeError (no implicit conversion of Object into String)

See Invalid Names and Values.

[ GitHub ]

  
# File 'hash.c', line 6284

static VALUE
env_key(VALUE dmy, VALUE value)
{
    SafeStringValue(value);
    VALUE str = Qnil;

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);
        while (*env) {
            char *s = strchr(*env, '=');
            if (s++) {
                long len = strlen(s);
                if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
                    str = env_str_new(*env, s-*env-1);
                    break;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    return str;
}

.include?(name) ⇒ Boolean .has_key?(name) ⇒ Boolean .member?(name) ⇒ Boolean .key?(name) ⇒ Boolean
Also known as: .include?, .member?, .has_key?

.has_key?, .member?, and key? are aliases for .include?.

Returns true if there is an environment variable with the given name:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.include?('foo') # => true

Returns false if name is a valid ::String and there is no such environment variable:

ENV.include?('baz') # => false

Returns false if name is the empty ::String or is a ::String containing character '=':

ENV.include?('') # => false
ENV.include?('=') # => false

Raises an exception if name is a ::String containing the NUL character "\0":

ENV.include?("\0") # Raises ArgumentError (bad environment variable name: contains null byte)

Raises an exception if name has an encoding that is not ASCII-compatible:

ENV.include?("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
# Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)

Raises an exception if name is not a ::String:

ENV.include?(Object.new) # TypeError (no implicit conversion of Object into String)
[ GitHub ]

  
# File 'hash.c', line 6141

static VALUE
env_has_key(VALUE env, VALUE key)
{
    const char *s = env_name(key);
    return RBOOL(has_env_with_lock(s));
}

.keysarray of names

Returns all variable names in an ::Array:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.keys # => ['bar', 'foo']

The order of the names is OS-dependent. See About Ordering.

Returns the empty ::Array if ENV is empty.

[ GitHub ]

  
# File 'hash.c', line 5468

static VALUE
env_f_keys(VALUE _)
{
    return env_keys(FALSE);
}

.lengthInteger .sizeInteger
Also known as: .size

Returns the count of environment variables:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.length # => 2
ENV.size # => 2
[ GitHub ]

  
# File 'hash.c', line 6082

static VALUE
env_size(VALUE _)
{
    return INT2FIX(env_size_with_lock());
}

.include?(name) ⇒ Boolean .has_key?(name) ⇒ Boolean .member?(name) ⇒ Boolean .key?(name) ⇒ Boolean

Alias for .key?.

.update(hash) ⇒ ENV .update(hash) {|name, env_val, hash_val| ... } ⇒ ENV .merge!(hash) ⇒ ENV .merge!(hash) {|name, env_val, hash_val| ... } ⇒ ENV
Also known as: .update

.update is an alias for merge!.

Adds to ENV each key/value pair in the given hash; returns ENV:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.merge!('baz' => '2', 'bat' => '3') # => {"bar"=>"1", "bat"=>"3", "baz"=>"2", "foo"=>"0"}

Deletes the ENV entry for a hash value that is nil:

ENV.merge!('baz' => nil, 'bat' => nil) # => {"bar"=>"1", "foo"=>"0"}

For an already-existing name, if no block given, overwrites the ENV value:

ENV.merge!('foo' => '4') # => {"bar"=>"1", "foo"=>"4"}

For an already-existing name, if block given, yields the name, its ENV value, and its hash value; the block’s return value becomes the new name:

ENV.merge!('foo' => '5') { |name, env_val, hash_val | env_val + hash_val } # => {"bar"=>"1", "foo"=>"45"}

Raises an exception if a name or value is invalid (see Invalid Names and Values);

ENV.replace('foo' => '0', 'bar' => '1')
ENV.merge!('foo' => '6', :bar => '7', 'baz' => '9') # Raises TypeError (no implicit conversion of Symbol into String)
ENV # => {"bar"=>"1", "foo"=>"6"}
ENV.merge!('foo' => '7', 'bar' => 8, 'baz' => '9') # Raises TypeError (no implicit conversion of Integer into String)
ENV # => {"bar"=>"1", "foo"=>"7"}

Raises an exception if the block returns an invalid name: (see Invalid Names and Values):

ENV.merge!('bat' => '8', 'foo' => '9') { |name, env_val, hash_val | 10 } # Raises TypeError (no implicit conversion of Integer into String)
ENV # => {"bar"=>"1", "bat"=>"8", "foo"=>"7"}

Note that for the exceptions above, hash pairs preceding an invalid name or value are processed normally; those following are ignored.

[ GitHub ]

  
# File 'hash.c', line 6632

static VALUE
env_update(VALUE env, VALUE hash)
{
    if (env == hash) return env;
    hash = to_hash(hash);
    rb_foreach_func *func = rb_block_given_p() ?
        env_update_block_i : env_update_i;
    rb_hash_foreach(hash, func, 0);
    return env;
}

.rassoc(value) ⇒ Array, value

Returns a 2-element ::Array containing the name and value of the first found environment variable that has value value, if one exists:

ENV.replace('foo' => '0', 'bar' => '0')
ENV.rassoc('0') # => ["bar", "0"]

The order in which environment variables are examined is OS-dependent. See About Ordering.

Returns nil if there is no such environment variable.

[ GitHub ]

  
# File 'hash.c', line 6237

static VALUE
env_rassoc(VALUE dmy, VALUE obj)
{
    obj = rb_check_string_type(obj);
    if (NIL_P(obj)) return Qnil;

    VALUE result = Qnil;

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);

        while (*env) {
            const char *p = *env;
            char *s = strchr(p, '=');
            if (s++) {
                long len = strlen(s);
                if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
                    result = rb_assoc_new(rb_str_new(p, s-p-1), obj);
                    break;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    return result;
}

.rehashnil

(Provided for compatibility with ::Hash.)

Does not modify ENV; returns nil.

[ GitHub ]

  
# File 'hash.c', line 6050

static VALUE
env_none(VALUE _)
{
    return Qnil;
}

.reject {|name, value| ... } ⇒ hash of name/value pairs .rejectEnumerator

Yields each environment variable name and its value as a 2-element ::Array. Returns a ::Hash whose items are determined by the block. When the block returns a truthy value, the name/value pair is added to the return Hash; otherwise the pair is ignored:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.reject { |name, value| name.start_with?('b') } # => {"foo"=>"0"}

Returns an ::Enumerator if no block given:

e = ENV.reject
e.each { |name, value| name.start_with?('b') } # => {"foo"=>"0"}
[ GitHub ]

  
# File 'hash.c', line 6427

static VALUE
env_reject(VALUE _)
{
    return rb_hash_delete_if(env_to_hash());
}

.reject! {|name, value| ... } ⇒ ENV? .reject!Enumerator

Similar to .delete_if, but returns nil if no changes were made.

Yields each environment variable name and its value as a 2-element ::Array, deleting each environment variable for which the block returns a truthy value, and returning ENV (if any deletions) or nil (if not):

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.reject! { |name, value| name.start_with?('b') } # => ENV
ENV # => {"foo"=>"0"}
ENV.reject! { |name, value| name.start_with?('b') } # => nil

Returns an ::Enumerator if no block given:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
e = ENV.reject! # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:reject!>
e.each { |name, value| name.start_with?('b') } # => ENV
ENV # => {"foo"=>"0"}
e.each { |name, value| name.start_with?('b') } # => nil
[ GitHub ]

  
# File 'hash.c', line 5677

static VALUE
env_reject_bang(VALUE ehash)
{
    VALUE keys;
    long i;
    int del = 0;

    RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
    keys = env_keys(FALSE);
    RBASIC_CLEAR_CLASS(keys);
    for (i=0; i<RARRAY_LEN(keys); i++) {
	VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
	if (!NIL_P(val)) {
	    if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
                env_delete(RARRAY_AREF(keys, i));
		del++;
	    }
	}
    }
    RB_GC_GUARD(keys);
    if (del == 0) return Qnil;
    return envtbl;
}

.replace(hash) ⇒ ENV

Replaces the entire content of the environment variables with the name/value pairs in the given hash; returns ENV.

Replaces the content of ENV with the given pairs:

ENV.replace('foo' => '0', 'bar' => '1') # => ENV
ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}

Raises an exception if a name or value is invalid (see Invalid Names and Values):

ENV.replace('foo' => '0', :bar => '1') # Raises TypeError (no implicit conversion of Symbol into String)
ENV.replace('foo' => '0', 'bar' => 1) # Raises TypeError (no implicit conversion of Integer into String)
ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
[ GitHub ]

  
# File 'hash.c', line 6560

static VALUE
env_replace(VALUE env, VALUE hash)
{
    VALUE keys;
    long i;

    keys = env_keys(TRUE);
    if (env == hash) return env;
    hash = to_hash(hash);
    rb_hash_foreach(hash, env_replace_i, keys);

    for (i=0; i<RARRAY_LEN(keys); i++) {
        env_delete(RARRAY_AREF(keys, i));
    }
    RB_GC_GUARD(keys);
    return env;
}

.select {|name, value| ... } ⇒ hash of name/value pairs .selectEnumerator .filter {|name, value| ... } ⇒ hash of name/value pairs .filterEnumerator

Alias for .filter.

.select! {|name, value| ... } ⇒ ENV? .select!Enumerator .filter! {|name, value| ... } ⇒ ENV? .filter!Enumerator

Alias for .filter!.

.shiftArray, value

Removes the first environment variable from ENV and returns a 2-element ::Array containing its name and value:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.to_hash # => {'bar' => '1', 'foo' => '0'}
ENV.shift # => ['bar', '1']
ENV.to_hash # => {'foo' => '0'}

Exactly which environment variable is “first” is OS-dependent. See About Ordering.

Returns nil if the environment is empty.

[ GitHub ]

  
# File 'hash.c', line 6463

static VALUE
env_shift(VALUE _)
{
    VALUE result = Qnil;
    VALUE key = Qnil;

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);
        if (*env) {
            const char *p = *env;
            char *s = strchr(p, '=');
            if (s) {
                key = env_str_new(p, s-p);
                VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
                result = rb_assoc_new(key, val);
            }
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    if (!NIL_P(key)) {
        env_delete(key);
    }

    return result;
}

.lengthInteger .sizeInteger

Alias for .length.

.slice(*names) ⇒ hash of name/value pairs

Returns a ::Hash of the given ENV names and their corresponding values:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2', 'bat' => '3')
ENV.slice('foo', 'baz') # => {"foo"=>"0", "baz"=>"2"}
ENV.slice('baz', 'foo') # => {"baz"=>"2", "foo"=>"0"}

Raises an exception if any of the names is invalid (see Invalid Names and Values):

ENV.slice('foo', 'bar', :bat) # Raises TypeError (no implicit conversion of Symbol into String)
[ GitHub ]

  
# File 'hash.c', line 5903

static VALUE
env_slice(int argc, VALUE *argv, VALUE _)
{
    int i;
    VALUE key, value, result;

    if (argc == 0) {
        return rb_hash_new();
    }
    result = rb_hash_new_with_size(argc);

    for (i = 0; i < argc; i++) {
        key = argv[i];
        value = rb_f_getenv(Qnil, key);
        if (value != Qnil)
            rb_hash_aset(result, key, value);
    }

    return result;
}

.[]=(name, value) ⇒ value .store(name, value) ⇒ value

Alias for .[]=.

.to_aarray of 2-element arrays

Returns the contents of ENV as an ::Array of 2-element Arrays, each of which is a name/value pair:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.to_a # => [["bar", "1"], ["foo", "0"]]
[ GitHub ]

  
# File 'hash.c', line 6019

static VALUE
env_to_a(VALUE _)
{
    VALUE ary = rb_ary_new();

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);
        while (*env) {
            char *s = strchr(*env, '=');
            if (s) {
                rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
                                              env_str_new2(s+1)));
            }
            env++;
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    return ary;
}

.to_hhash of name/value pairs .to_h {|name, value| ... } ⇒ hash of name/value pairs

With no block, returns a ::Hash containing all name/value pairs from ENV:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.to_h # => {"bar"=>"1", "foo"=>"0"}

With a block, returns a ::Hash whose items are determined by the block. Each name/value pair in ENV is yielded to the block. The block must return a 2-element ::Array (name/value pair) that is added to the return ::Hash as a key and value:

ENV.to_h { |name, value| [name.to_sym, value.to_i] } # => {:bar=>1, :foo=>0}

Raises an exception if the block does not return an ::Array:

ENV.to_h { |name, value| name } # Raises TypeError (wrong element type String (expected array))

Raises an exception if the block returns an ::Array of the wrong size:

ENV.to_h { |name, value| [name] } # Raises ArgumentError (element has wrong array length (expected 2, was 1))
[ GitHub ]

  
# File 'hash.c', line 6379

static VALUE
env_to_h(VALUE _)
{
    VALUE hash = env_to_hash();
    if (rb_block_given_p()) {
        hash = rb_hash_to_h_block(hash);
    }
    return hash;
}

.to_hashhash of name/value pairs

Returns a ::Hash containing all name/value pairs from ENV:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
[ GitHub ]

  
# File 'hash.c', line 6355

static VALUE
env_f_to_hash(VALUE _)
{
    return env_to_hash();
}

.to_sENV

Returns String ‘ENV’:

ENV.to_s # => "ENV"
[ GitHub ]

  
# File 'hash.c', line 5963

static VALUE
env_to_s(VALUE _)
{
    return rb_usascii_str_new2("ENV");
}

.update(hash) ⇒ ENV .update(hash) {|name, env_val, hash_val| ... } ⇒ ENV .merge!(hash) ⇒ ENV .merge!(hash) {|name, env_val, hash_val| ... } ⇒ ENV

Alias for .merge!.

.value?(value) ⇒ Boolean .has_value?(value) ⇒ Boolean
Also known as: .has_value?

Returns true if value is the value for some environment variable name, false otherwise:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.value?('0') # => true
ENV.has_value?('0') # => true
ENV.value?('2') # => false
ENV.has_value?('2') # => false
[ GitHub ]

  
# File 'hash.c', line 6194

static VALUE
env_has_value(VALUE dmy, VALUE obj)
{
    obj = rb_check_string_type(obj);
    if (NIL_P(obj)) return Qnil;

    VALUE ret = Qfalse;

    ENV_LOCK();
    {
        char **env = GET_ENVIRON(environ);
        while (*env) {
            char *s = strchr(*env, '=');
            if (s++) {
                long len = strlen(s);
                if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
                    ret = Qtrue;
                    break;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
    }
    ENV_UNLOCK();

    return ret;
}

.valuesarray of values

Returns all environment variable values in an ::Array:

ENV.replace('foo' => '0', 'bar' => '1')
ENV.values # => ['1', '0']

The order of the values is OS-dependent. See About Ordering.

Returns the empty ::Array if ENV is empty.

[ GitHub ]

  
# File 'hash.c', line 5561

static VALUE
env_f_values(VALUE _)
{
    return env_values();
}

.values_at(*names) ⇒ array of values

Returns an ::Array containing the environment variable values associated with the given names:

ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
ENV.values_at('foo', 'baz') # => ["0", "2"]

Returns nil in the ::Array for each name that is not an ENV name:

ENV.values_at('foo', 'bat', 'bar', 'bam') # => ["0", nil, "1", nil]

Returns an empty Array if no names given.

Raises an exception if any name is invalid. See Invalid Names and Values.

[ GitHub ]

  
# File 'hash.c', line 5746

static VALUE
env_values_at(int argc, VALUE *argv, VALUE _)
{
    VALUE result;
    long i;

    result = rb_ary_new();
    for (i=0; i<argc; i++) {
	rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
    }
    return result;
}