# class ENV

`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 `ENV.keys`, `ENV.values`, or `ENV.to_a`.

- The `String` returned by `ENV.inspect`.

- The `Array` returned by `ENV.shift`.

- The name returned by `ENV.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:

- `ENV.replace` replaces `ENV` with a new collection of entries.

- `ENV.clear` empties `ENV`.

### Public Class Methods

ENV[name] → value click to toggle source

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:

    ENV.clear
    ENV['foo'] # => nil

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

    static VALUE
    rb_f_getenv(VALUE obj, VALUE name)
    {
        const char *nam, *env;

        nam = env_name(name);
        env = getenv(nam);
        if (env) {
            return env_name_new(nam, env);
        }
        return Qnil;
    }

ENV[name] = value → value click to toggle source

`ENV.store` is an alias for `ENV.[]=`.

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.

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

assoc(name) → Array or nil click to toggle source

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:

    ENV.assoc('baz') # => false

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

    ENV.assoc('') # => false
    ENV.assoc('=') # => false

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)

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

        s = env_name(key);
        e = getenv(s);
        if (e) return rb_assoc_new(key, env_str_new2(e));
        return Qnil;
    }

clear → ENV click to toggle source

Removes every environment variable; returns ENV:

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

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

delete(name) → value click to toggle source
delete(name) { |name| block } → value

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

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

Returns `nil` if the named environment variable does not exist:

    ENV.delete('foo') # => nil

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

    ENV.delete('foo') { |name| puts name } # => nil
    foo

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| fail 'ignored' } # => "0"

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

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

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

delete_if { |name, value| block } → ENV click to toggle source
delete_if → Enumerator

Deletes every environment variable for which the block evaluates to `true`.

If no block is given an enumerator is returned instead.

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

each { |name, value| block } → ENV click to toggle source
each → Enumerator
each_pair { |name, value| block } → ENV
each_pair → Enumerator

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

    static VALUE
    env_each_pair(VALUE ehash)
    {
        char **env;
        VALUE ary;
        long i;

        RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);

        ary = rb_ary_new();
        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);

        if (rb_block_arity() > 1) {
            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| block } → ENV click to toggle source
each_key → Enumerator

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"]

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

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

each_pair { |name, value| block } → ENV click to toggle source
each_pair → Enumerator

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

    static VALUE
    env_each_pair(VALUE ehash)
    {
        char **env;
        VALUE ary;
        long i;

        RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);

        ary = rb_ary_new();
        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);

        if (rb_block_arity() > 1) {
            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_value { |value| block } → ENV click to toggle source
each_value → Enumerator

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"]

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

empty? → true or false click to toggle source

Returns true when there are no environment variables

    static VALUE
    env_empty_p(VALUE _)
    {
        char **env;

        env = GET_ENVIRON(environ);
        if (env[0] == 0) {
            FREE_ENVIRON(environ);
            return Qtrue;
        }
        FREE_ENVIRON(environ);
        return Qfalse;
    }

fetch(name) → value click to toggle source
fetch(name, default) → value
fetch(name) { |name| block } → 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.

    static VALUE
    env_fetch(int argc, VALUE *argv, VALUE _)
    {
        VALUE key;
        long block_given;
        const char *nam, *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(nam);
        if (!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_name_new(nam, env);
    }

filter { |name, value| block } → Hash click to toggle source
filter → Enumerator

Returns a copy of the environment for entries where the block returns true.

Returns an `Enumerator` if no block was given.

`ENV.filter` is an alias for `ENV.select`.

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

filter! { |name, value| block } → ENV or nil click to toggle source
filter! → Enumerator

Equivalent to `ENV.keep_if` but returns `nil` if no changes were made.

`ENV.filter!` is an alias for `ENV.select!`.

    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();
        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 TypeError click to toggle source

Ruby does not allow `ENV` to be frozen, so calling `ENV.freeze` raises `TypeError`.

    static VALUE
    env_freeze(VALUE self)
    {
        rb_raise(rb_eTypeError, "cannot freeze ENV");
        return self; /* Not reached */
    }

has_key?(name) → true or false click to toggle source

`ENV.has_key?`, `ENV.member?`, and `ENV.key?` are aliases for `ENV.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)

    static VALUE
    env_has_key(VALUE env, VALUE key)
    {
        const char *s;

        s = env_name(key);
        if (getenv(s)) return Qtrue;
        return Qfalse;
    }

has_value?(value) → true or false click to toggle source

Returns `true` if there is an environment variable with the given `value`.

    static VALUE
    env_has_value(VALUE dmy, VALUE obj)
    {
        char **env;

        obj = rb_check_string_type(obj);
        if (NIL_P(obj)) return Qnil;
        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) {
                    FREE_ENVIRON(environ);
                    return Qtrue;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
        return Qfalse;
    }

include?(name) → true or false click to toggle source

`ENV.has_key?`, `ENV.member?`, and `ENV.key?` are aliases for `ENV.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)

    static VALUE
    env_has_key(VALUE env, VALUE key)
    {
        const char *s;

        s = env_name(key);
        if (getenv(s)) return Qtrue;
        return Qfalse;
    }

index(value) → key click to toggle source

Deprecated method that is equivalent to `ENV.key`

    static VALUE
    env_index(VALUE dmy, VALUE value)
    {
        rb_warn_deprecated("ENV.index", "ENV.key");
        return env_key(dmy, value);
    }

inspect → string click to toggle source

Returns the contents of the environment as a `String`.

    static VALUE
    env_inspect(VALUE _)
    {
        char **env;
        VALUE str, i;

        str = rb_str_buf_new2("{");
        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);
        rb_str_buf_cat2(str, "}");

        return str;
    }

invert → Hash click to toggle source

