diff options
-rw-r--r-- | test/ruby/test_defined.rb | 46 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vm_insnhelper.c | 2 |
3 files changed, 47 insertions, 3 deletions
diff --git a/test/ruby/test_defined.rb b/test/ruby/test_defined.rb index 9976db3b6f..e1571d5714 100644 --- a/test/ruby/test_defined.rb +++ b/test/ruby/test_defined.rb @@ -23,40 +23,80 @@ class TestDefined < Test::Unit::TestCase return !defined?(yield) end - def test_defined + def test_defined_global_variable $x = nil assert(defined?($x)) # global variable assert_equal('global-variable', defined?($x))# returns description + end + def test_defined_local_variable assert_nil(defined?(foo)) # undefined foo=5 assert(defined?(foo)) # local variable + end + def test_defined_constant assert(defined?(Array)) # constant assert(defined?(::Array)) # toplevel constant assert(defined?(File::Constants)) # nested constant + end + + def test_defined_public_method assert(defined?(Object.new)) # method assert(defined?(Object::new)) # method + end + + def test_defined_private_method assert(!defined?(Object.print)) # private method + end + + def test_defined_operator assert(defined?(1 == 2)) # operator expression + end + def test_defined_protected_method f = Foo.new assert_nil(defined?(f.foo)) # protected method f.bar(f) { |v| assert(v) } + f.bar(Class.new(Foo).new) { |v| assert(v, "inherited protected method") } + end + + def test_defined_undefined_method + f = Foo.new assert_nil(defined?(f.quux)) # undefined method + end + + def test_defined_undefined_argument + f = Foo.new assert_nil(defined?(f.baz(x))) # undefined argument x = 0 assert(defined?(f.baz(x))) assert_nil(defined?(f.quux(x))) assert(defined?(print(x))) assert_nil(defined?(quux(x))) + end + + def test_defined_attrasgn + f = Foo.new assert(defined?(f.attr = 1)) f.attrasgn_test { |v| assert(v) } + end + + def test_defined_undef + x = Object.new + def x.foo; end + assert(defined?(x.foo)) + x.instance_eval {undef :foo} + assert(!defined?(x.foo), "undefed method should not be defined?") + end + def test_defined_yield assert(defined_test) # not iterator assert(!defined_test{}) # called as iterator + end + def test_defined_matchdata /a/ =~ '' assert_equal nil, defined?($&) assert_equal nil, defined?($`) @@ -85,12 +125,16 @@ class TestDefined < Test::Unit::TestCase assert_equal 'global-variable', defined?($+) assert_equal 'global-variable', defined?($1) assert_equal nil, defined?($2) + end + def test_defined_literal assert_equal("nil", defined?(nil)) assert_equal("true", defined?(true)) assert_equal("false", defined?(false)) assert_equal("expression", defined?(1)) + end + def test_defined_empty_paren_expr bug8224 = '[ruby-core:54024] [Bug #8224]' (1..3).each do |level| expr = "("*level+")"*level @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.6.7" #define RUBY_RELEASE_DATE "2021-04-05" -#define RUBY_PATCHLEVEL 179 +#define RUBY_PATCHLEVEL 180 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 4 diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 4a47a8ee5c..b3a89fca06 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2858,7 +2858,7 @@ vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t op_ case METHOD_VISI_PRIVATE: break; case METHOD_VISI_PROTECTED: - if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(klass))) { + if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(me->defined_class))) { break; } case METHOD_VISI_PUBLIC: |