mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-env: add ENV object for environment variable access
ENV is a plain Object with singleton methods and Enumerable, matching CRuby's behavior. C methods wrap getenv/setenv/unsetenv with platform support for POSIX, macOS, and Windows. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
MRuby::Gem::Specification.new('mruby-env') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = ['mruby developers']
|
||||
spec.summary = 'ENV object for environment variable access'
|
||||
spec.add_dependency('mruby-enumerator', :core => 'mruby-enumerator')
|
||||
end
|
||||
@@ -0,0 +1,153 @@
|
||||
class << ENV
|
||||
def each(&block)
|
||||
return to_enum(:each) unless block
|
||||
keys.each do |k|
|
||||
v = self[k]
|
||||
block.call([k, v]) if v
|
||||
end
|
||||
self
|
||||
end
|
||||
alias each_pair each
|
||||
|
||||
def each_key(&block)
|
||||
return to_enum(:each_key) unless block
|
||||
keys.each(&block)
|
||||
self
|
||||
end
|
||||
|
||||
def each_value(&block)
|
||||
return to_enum(:each_value) unless block
|
||||
__values.each(&block)
|
||||
self
|
||||
end
|
||||
|
||||
def values
|
||||
__values
|
||||
end
|
||||
|
||||
def delete(key, &block)
|
||||
val = __delete(key)
|
||||
if val.nil? && block
|
||||
block.call(key)
|
||||
else
|
||||
val
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
__clear
|
||||
self
|
||||
end
|
||||
|
||||
def fetch(key, *args, &block)
|
||||
val = self[key]
|
||||
return val unless val.nil?
|
||||
if block
|
||||
block.call(key)
|
||||
elsif args.length > 0
|
||||
args[0]
|
||||
else
|
||||
raise KeyError, "key not found: \"#{key}\""
|
||||
end
|
||||
end
|
||||
|
||||
def store(key, val)
|
||||
self[key] = val
|
||||
end
|
||||
|
||||
def to_h(&block)
|
||||
h = {}
|
||||
each do |k, v|
|
||||
if block
|
||||
k, v = block.call(k, v)
|
||||
end
|
||||
h[k] = v
|
||||
end
|
||||
h
|
||||
end
|
||||
|
||||
def to_a
|
||||
each_pair.to_a
|
||||
end
|
||||
|
||||
def inspect
|
||||
to_h.inspect
|
||||
end
|
||||
|
||||
def empty?
|
||||
size == 0
|
||||
end
|
||||
|
||||
def has_value?(val)
|
||||
__values.include?(val)
|
||||
end
|
||||
alias value? has_value?
|
||||
|
||||
def assoc(key)
|
||||
val = self[key]
|
||||
val.nil? ? nil : [key, val]
|
||||
end
|
||||
|
||||
def rassoc(val)
|
||||
each do |k, v|
|
||||
return [k, v] if v == val
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def key(val)
|
||||
each do |k, v|
|
||||
return k if v == val
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def replace(hash)
|
||||
clear
|
||||
hash.each do |k, v|
|
||||
self[k] = v
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def update(hash, &block)
|
||||
hash.each do |k, v|
|
||||
if block && key?(k)
|
||||
self[k] = block.call(k, self[k], v)
|
||||
else
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
self
|
||||
end
|
||||
alias merge! update
|
||||
|
||||
def select(&block)
|
||||
return to_enum(:select) unless block
|
||||
to_h.select(&block)
|
||||
end
|
||||
alias filter select
|
||||
|
||||
def reject(&block)
|
||||
return to_enum(:reject) unless block
|
||||
to_h.reject(&block)
|
||||
end
|
||||
|
||||
def slice(*keys)
|
||||
h = {}
|
||||
keys.each do |k|
|
||||
v = self[k]
|
||||
h[k] = v unless v.nil?
|
||||
end
|
||||
h
|
||||
end
|
||||
|
||||
alias include? key?
|
||||
alias has_key? key?
|
||||
alias member? key?
|
||||
alias length size
|
||||
|
||||
def freeze
|
||||
raise TypeError, "cannot freeze ENV"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
** env.c - ENV object for environment variable access
|
||||
*/
|
||||
|
||||
#include <mruby.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/error.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdlib.h>
|
||||
#define environ _environ
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
#include <crt_externs.h>
|
||||
#define environ (*_NSGetEnviron())
|
||||
#else
|
||||
extern char **environ;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void
|
||||
env_check_key(mrb_state *mrb, mrb_value key)
|
||||
{
|
||||
mrb_ensure_string_type(mrb, key);
|
||||
if (memchr(RSTRING_PTR(key), '=', RSTRING_LEN(key))) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "bad environment variable name: contains '='");
|
||||
}
|
||||
if (memchr(RSTRING_PTR(key), '\0', RSTRING_LEN(key))) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "bad environment variable name: contains null byte");
|
||||
}
|
||||
}
|
||||
|
||||
/* ENV[] */
|
||||
static mrb_value
|
||||
mrb_env_aref(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value key;
|
||||
const char *val;
|
||||
|
||||
mrb_get_args(mrb, "o", &key);
|
||||
env_check_key(mrb, key);
|
||||
val = getenv(RSTRING_PTR(key));
|
||||
if (val == NULL) return mrb_nil_value();
|
||||
return mrb_str_new_cstr(mrb, val);
|
||||
}
|
||||
|
||||
/* ENV[]= */
|
||||
static mrb_value
|
||||
mrb_env_aset(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value key, val;
|
||||
|
||||
mrb_get_args(mrb, "oo", &key, &val);
|
||||
env_check_key(mrb, key);
|
||||
|
||||
if (mrb_nil_p(val)) {
|
||||
#ifdef _WIN32
|
||||
_putenv_s(RSTRING_PTR(key), "");
|
||||
#else
|
||||
unsetenv(RSTRING_PTR(key));
|
||||
#endif
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
mrb_ensure_string_type(mrb, val);
|
||||
if (memchr(RSTRING_PTR(val), '\0', RSTRING_LEN(val))) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "bad environment variable value: contains null byte");
|
||||
}
|
||||
#ifdef _WIN32
|
||||
_putenv_s(RSTRING_PTR(key), RSTRING_PTR(val));
|
||||
#else
|
||||
setenv(RSTRING_PTR(key), RSTRING_PTR(val), 1);
|
||||
#endif
|
||||
return val;
|
||||
}
|
||||
|
||||
/* ENV.__delete(key) - returns old value or nil */
|
||||
static mrb_value
|
||||
mrb_env_delete(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value key;
|
||||
const char *val;
|
||||
mrb_value result;
|
||||
|
||||
mrb_get_args(mrb, "o", &key);
|
||||
env_check_key(mrb, key);
|
||||
val = getenv(RSTRING_PTR(key));
|
||||
if (val == NULL) return mrb_nil_value();
|
||||
result = mrb_str_new_cstr(mrb, val);
|
||||
#ifdef _WIN32
|
||||
_putenv_s(RSTRING_PTR(key), "");
|
||||
#else
|
||||
unsetenv(RSTRING_PTR(key));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ENV.keys */
|
||||
static mrb_value
|
||||
mrb_env_keys(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value ary = mrb_ary_new(mrb);
|
||||
char **env;
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
|
||||
for (env = environ; *env != NULL; env++) {
|
||||
char *eq = strchr(*env, '=');
|
||||
if (eq) {
|
||||
mrb_ary_push(mrb, ary, mrb_str_new(mrb, *env, (mrb_int)(eq - *env)));
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
/* ENV.__values */
|
||||
static mrb_value
|
||||
mrb_env_values(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value ary = mrb_ary_new(mrb);
|
||||
char **env;
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
|
||||
for (env = environ; *env != NULL; env++) {
|
||||
char *eq = strchr(*env, '=');
|
||||
if (eq) {
|
||||
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, eq + 1));
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
/* ENV.size */
|
||||
static mrb_value
|
||||
mrb_env_size(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_int count = 0;
|
||||
char **env;
|
||||
|
||||
for (env = environ; *env != NULL; env++) {
|
||||
count++;
|
||||
}
|
||||
return mrb_fixnum_value(count);
|
||||
}
|
||||
|
||||
/* ENV.key? */
|
||||
static mrb_value
|
||||
mrb_env_has_key(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
mrb_value key;
|
||||
|
||||
mrb_get_args(mrb, "o", &key);
|
||||
env_check_key(mrb, key);
|
||||
return mrb_bool_value(getenv(RSTRING_PTR(key)) != NULL);
|
||||
}
|
||||
|
||||
/* ENV.to_s */
|
||||
static mrb_value
|
||||
mrb_env_to_s(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
return mrb_str_new_lit(mrb, "ENV");
|
||||
}
|
||||
|
||||
/* ENV.__clear */
|
||||
static mrb_value
|
||||
mrb_env_clear(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
while (*environ) {
|
||||
char *eq = strchr(*environ, '=');
|
||||
if (eq) {
|
||||
mrb_int len = (mrb_int)(eq - *environ);
|
||||
char *key = (char*)mrb_malloc(mrb, len + 1);
|
||||
memcpy(key, *environ, len);
|
||||
key[len] = '\0';
|
||||
#ifdef _WIN32
|
||||
_putenv_s(key, "");
|
||||
#else
|
||||
unsetenv(key);
|
||||
#endif
|
||||
mrb_free(mrb, key);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_env_gem_init(mrb_state *mrb)
|
||||
{
|
||||
mrb_value env = mrb_obj_new(mrb, mrb->object_class, 0, NULL);
|
||||
struct RObject *eobj = mrb_obj_ptr(env);
|
||||
|
||||
mrb_define_global_const(mrb, "ENV", env);
|
||||
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_OPSYM(aref), mrb_env_aref, MRB_ARGS_REQ(1));
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_OPSYM(aset), mrb_env_aset, MRB_ARGS_REQ(2));
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM(__delete), mrb_env_delete, MRB_ARGS_REQ(1));
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM(keys), mrb_env_keys, MRB_ARGS_NONE());
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM(__values), mrb_env_values, MRB_ARGS_NONE());
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM(size), mrb_env_size, MRB_ARGS_NONE());
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM_Q(key), mrb_env_has_key, MRB_ARGS_REQ(1));
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM(to_s), mrb_env_to_s, MRB_ARGS_NONE());
|
||||
mrb_define_singleton_method_id(mrb, eobj, MRB_SYM(__clear), mrb_env_clear, MRB_ARGS_NONE());
|
||||
|
||||
/* include Enumerable in ENV's singleton class */
|
||||
{
|
||||
struct RClass *sc = mrb_singleton_class_ptr(mrb, env);
|
||||
mrb_include_module(mrb, sc, mrb_module_get_id(mrb, MRB_SYM(Enumerable)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mrb_mruby_env_gem_final(mrb_state *mrb)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
##
|
||||
# ENV test
|
||||
|
||||
assert('ENV class') do
|
||||
assert_equal Object, ENV.class
|
||||
end
|
||||
|
||||
assert('ENV.to_s') do
|
||||
assert_equal "ENV", ENV.to_s
|
||||
end
|
||||
|
||||
assert('ENV[] and ENV[]=') do
|
||||
ENV["MRUBY_ENV_TEST_A"] = "hello"
|
||||
assert_equal "hello", ENV["MRUBY_ENV_TEST_A"]
|
||||
ENV["MRUBY_ENV_TEST_A"] = nil
|
||||
assert_nil ENV["MRUBY_ENV_TEST_A"]
|
||||
end
|
||||
|
||||
assert('ENV[] returns nil for missing key') do
|
||||
assert_nil ENV["MRUBY_ENV_TEST_NONEXISTENT"]
|
||||
end
|
||||
|
||||
assert('ENV.store') do
|
||||
ENV.store("MRUBY_ENV_TEST_B", "world")
|
||||
assert_equal "world", ENV["MRUBY_ENV_TEST_B"]
|
||||
ENV.delete("MRUBY_ENV_TEST_B")
|
||||
end
|
||||
|
||||
assert('ENV.delete') do
|
||||
ENV["MRUBY_ENV_TEST_C"] = "val"
|
||||
assert_equal "val", ENV.delete("MRUBY_ENV_TEST_C")
|
||||
assert_nil ENV["MRUBY_ENV_TEST_C"]
|
||||
end
|
||||
|
||||
assert('ENV.delete returns nil for missing key') do
|
||||
assert_nil ENV.delete("MRUBY_ENV_TEST_NONEXISTENT")
|
||||
end
|
||||
|
||||
assert('ENV.delete with block') do
|
||||
result = ENV.delete("MRUBY_ENV_TEST_NONEXISTENT") { |k| "missing: #{k}" }
|
||||
assert_equal "missing: MRUBY_ENV_TEST_NONEXISTENT", result
|
||||
end
|
||||
|
||||
assert('ENV.key?') do
|
||||
ENV["MRUBY_ENV_TEST_D"] = "yes"
|
||||
assert_true ENV.key?("MRUBY_ENV_TEST_D")
|
||||
assert_false ENV.key?("MRUBY_ENV_TEST_NONEXISTENT")
|
||||
ENV.delete("MRUBY_ENV_TEST_D")
|
||||
end
|
||||
|
||||
assert('ENV.include?/has_key?/member?') do
|
||||
ENV["MRUBY_ENV_TEST_E"] = "val"
|
||||
assert_true ENV.include?("MRUBY_ENV_TEST_E")
|
||||
assert_true ENV.has_key?("MRUBY_ENV_TEST_E")
|
||||
assert_true ENV.member?("MRUBY_ENV_TEST_E")
|
||||
ENV.delete("MRUBY_ENV_TEST_E")
|
||||
end
|
||||
|
||||
assert('ENV.keys') do
|
||||
ENV["MRUBY_ENV_TEST_F"] = "val"
|
||||
k = ENV.keys
|
||||
assert_kind_of Array, k
|
||||
assert_true k.include?("MRUBY_ENV_TEST_F")
|
||||
ENV.delete("MRUBY_ENV_TEST_F")
|
||||
end
|
||||
|
||||
assert('ENV.values') do
|
||||
ENV["MRUBY_ENV_TEST_G"] = "unique_val_42"
|
||||
v = ENV.values
|
||||
assert_kind_of Array, v
|
||||
assert_true v.include?("unique_val_42")
|
||||
ENV.delete("MRUBY_ENV_TEST_G")
|
||||
end
|
||||
|
||||
assert('ENV.size/length') do
|
||||
s1 = ENV.size
|
||||
ENV["MRUBY_ENV_TEST_H"] = "val"
|
||||
assert_equal s1 + 1, ENV.size
|
||||
assert_equal ENV.size, ENV.length
|
||||
ENV.delete("MRUBY_ENV_TEST_H")
|
||||
end
|
||||
|
||||
assert('ENV.empty?') do
|
||||
assert_equal [true, false].include?(ENV.empty?), true
|
||||
end
|
||||
|
||||
assert('ENV.has_value?/value?') do
|
||||
ENV["MRUBY_ENV_TEST_I"] = "unique_find_me"
|
||||
assert_true ENV.has_value?("unique_find_me")
|
||||
assert_true ENV.value?("unique_find_me")
|
||||
assert_false ENV.has_value?("MRUBY_ENV_NEVER_EXISTS_VALUE")
|
||||
ENV.delete("MRUBY_ENV_TEST_I")
|
||||
end
|
||||
|
||||
assert('ENV.each/each_pair') do
|
||||
ENV["MRUBY_ENV_TEST_J"] = "iter_val"
|
||||
found = false
|
||||
ENV.each do |k, v|
|
||||
if k == "MRUBY_ENV_TEST_J" && v == "iter_val"
|
||||
found = true
|
||||
end
|
||||
end
|
||||
assert_true found
|
||||
ENV.delete("MRUBY_ENV_TEST_J")
|
||||
end
|
||||
|
||||
assert('ENV.each_key') do
|
||||
ENV["MRUBY_ENV_TEST_K"] = "val"
|
||||
found = false
|
||||
ENV.each_key { |k| found = true if k == "MRUBY_ENV_TEST_K" }
|
||||
assert_true found
|
||||
ENV.delete("MRUBY_ENV_TEST_K")
|
||||
end
|
||||
|
||||
assert('ENV.each_value') do
|
||||
ENV["MRUBY_ENV_TEST_L"] = "val_each_v"
|
||||
found = false
|
||||
ENV.each_value { |v| found = true if v == "val_each_v" }
|
||||
assert_true found
|
||||
ENV.delete("MRUBY_ENV_TEST_L")
|
||||
end
|
||||
|
||||
assert('ENV.fetch') do
|
||||
ENV["MRUBY_ENV_TEST_M"] = "fetch_val"
|
||||
assert_equal "fetch_val", ENV.fetch("MRUBY_ENV_TEST_M")
|
||||
assert_equal "default", ENV.fetch("MRUBY_ENV_TEST_NONE", "default")
|
||||
assert_equal "block", ENV.fetch("MRUBY_ENV_TEST_NONE") { "block" }
|
||||
assert_raise(KeyError) { ENV.fetch("MRUBY_ENV_TEST_NONE") }
|
||||
ENV.delete("MRUBY_ENV_TEST_M")
|
||||
end
|
||||
|
||||
assert('ENV.to_h') do
|
||||
ENV["MRUBY_ENV_TEST_N"] = "to_h_val"
|
||||
h = ENV.to_h
|
||||
assert_kind_of Hash, h
|
||||
assert_equal "to_h_val", h["MRUBY_ENV_TEST_N"]
|
||||
ENV.delete("MRUBY_ENV_TEST_N")
|
||||
end
|
||||
|
||||
assert('ENV.to_a') do
|
||||
ENV["MRUBY_ENV_TEST_O"] = "to_a_val"
|
||||
a = ENV.to_a
|
||||
assert_kind_of Array, a
|
||||
assert_true a.include?(["MRUBY_ENV_TEST_O", "to_a_val"])
|
||||
ENV.delete("MRUBY_ENV_TEST_O")
|
||||
end
|
||||
|
||||
assert('ENV.assoc') do
|
||||
ENV["MRUBY_ENV_TEST_P"] = "assoc_val"
|
||||
assert_equal ["MRUBY_ENV_TEST_P", "assoc_val"], ENV.assoc("MRUBY_ENV_TEST_P")
|
||||
assert_nil ENV.assoc("MRUBY_ENV_TEST_NONEXISTENT")
|
||||
ENV.delete("MRUBY_ENV_TEST_P")
|
||||
end
|
||||
|
||||
assert('ENV.rassoc') do
|
||||
ENV["MRUBY_ENV_TEST_Q"] = "rassoc_unique_val"
|
||||
result = ENV.rassoc("rassoc_unique_val")
|
||||
assert_equal "MRUBY_ENV_TEST_Q", result[0]
|
||||
assert_equal "rassoc_unique_val", result[1]
|
||||
assert_nil ENV.rassoc("MRUBY_ENV_NEVER_EXISTS_VALUE")
|
||||
ENV.delete("MRUBY_ENV_TEST_Q")
|
||||
end
|
||||
|
||||
assert('ENV.key') do
|
||||
ENV["MRUBY_ENV_TEST_R"] = "key_search_val"
|
||||
assert_equal "MRUBY_ENV_TEST_R", ENV.key("key_search_val")
|
||||
assert_nil ENV.key("MRUBY_ENV_NEVER_EXISTS_VALUE")
|
||||
ENV.delete("MRUBY_ENV_TEST_R")
|
||||
end
|
||||
|
||||
assert('ENV.inspect') do
|
||||
s = ENV.inspect
|
||||
assert_kind_of String, s
|
||||
end
|
||||
|
||||
assert('ENV.select/filter') do
|
||||
ENV["MRUBY_ENV_TEST_S"] = "sel_val"
|
||||
result = ENV.select { |k, v| k == "MRUBY_ENV_TEST_S" }
|
||||
assert_kind_of Hash, result
|
||||
assert_equal "sel_val", result["MRUBY_ENV_TEST_S"]
|
||||
ENV.delete("MRUBY_ENV_TEST_S")
|
||||
end
|
||||
|
||||
assert('ENV.reject') do
|
||||
ENV["MRUBY_ENV_TEST_T"] = "rej_val"
|
||||
result = ENV.reject { |k, v| k != "MRUBY_ENV_TEST_T" }
|
||||
assert_equal({"MRUBY_ENV_TEST_T" => "rej_val"}, result)
|
||||
ENV.delete("MRUBY_ENV_TEST_T")
|
||||
end
|
||||
|
||||
assert('ENV.replace') do
|
||||
ENV["MRUBY_ENV_TEST_U1"] = "old1"
|
||||
ENV.replace({"MRUBY_ENV_TEST_U2" => "new2"})
|
||||
assert_nil ENV["MRUBY_ENV_TEST_U1"]
|
||||
assert_equal "new2", ENV["MRUBY_ENV_TEST_U2"]
|
||||
ENV.delete("MRUBY_ENV_TEST_U2")
|
||||
end
|
||||
|
||||
assert('ENV.update/merge!') do
|
||||
ENV["MRUBY_ENV_TEST_V"] = "orig"
|
||||
ENV.update({"MRUBY_ENV_TEST_V" => "updated", "MRUBY_ENV_TEST_W" => "new"})
|
||||
assert_equal "updated", ENV["MRUBY_ENV_TEST_V"]
|
||||
assert_equal "new", ENV["MRUBY_ENV_TEST_W"]
|
||||
ENV.delete("MRUBY_ENV_TEST_V")
|
||||
ENV.delete("MRUBY_ENV_TEST_W")
|
||||
end
|
||||
|
||||
assert('ENV.update with block') do
|
||||
ENV["MRUBY_ENV_TEST_X"] = "old"
|
||||
ENV.update({"MRUBY_ENV_TEST_X" => "new"}) { |k, o, n| "#{o}_#{n}" }
|
||||
assert_equal "old_new", ENV["MRUBY_ENV_TEST_X"]
|
||||
ENV.delete("MRUBY_ENV_TEST_X")
|
||||
end
|
||||
|
||||
assert('ENV.slice') do
|
||||
ENV["MRUBY_ENV_TEST_Y"] = "s1"
|
||||
ENV["MRUBY_ENV_TEST_Z"] = "s2"
|
||||
h = ENV.slice("MRUBY_ENV_TEST_Y", "MRUBY_ENV_TEST_Z", "MRUBY_ENV_TEST_NONEXISTENT")
|
||||
assert_equal({"MRUBY_ENV_TEST_Y" => "s1", "MRUBY_ENV_TEST_Z" => "s2"}, h)
|
||||
ENV.delete("MRUBY_ENV_TEST_Y")
|
||||
ENV.delete("MRUBY_ENV_TEST_Z")
|
||||
end
|
||||
|
||||
assert('ENV.freeze raises TypeError') do
|
||||
assert_raise(TypeError) { ENV.freeze }
|
||||
end
|
||||
|
||||
assert('ENV raises TypeError for non-string key') do
|
||||
assert_raise(TypeError) { ENV[123] }
|
||||
end
|
||||
|
||||
assert('ENV raises TypeError for non-string value') do
|
||||
assert_raise(TypeError) { ENV["MRUBY_ENV_TEST_ERR"] = 123 }
|
||||
end
|
||||
|
||||
assert('ENV.each returns enumerator without block') do
|
||||
e = ENV.each
|
||||
assert_kind_of Enumerator, e
|
||||
end
|
||||
|
||||
assert('ENV is Enumerable') do
|
||||
assert_true ENV.is_a?(Enumerable)
|
||||
end
|
||||
@@ -12,4 +12,7 @@ MRuby::GemBox.new do |conf|
|
||||
|
||||
# Use Dir class
|
||||
conf.gem :core => "mruby-dir"
|
||||
|
||||
# Use ENV object
|
||||
conf.gem :core => "mruby-env"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user