mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	error.c: KeyError#receiver and KeyError#key
* error.c: new method KeyError#receiver and KeyError#key. [Feature #12063] * hash.c: make KeyError object with receiver and key. * sprintf.c: ditto. Author: ksss <co000ri@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59955 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									2627c19d82
								
							
						
					
					
						commit
						13f5dcb9f2
					
				
					 8 changed files with 58 additions and 7 deletions
				
			
		
							
								
								
									
										5
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								NEWS
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -109,6 +109,11 @@ with all sufficient information, see the ChangeLog file or Redmine
 | 
			
		|||
 | 
			
		||||
  * Description set by Thread#name= is now visible on Windows 10.
 | 
			
		||||
 | 
			
		||||
* KeyError
 | 
			
		||||
 | 
			
		||||
  * KeyError#receiver [Feature #12063]
 | 
			
		||||
  * KeyError#key      [Feature #12063]
 | 
			
		||||
 | 
			
		||||
=== Stdlib updates (outstanding ones only)
 | 
			
		||||
 | 
			
		||||
* Bundler
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								error.c
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								error.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -815,7 +815,7 @@ VALUE rb_mErrno;
 | 
			
		|||
static VALUE rb_eNOERROR;
 | 
			
		||||
 | 
			
		||||
static ID id_new, id_cause, id_message, id_backtrace;
 | 
			
		||||
static ID id_name, id_args, id_Errno, id_errno, id_i_path;
 | 
			
		||||
static ID id_name, id_key, id_args, id_Errno, id_errno, id_i_path;
 | 
			
		||||
static ID id_receiver, id_iseq, id_local_variables;
 | 
			
		||||
static ID id_private_call_p;
 | 
			
		||||
extern ID ruby_static_id_status;
 | 
			
		||||