Returns a new hash created by using environment variable names as values and values as names.

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

keep_if { |name, value| block } → ENV click to toggle source
keep_if → Enumerator

Deletes every environment variable where the block evaluates to `false`.

Returns an enumerator if no block was given.

    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 or nil click to toggle source

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

    ENV.replace('foo' => '0', 'bar' => '1')
    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:

    ENV.key('2') # => nil

Raises an exception if `value` is not a String:

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

    static VALUE
    env_key(VALUE dmy, VALUE value)
    {
        char **env;
        VALUE str;

        SafeStringValue(value);
        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);
                    FREE_ENVIRON(environ);
                    return str;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
        return Qnil;
    }

key?(name) → true or false click to toggle source

`ENV.has_key?`, `ENV.member?`, and `ENV.key?` are aliases for `ENV.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)

    static VALUE
    env_has_key(VALUE env, VALUE key)
    {
        const char *s;

        s = env_name(key);
        if (getenv(s)) return Qtrue;
        return Qfalse;
    }

keys → Array click to toggle source

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:

    ENV.clear
    ENV.keys # => []

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

length click to toggle source

Returns the number of environment variables.

    static VALUE
    env_size(VALUE _)
    {
        int i;
        char **env;

        env = GET_ENVIRON(environ);
        for (i=0; env[i]; i++)
            ;
        FREE_ENVIRON(environ);
        return INT2FIX(i);
    }

member?(name) → true or false click to toggle source

`ENV.has_key?`, `ENV.member?`, and `ENV.key?` are aliases for `ENV.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)

    static VALUE
    env_has_key(VALUE env, VALUE key)
    {
        const char *s;

        s = env_name(key);
        if (getenv(s)) return Qtrue;
        return Qfalse;
    }

merge!(hash) → ENV click to toggle source
merge!(hash) { |name, old_value, new_value| block } → ENV

Adds the contents of `hash` to the environment variables. If no block is specified entries with duplicate keys are overwritten, otherwise the value of each duplicate name is determined by calling the block with the key, its value from the environment and its value from the hash.

    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) click to toggle source

Returns an `Array` of the name and value of the environment variable with `value` or `nil` if the value cannot be found.

    static VALUE
    env_rassoc(VALUE dmy, VALUE obj)
    {
        char **env;

        obj = rb_check_string_type(obj);
        if (NIL_P(obj)) return Qnil;
        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) {
                    VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
                    FREE_ENVIRON(environ);
                    return result;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
        return Qnil;
    }

rehash click to toggle source

Re-hashing the environment variables does nothing. It is provided for compatibility with `Hash`.

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

reject { |name, value| block } → Hash click to toggle source
reject → Enumerator

Same as `ENV.delete_if`, but works on (and returns) a copy of the environment.

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

reject! { |name, value| block } → ENV or nil click to toggle source
reject! → Enumerator

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

Deletes each environment variable for which the block returns a truthy value, 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

    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();
        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 click to toggle source

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.

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

        keys = env_keys();
        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| block } → Hash click to toggle source
select → Enumerator

Returns a copy of the environment for entries where the block returns true.

Returns an `Enumerator` if no block was given.

`ENV.filter` is an alias for `ENV.select`.

    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();
        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| block } → ENV or nil click to toggle source
select! → Enumerator

Equivalent to `ENV.keep_if` but returns `nil` if no changes were made.

`ENV.filter!` is an alias for `ENV.select!`.

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

shift → [name, value] or nil click to toggle source

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:

    ENV.clear
    ENV.shift # => nil

    static VALUE
    env_shift(VALUE _)
    {
        char **env;
        VALUE result = Qnil;

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

size click to toggle source

Returns the number of environment variables.

    static VALUE
    env_size(VALUE _)
    {
        int i;
        char **env;

        env = GET_ENVIRON(environ);
        for (i=0; env[i]; i++)
            ;
        FREE_ENVIRON(environ);
        return INT2FIX(i);
    }

slice(*keys) → a_hash click to toggle source

Returns a hash containing only the given keys from `ENV` and their values.

    ENV.slice("TERM","HOME")  #=> {"TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}

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

store(name, value) → value click to toggle source

`ENV.store` is an alias for `ENV.[]=`.

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.

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

to_a → Array click to toggle source

Converts the environment variables into an array of names and value arrays.

    ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]

    static VALUE
    env_to_a(VALUE _)
    {
        char **env;
        VALUE ary;

        ary = rb_ary_new();
        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);
        return ary;
    }

to_h → hash click to toggle source
to_h {|name, value| block } → hash

Creates a hash with a copy of the environment variables.

    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_hash → hash click to toggle source

Creates a hash with a copy of the environment variables.

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

to_s → "ENV" click to toggle source

Returns “ENV”

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

update(hash) → ENV click to toggle source
update(hash) { |name, old_value, new_value| block } → ENV

Adds the contents of `hash` to the environment variables. If no block is specified entries with duplicate keys are overwritten, otherwise the value of each duplicate name is determined by calling the block with the key, its value from the environment and its value from the hash.

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

value?(value) → true or false click to toggle source

Returns `true` if there is an environment variable with the given `value`.

    static VALUE
    env_has_value(VALUE dmy, VALUE obj)
    {
        char **env;

        obj = rb_check_string_type(obj);
        if (NIL_P(obj)) return Qnil;
        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) {
                    FREE_ENVIRON(environ);
                    return Qtrue;
                }
            }
            env++;
        }
        FREE_ENVIRON(environ);
        return Qfalse;
    }

values → Array click to toggle source

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:

    ENV.clear
    ENV.values # => []

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

values_at(name, ...) → Array click to toggle source

Returns an array containing the environment variable values associated with the given names. See also `ENV.select`.

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