2015-12-16 00:07:31 -05:00
|
|
|
# frozen_string_literal: false
|
2003-09-04 12:18:59 -04:00
|
|
|
require 'test/unit'
|
|
|
|
|
|
|
|
class TestVariable < Test::Unit::TestCase
|
|
|
|
class Gods
|
|
|
|
@@rule = "Uranus"
|
|
|
|
def ruler0
|
|
|
|
@@rule
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.ruler1 # <= per method definition style
|
|
|
|
@@rule
|
2003-09-05 11:15:43 -04:00
|
|
|
end
|
2003-09-04 12:18:59 -04:00
|
|
|
class << self # <= multiple method definition style
|
|
|
|
def ruler2
|
|
|
|
@@rule
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module Olympians
|
|
|
|
@@rule ="Zeus"
|
|
|
|
def ruler3
|
|
|
|
@@rule
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Titans < Gods
|
2007-10-03 02:48:06 -04:00
|
|
|
@@rule = "Cronus" # modifies @@rule in Gods
|
2004-03-19 02:13:01 -05:00
|
|
|
include Olympians
|
|
|
|
def ruler4
|
2014-11-22 18:47:22 -05:00
|
|
|
EnvUtil.suppress_warning {
|
|
|
|
@@rule
|
|
|
|
}
|
2004-03-19 02:13:01 -05:00
|
|
|
end
|
2003-09-04 12:18:59 -04:00
|
|
|
end
|
|
|
|
|
2019-08-09 19:44:43 -04:00
|
|
|
def test_singleton_class_included_class_variable
|
|
|
|
c = Class.new
|
|
|
|
c.extend(Olympians)
|
|
|
|
assert_empty(c.singleton_class.class_variables)
|
|
|
|
assert_raise(NameError){ c.singleton_class.class_variable_get(:@@rule) }
|
|
|
|
c.class_variable_set(:@@foo, 1)
|
|
|
|
assert_equal([:@@foo], c.singleton_class.class_variables)
|
|
|
|
assert_equal(1, c.singleton_class.class_variable_get(:@@foo))
|
2019-11-28 13:11:28 -05:00
|
|
|
|
2019-08-09 19:44:43 -04:00
|
|
|
c = Class.new
|
|
|
|
c.extend(Olympians)
|
|
|
|
sc = Class.new(c)
|
|
|
|
assert_empty(sc.singleton_class.class_variables)
|
|
|
|
assert_raise(NameError){ sc.singleton_class.class_variable_get(:@@rule) }
|
|
|
|
c.class_variable_set(:@@foo, 1)
|
|
|
|
assert_equal([:@@foo], sc.singleton_class.class_variables)
|
|
|
|
assert_equal(1, sc.singleton_class.class_variable_get(:@@foo))
|
|
|
|
|
|
|
|
c = Class.new
|
|
|
|
o = c.new
|
|
|
|
o.extend(Olympians)
|
|
|
|
assert_equal([:@@rule], o.singleton_class.class_variables)
|
|
|
|
assert_equal("Zeus", o.singleton_class.class_variable_get(:@@rule))
|
|
|
|
c.class_variable_set(:@@foo, 1)
|
|
|
|
assert_equal([:@@foo, :@@rule], o.singleton_class.class_variables.sort)
|
|
|
|
assert_equal(1, o.singleton_class.class_variable_get(:@@foo))
|
|
|
|
end
|
|
|
|
|
2019-11-28 20:28:13 -05:00
|
|
|
class IncludeRefinedModuleClassVariableNoWarning
|
|
|
|
module Mod
|
|
|
|
@@_test_include_refined_module_class_variable = true
|
|
|
|
end
|
|
|
|
|
|
|
|
module Mod2
|
|
|
|
refine Mod do
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
include Mod
|
|
|
|
|
|
|
|
def t
|
|
|
|
@@_test_include_refined_module_class_variable
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_include_refined_module_class_variable
|
|
|
|
assert_warning('') do
|
|
|
|
IncludeRefinedModuleClassVariableNoWarning.new.t
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2003-09-04 12:18:59 -04:00
|
|
|
def test_variable
|
Use Integer instead of Fixnum and Bignum.
* object.c, numeric.c, enum.c, ext/-test-/bignum/mul.c,
lib/rexml/quickpath.rb, lib/rexml/text.rb, lib/rexml/xpath_parser.rb,
lib/rubygems/specification.rb, lib/uri/generic.rb,
bootstraptest/test_eval.rb, basictest/test.rb,
test/-ext-/bignum/test_big2str.rb, test/-ext-/bignum/test_div.rb,
test/-ext-/bignum/test_mul.rb, test/-ext-/bignum/test_str2big.rb,
test/csv/test_data_converters.rb, test/date/test_date.rb,
test/json/test_json_generate.rb, test/minitest/test_minitest_mock.rb,
test/openssl/test_cipher.rb, test/rexml/test_jaxen.rb,
test/ruby/test_array.rb, test/ruby/test_basicinstructions.rb,
test/ruby/test_bignum.rb, test/ruby/test_case.rb,
test/ruby/test_class.rb, test/ruby/test_complex.rb,
test/ruby/test_enum.rb, test/ruby/test_eval.rb,
test/ruby/test_iseq.rb, test/ruby/test_literal.rb,
test/ruby/test_math.rb, test/ruby/test_module.rb,
test/ruby/test_numeric.rb, test/ruby/test_range.rb,
test/ruby/test_rational.rb, test/ruby/test_refinement.rb,
test/ruby/test_rubyvm.rb, test/ruby/test_struct.rb,
test/ruby/test_variable.rb, test/rubygems/test_gem_specification.rb,
test/thread/test_queue.rb: Use Integer instead of Fixnum and Bignum.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55029 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-17 09:15:57 -04:00
|
|
|
assert_instance_of(Integer, $$)
|
2009-03-05 22:56:38 -05:00
|
|
|
|
2003-09-04 12:18:59 -04:00
|
|
|
# read-only variable
|
2008-09-24 13:44:39 -04:00
|
|
|
assert_raise(NameError) do
|
2003-09-04 12:18:59 -04:00
|
|
|
$$ = 5
|
|
|
|
end
|
2008-10-13 23:23:57 -04:00
|
|
|
assert_normal_exit("$*=0; $*", "[ruby-dev:36698]")
|
2003-09-05 11:15:43 -04:00
|
|
|
|
2003-09-04 12:18:59 -04:00
|
|
|
foobar = "foobar"
|
|
|
|
$_ = foobar
|
2003-09-05 11:15:43 -04:00
|
|
|
assert_equal(foobar, $_)
|
2003-09-04 12:18:59 -04:00
|
|
|
|
2007-10-03 02:48:06 -04:00
|
|
|
assert_equal("Cronus", Gods.new.ruler0)
|
|
|
|
assert_equal("Cronus", Gods.ruler1)
|
|
|
|
assert_equal("Cronus", Gods.ruler2)
|
|
|
|
assert_equal("Cronus", Titans.ruler1)
|
|
|
|
assert_equal("Cronus", Titans.ruler2)
|
2003-09-04 12:18:59 -04:00
|
|
|
atlas = Titans.new
|
2007-10-03 02:48:06 -04:00
|
|
|
assert_equal("Cronus", atlas.ruler0)
|
2003-09-05 11:15:43 -04:00
|
|
|
assert_equal("Zeus", atlas.ruler3)
|
2004-03-19 02:13:01 -05:00
|
|
|
assert_equal("Cronus", atlas.ruler4)
|
2011-08-23 20:52:04 -04:00
|
|
|
assert_nothing_raised do
|
|
|
|
class << Gods
|
|
|
|
defined?(@@rule) && @@rule
|
|
|
|
end
|
|
|
|
end
|
2003-09-04 12:18:59 -04:00
|
|
|
end
|
2008-03-09 06:16:20 -04:00
|
|
|
|
|
|
|
def test_local_variables
|
|
|
|
lvar = 1
|
|
|
|
assert_instance_of(Symbol, local_variables[0], "[ruby-dev:34008]")
|
2014-11-22 18:47:22 -05:00
|
|
|
lvar
|
2008-03-09 06:16:20 -04:00
|
|
|
end
|
2008-05-12 10:42:17 -04:00
|
|
|
|
|
|
|
def test_local_variables2
|
|
|
|
x = 1
|
|
|
|
proc do |y|
|
|
|
|
assert_equal([:x, :y], local_variables.sort)
|
|
|
|
end.call
|
2014-11-22 18:47:22 -05:00
|
|
|
x
|
2008-05-12 10:42:17 -04:00
|
|
|
end
|
2008-05-14 08:52:17 -04:00
|
|
|
|
|
|
|
def test_local_variables3
|
|
|
|
x = 1
|
|
|
|
proc do |y|
|
|
|
|
1.times do |z|
|
|
|
|
assert_equal([:x, :y, :z], local_variables.sort)
|
|
|
|
end
|
|
|
|
end.call
|
2014-11-22 18:47:22 -05:00
|
|
|
x
|
2008-05-14 08:52:17 -04:00
|
|
|
end
|
2008-07-14 02:17:36 -04:00
|
|
|
|
2014-05-06 10:28:48 -04:00
|
|
|
def test_shadowing_local_variables
|
|
|
|
bug9486 = '[ruby-core:60501] [Bug #9486]'
|
2016-02-19 02:48:02 -05:00
|
|
|
assert_equal([:x, :bug9486], tap {|x| break local_variables}, bug9486)
|
2014-05-06 10:28:48 -04:00
|
|
|
end
|
|
|
|
|
2014-05-06 10:29:07 -04:00
|
|
|
def test_shadowing_block_local_variables
|
|
|
|
bug9486 = '[ruby-core:60501] [Bug #9486]'
|
2016-02-19 02:48:02 -05:00
|
|
|
assert_equal([:x, :bug9486], tap {|;x| x = x; break local_variables}, bug9486)
|
2014-05-06 10:29:07 -04:00
|
|
|
end
|
|
|
|
|
2016-01-13 21:45:03 -05:00
|
|
|
def test_global_variables
|
|
|
|
gv = global_variables
|
|
|
|
assert_empty(gv.grep(/\A(?!\$)/))
|
|
|
|
assert_nil($~)
|
|
|
|
assert_not_include(gv, :$1)
|
2016-01-14 03:36:49 -05:00
|
|
|
/(\w)(\d)?(.)(.)(.)(.)(.)(.)(.)(.)(\d)?(.)/ =~ "globalglobalglobal"
|
2016-01-13 21:45:03 -05:00
|
|
|
assert_not_nil($~)
|
2016-01-14 03:36:49 -05:00
|
|
|
gv = global_variables - gv
|
|
|
|
assert_include(gv, :$1)
|
|
|
|
assert_not_include(gv, :$2)
|
|
|
|
assert_not_include(gv, :$11)
|
|
|
|
assert_include(gv, :$12)
|
2016-01-13 21:45:03 -05:00
|
|
|
end
|
|
|
|
|
2008-07-14 02:17:36 -04:00
|
|
|
def test_global_variable_0
|
2008-07-15 11:26:04 -04:00
|
|
|
assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
|
2008-07-14 02:17:36 -04:00
|
|
|
end
|
2010-01-21 11:08:40 -05:00
|
|
|
|
2016-12-06 07:49:46 -05:00
|
|
|
def test_global_variable_popped
|
2014-11-22 18:47:22 -05:00
|
|
|
assert_nothing_raised {
|
|
|
|
EnvUtil.suppress_warning {
|
|
|
|
eval("$foo; 1")
|
|
|
|
}
|
|
|
|
}
|
2010-01-21 11:08:40 -05:00
|
|
|
end
|
2010-01-22 09:53:12 -05:00
|
|
|
|
2016-12-06 07:49:46 -05:00
|
|
|
def test_constant_popped
|
2014-11-22 18:47:22 -05:00
|
|
|
assert_nothing_raised {
|
|
|
|
EnvUtil.suppress_warning {
|
|
|
|
eval("TestVariable::Gods; 1")
|
|
|
|
}
|
|
|
|
}
|
2010-01-22 09:53:12 -05:00
|
|
|
end
|
variable.c: remove generic ivar support for special constants
Special constants are all frozen since [Feature #8923] and cannot
support ivars. Remove some unused code we had for supporting them.
* variable.c (special_generic_ivar): remove flag
(givar_i, rb_mark_generic_ivar_tbl): remove functions
(rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
generic_ivar_set, rb_ivar_set, rb_ivar_defined,
rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
rb_obj_remove_instance_variable):
adjust for lack of ivar support in special constants
* test/ruby/test_variable.rb: test ivars for special consts
* internal.h: remove rb_mark_generic_ivar_tbl decl
* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-03 16:53:35 -04:00
|
|
|
|
|
|
|
def test_special_constant_ivars
|
|
|
|
[ true, false, :symbol, "dsym#{rand(9999)}".to_sym, 1, 1.0 ].each do |v|
|
|
|
|
assert_empty v.instance_variables
|
2019-05-27 20:52:35 -04:00
|
|
|
msg = "can't modify frozen #{v.class}: #{v.inspect}"
|
variable.c: remove generic ivar support for special constants
Special constants are all frozen since [Feature #8923] and cannot
support ivars. Remove some unused code we had for supporting them.
* variable.c (special_generic_ivar): remove flag
(givar_i, rb_mark_generic_ivar_tbl): remove functions
(rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
generic_ivar_set, rb_ivar_set, rb_ivar_defined,
rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
rb_obj_remove_instance_variable):
adjust for lack of ivar support in special constants
* test/ruby/test_variable.rb: test ivars for special consts
* internal.h: remove rb_mark_generic_ivar_tbl decl
* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-03 16:53:35 -04:00
|
|
|
|
2017-12-11 19:46:34 -05:00
|
|
|
assert_raise_with_message(FrozenError, msg) do
|
variable.c: remove generic ivar support for special constants
Special constants are all frozen since [Feature #8923] and cannot
support ivars. Remove some unused code we had for supporting them.
* variable.c (special_generic_ivar): remove flag
(givar_i, rb_mark_generic_ivar_tbl): remove functions
(rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
generic_ivar_set, rb_ivar_set, rb_ivar_defined,
rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
rb_obj_remove_instance_variable):
adjust for lack of ivar support in special constants
* test/ruby/test_variable.rb: test ivars for special consts
* internal.h: remove rb_mark_generic_ivar_tbl decl
* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-03 16:53:35 -04:00
|
|
|
v.instance_variable_set(:@foo, :bar)
|
|
|
|
end
|
|
|
|
|
2016-02-19 02:58:09 -05:00
|
|
|
assert_nil EnvUtil.suppress_warning {v.instance_variable_get(:@foo)}
|
2016-02-19 02:45:58 -05:00
|
|
|
assert_not_send([v, :instance_variable_defined?, :@foo])
|
variable.c: remove generic ivar support for special constants
Special constants are all frozen since [Feature #8923] and cannot
support ivars. Remove some unused code we had for supporting them.
* variable.c (special_generic_ivar): remove flag
(givar_i, rb_mark_generic_ivar_tbl): remove functions
(rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
generic_ivar_set, rb_ivar_set, rb_ivar_defined,
rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
rb_obj_remove_instance_variable):
adjust for lack of ivar support in special constants
* test/ruby/test_variable.rb: test ivars for special consts
* internal.h: remove rb_mark_generic_ivar_tbl decl
* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-03 16:53:35 -04:00
|
|
|
|
2017-12-11 19:46:34 -05:00
|
|
|
assert_raise_with_message(FrozenError, msg) do
|
variable.c: remove generic ivar support for special constants
Special constants are all frozen since [Feature #8923] and cannot
support ivars. Remove some unused code we had for supporting them.
* variable.c (special_generic_ivar): remove flag
(givar_i, rb_mark_generic_ivar_tbl): remove functions
(rb_free_generic_ivar, rb_ivar_lookup, rb_ivar_delete,
generic_ivar_set, rb_ivar_set, rb_ivar_defined,
rb_copy_generic_ivar, rb_ivar_foreach, rb_ivar_count,
rb_obj_remove_instance_variable):
adjust for lack of ivar support in special constants
* test/ruby/test_variable.rb: test ivars for special consts
* internal.h: remove rb_mark_generic_ivar_tbl decl
* gc.c (gc_mark_roots): remove rb_mark_generic_ivar_tbl call
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-03 16:53:35 -04:00
|
|
|
v.remove_instance_variable(:@foo)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2015-11-11 03:38:27 -05:00
|
|
|
|
fastpath for ivar read of FL_EXIVAR objects.
vm_getivar() provides fastpath for T_OBJECT by caching an index
of ivar. This patch also provides fastpath for FL_EXIVAR objects.
FL_EXIVAR objects have an each ivar array and index can be cached
as T_OBJECT. To access this ivar array, generic_iv_tbl is exposed
by rb_ivar_generic_ivtbl() (declared in variable.h which is newly
introduced).
Benchmark script:
Benchmark.driver(repeat_count: 3){|x|
x.executable name: 'clean', command: %w'../clean/miniruby'
x.executable name: 'trunk', command: %w'./miniruby'
objs = [Object.new, 'str', {a: 1, b: 2}, [1, 2]]
objs.each.with_index{|obj, i|
rep = obj.inspect
rep = 'Object.new' if /\#/ =~ rep
x.prelude str = %Q{
v#{i} = #{rep}
def v#{i}.foo
@iv # ivar access method (attr_reader)
end
v#{i}.instance_variable_set(:@iv, :iv)
}
puts str
x.report %Q{
v#{i}.foo
}
}
}
Result:
v0.foo # T_OBJECT
clean: 85387141.8 i/s
trunk: 85249373.6 i/s - 1.00x slower
v1.foo # T_STRING
trunk: 57894407.5 i/s
clean: 39957178.6 i/s - 1.45x slower
v2.foo # T_HASH
trunk: 56629413.2 i/s
clean: 39227088.9 i/s - 1.44x slower
v3.foo # T_ARRAY
trunk: 55797530.2 i/s
clean: 38263572.9 i/s - 1.46x slower
2019-11-28 13:02:44 -05:00
|
|
|
class ExIvar < Hash
|
|
|
|
def initialize
|
|
|
|
@a = 1
|
|
|
|
@b = 2
|
|
|
|
@c = 3
|
|
|
|
end
|
|
|
|
|
|
|
|
def ivars
|
|
|
|
[@a, @b, @c]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_external_ivars
|
|
|
|
3.times{
|
|
|
|
# check inline cache for external ivar access
|
|
|
|
assert_equal [1, 2, 3], ExIvar.new.ivars
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2015-11-11 03:38:27 -05:00
|
|
|
def test_local_variables_with_kwarg
|
|
|
|
bug11674 = '[ruby-core:71437] [Bug #11674]'
|
|
|
|
v = with_kwargs_11(v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8,v9:9,v10:10,v11:11)
|
|
|
|
assert_equal(%i(v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11), v, bug11674)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
def with_kwargs_11(v1:, v2:, v3:, v4:, v5:, v6:, v7:, v8:, v9:, v10:, v11:)
|
|
|
|
local_variables
|
|
|
|
end
|
2003-09-04 12:18:59 -04:00
|
|
|
end
|