| 
						 | 
				
			
			@ -1547,6 +1547,37 @@ rb_invalid_str(const char *str, const char *type)
 | 
			
		|||
    rb_raise(rb_eArgError, "invalid value for %s: %+"PRIsVALUE, type, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
key_err_receiver(VALUE self)
 | 
			
		||||
{
 | 
			
		||||
    VALUE recv;
 | 
			
		||||
 | 
			
		||||
    recv = rb_ivar_lookup(self, id_receiver, Qundef);
 | 
			
		||||
    if (recv != Qundef) return recv;
 | 
			
		||||
    rb_raise(rb_eArgError, "no receiver is available");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
key_err_key(VALUE self)
 | 
			
		||||
{
 | 
			
		||||
    VALUE key;
 | 
			
		||||
 | 
			
		||||
    key = rb_ivar_lookup(self, id_key, Qundef);
 | 
			
		||||
    if (key != Qundef) return key;
 | 
			
		||||
    rb_raise(rb_eArgError, "no key is available");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_key_err_new(VALUE mesg, VALUE recv, VALUE key)
 | 
			
		||||
{
 | 
			
		||||
    VALUE exc = rb_obj_alloc(rb_eKeyError);
 | 
			
		||||
    rb_ivar_set(exc, id_mesg, mesg);
 | 
			
		||||
    rb_ivar_set(exc, id_bt, Qnil);
 | 
			
		||||
    rb_ivar_set(exc, id_key, key);
 | 
			
		||||
    rb_ivar_set(exc, id_receiver, recv);
 | 
			
		||||
    return exc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * call-seq:
 | 
			
		||||
 *   SyntaxError.new([msg])  -> syntax_error
 | 
			
		||||
| 
						 | 
				
			
			@ -2161,6 +2192,8 @@ Init_Exception(void)
 | 
			
		|||
    rb_eArgError      = rb_define_class("ArgumentError", rb_eStandardError);
 | 
			
		||||
    rb_eIndexError    = rb_define_class("IndexError", rb_eStandardError);
 | 
			
		||||
    rb_eKeyError      = rb_define_class("KeyError", rb_eIndexError);
 | 
			
		||||
    rb_define_method(rb_eKeyError, "receiver", key_err_receiver, 0);
 | 
			
		||||
    rb_define_method(rb_eKeyError, "key", key_err_key, 0);
 | 
			
		||||
    rb_eRangeError    = rb_define_class("RangeError", rb_eStandardError);
 | 
			
		||||
 | 
			
		||||
    rb_eScriptError = rb_define_class("ScriptError", rb_eException);
 | 
			
		||||
| 
						 | 
				
			
			@ -2216,6 +2249,7 @@ Init_Exception(void)
 | 
			
		|||
    id_message = rb_intern_const("message");
 | 
			
		||||
    id_backtrace = rb_intern_const("backtrace");
 | 
			
		||||
    id_name = rb_intern_const("name");
 | 
			
		||||
    id_key = rb_intern_const("key");
 | 
			
		||||
    id_args = rb_intern_const("args");
 | 
			
		||||
    id_receiver = rb_intern_const("receiver");
 | 
			
		||||
    id_private_call_p = rb_intern_const("private_call?");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								hash.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								hash.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -912,7 +912,7 @@ rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
 | 
			
		|||
		desc = rb_any_to_s(key);
 | 
			
		||||
	    }
 | 
			
		||||
	    desc = rb_str_ellipsize(desc, 65);
 | 
			
		||||
	    rb_raise(rb_eKeyError, "key not found: %"PRIsVALUE, desc);
 | 
			
		||||
	    rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
 | 
			
		||||
	}
 | 
			
		||||
	return argv[1];
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -3375,7 +3375,7 @@ env_fetch(int argc, VALUE *argv)
 | 
			
		|||
    if (!env) {
 | 
			
		||||
	if (block_given) return rb_yield(key);
 | 
			
		||||
	if (argc == 1) {
 | 
			
		||||
	    rb_raise(rb_eKeyError, "key not found: \"%"PRIsVALUE"\"", key);
 | 
			
		||||
	    rb_key_err_raise(rb_sprintf("key not found: \"%"PRIsVALUE"\"", key), envtbl, key);
 | 
			
		||||
	}
 | 
			
		||||
	return argv[1];
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1156,6 +1156,9 @@ VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method);
 | 
			
		|||
    rb_exc_raise(rb_name_err_new(mesg, recv, name))
 | 
			
		||||
#define rb_name_err_raise(mesg, recv, name) \
 | 
			
		||||
    rb_name_err_raise_str(rb_fstring_cstr(mesg), (recv), (name))
 | 
			
		||||
VALUE rb_key_err_new(VALUE mesg, VALUE recv, VALUE name);
 | 
			
		||||
#define rb_key_err_raise(mesg, recv, name) \
 | 
			
		||||
    rb_exc_raise(rb_key_err_new(mesg, recv, name))
 | 
			
		||||
NORETURN(void ruby_deprecated_internal_feature(const char *));
 | 
			
		||||
#define DEPRECATED_INTERNAL_FEATURE(func) \
 | 
			
		||||
    (ruby_deprecated_internal_feature(func), UNREACHABLE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -633,7 +633,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
 | 
			
		|||
		    }
 | 
			
		||||
		    nextvalue = rb_hash_default_value(hash, sym);
 | 
			
		||||
		    if (NIL_P(nextvalue)) {
 | 
			
		||||
			rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
 | 
			
		||||
			rb_key_err_raise(rb_enc_sprintf(enc, "key%.*s not found", len, start), hash, sym);
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
		if (term == '}') goto format_s;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,9 +122,11 @@ class TestEnv < Test::Unit::TestCase
 | 
			
		|||
    assert_equal("foo", ENV.fetch("test"))
 | 
			
		||||
    ENV.delete("test")
 | 
			
		||||
    feature8649 = '[ruby-core:56062] [Feature #8649]'
 | 
			
		||||
    assert_raise_with_message(KeyError, 'key not found: "test"', feature8649) do
 | 
			
		||||
    e = assert_raise_with_message(KeyError, 'key not found: "test"', feature8649) do
 | 
			
		||||
      ENV.fetch("test")
 | 
			
		||||
    end
 | 
			
		||||
    assert_same(ENV, e.receiver)
 | 
			
		||||
    assert_equal("test", e.key)
 | 
			
		||||
    assert_equal("foo", ENV.fetch("test", "foo"))
 | 
			
		||||
    assert_equal("bar", ENV.fetch("test") { "bar" })
 | 
			
		||||
    assert_equal("bar", ENV.fetch("test", "foo") { "bar" })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -531,6 +531,8 @@ class TestHash < Test::Unit::TestCase
 | 
			
		|||
    e = assert_raise(KeyError) { @h.fetch('gumby'*20) }
 | 
			
		||||
    assert_match(/key not found: "gumbygumby/, e.message)
 | 
			
		||||
    assert_match(/\.\.\.\z/, e.message)
 | 
			
		||||
    assert_same(@h, e.receiver)
 | 
			
		||||
    assert_equal('gumby'*20, e.key)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_key2?
 | 
			
		||||
| 
						 | 
				
			
			@ -591,9 +593,11 @@ class TestHash < Test::Unit::TestCase
 | 
			
		|||
    assert_equal(4, res.length)
 | 
			
		||||
    assert_equal %w( three two one nil ), res
 | 
			
		||||
 | 
			
		||||
    assert_raise KeyError do
 | 
			
		||||
    e = assert_raise KeyError do
 | 
			
		||||
      @h.fetch_values(3, 'invalid')
 | 
			
		||||
    end
 | 
			
		||||
    assert_same(@h, e.receiver)
 | 
			
		||||
    assert_equal('invalid', e.key)
 | 
			
		||||
 | 
			
		||||
    res = @h.fetch_values(3, 'invalid') { |k| k.upcase }
 | 
			
		||||
    assert_equal %w( three INVALID ), res
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -452,7 +452,10 @@ class TestSprintf < Test::Unit::TestCase
 | 
			
		|||
    assert_raise_with_message(ArgumentError, "named<key2> after numbered") {sprintf("%1$<key2>s", :key => "value")}
 | 
			
		||||
    assert_raise_with_message(ArgumentError, "named<key2> after unnumbered(2)") {sprintf("%s%s%<key2>s", "foo", "bar", :key => "value")}
 | 
			
		||||
    assert_raise_with_message(ArgumentError, "named<key2> after <key>") {sprintf("%<key><key2>s", :key => "value")}
 | 
			
		||||
    assert_raise_with_message(KeyError, "key<key> not found") {sprintf("%<key>s", {})}
 | 
			
		||||
    h = {}
 | 
			
		||||
    e = assert_raise_with_message(KeyError, "key<key> not found") {sprintf("%<key>s", h)}
 | 
			
		||||
    assert_same(h, e.receiver)
 | 
			
		||||
    assert_equal(:key, e.key)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_named_untyped_enc
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue