mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
9b383bd6cf
string (e.g. ?x). * lib/tempfile.rb (Tempfile::make_tmpname): put dot between basename and pid. [ruby-talk:196272] * parse.y (do_block): remove -> style block. * parse.y (parser_yylex): remove tLAMBDA_ARG. * eval.c (rb_call0): binding for the return event hook should have consistent scope. [ruby-core:07928] * eval.c (proc_invoke): return behavior should depend whether it is surrounded by a lambda or a mere block. * eval.c (formal_assign): handles post splat arguments. * eval.c (rb_call0): ditto. * st.c (strhash): use FNV-1a hash. * parse.y (parser_yylex): removed experimental ';;' terminator. * eval.c (rb_node_arity): should be aware of post splat arguments. * eval.c (rb_proc_arity): ditto. * parse.y (f_args): syntax rule enhanced to support arguments after the splat. * parse.y (block_param): ditto for block parameters. * parse.y (f_post_arg): mandatory formal arguments after the splat argument. * parse.y (new_args_gen): generate nodes for mandatory formal arguments after the splat argument. * eval.c (rb_eval): dispatch mandatory formal arguments after the splat argument. * parse.y (args): allow more than one splat in the argument list. * parse.y (method_call): allow aref [] to accept all kind of method argument, including assocs, splat, and block argument. * eval.c (SETUP_ARGS0): prepare block argument as well. * lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931] * eval.c (error_line): print receivers true/false/nil specially. * eval.c (rb_proc_yield): handles parameters in yield semantics. * eval.c (nil_yield): gives LocalJumpError to denote no block error. * io.c (rb_io_getc): now takes one-character string. * string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo hashing algorithm. * string.c (rb_str_aref): str[0] now returns 1 character string, instead of a fixnum. [Ruby2] * parse.y (parser_yylex): ?c now returns 1 character string, instead of a fixnum. [Ruby2] * string.c (rb_str_aset): no longer support fixnum insertion. * eval.c (umethod_bind): should not update original class. [ruby-dev:28636] * eval.c (ev_const_get): should support constant access from within instance_eval(). [ruby-dev:28327] * time.c (time_timeval): should round for usec floating number. [ruby-core:07896] * time.c (time_add): ditto. * dir.c (sys_warning): should not call a vararg function rb_sys_warning() indirectly. [ruby-core:07886] * numeric.c (flo_divmod): the first element of Float#divmod should be an integer. [ruby-dev:28589] * test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder. * re.c (rb_reg_initialize): should not allow modifying literal regexps. frozen check moved from rb_reg_initialize_m as well. * re.c (rb_reg_initialize): should not modify untainted objects in safe levels higher than 3. * re.c (rb_memcmp): type change from char* to const void*. * dir.c (dir_close): should not close untainted dir stream. * dir.c (GetDIR): add tainted/frozen check for each dir operation. * lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg): typo fixed. a patch from Florian Gross <florg at florg.net>. * eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from event_hooks. no guarantee for arbitrary hook deletion. [ruby-dev:28632] * util.c (ruby_strtod): differ addition to minimize error. [ruby-dev:28619] * util.c (ruby_strtod): should not raise ERANGE when the input string does not have any digits. [ruby-dev:28629] * eval.c (proc_invoke): should restore old ruby_frame->block. thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833] also fix [ruby-dev:28614] as well. * signal.c (trap): sig should be less then NSIG. Coverity found this bug. a patch from Kevin Tew <tewk at tewk.com>. [ruby-core:07823] * math.c (math_log2): add new method inspired by [ruby-talk:191237]. * math.c (math_log): add optional base argument to Math::log(). [ruby-talk:191308] * ext/syck/emitter.c (syck_scan_scalar): avoid accessing uninitialized array element. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07809] * array.c (rb_ary_fill): initialize local variables first. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810] * ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free type_tag. a patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07808] * ext/socket/socket.c (make_hostent_internal): accept ai_family check from Sam Roberts <sroberts at uniserve.com>. [ruby-core:07691] * util.c (ruby_strtod): should not cut off 18 digits for no reason. [ruby-core:07796] * array.c (rb_ary_fill): internalize local variable "beg" to pacify Coverity. [ruby-core:07770] * pack.c (pack_unpack): now supports CRLF newlines. a patch from <tommy at tmtm.org>. [ruby-dev:28601] * applied code clean-up patch from Stefan Huehner <stefan at huehner.org>. [ruby-core:07764] * lib/jcode.rb (String::tr_s): should have translated non squeezing character sequence (i.e. a character) as well. thanks to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090] * ext/socket/socket.c: document update patch from Sam Roberts <sroberts at uniserve.com>. [ruby-core:07701] * lib/mathn.rb (Integer): need not to remove gcd2. a patch from NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570] * parse.y (arg): too much NEW_LIST() * eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen. * eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1. [ruby-dev:28585] * parse.y (arg): use NODE_ARGSCAT for placeholder. * lib/getoptlong.rb (GetoptLong::get): RDoc update patch from mathew <meta at pobox.com>. [ruby-core:07738] * variable.c (rb_const_set): raise error when no target klass is supplied. [ruby-dev:28582] * prec.c (prec_prec_f): documentation patch from <gerardo.santana at gmail.com>. [ruby-core:07689] * bignum.c (rb_big_pow): second operand may be too big even if it's a Fixnum. [ruby-talk:187984] * README.EXT: update symbol description. [ruby-talk:188104] * COPYING: explicitly note GPLv2. [ruby-talk:187922] * parse.y: remove some obsolete syntax rules (unparenthesized method calls in argument list). * eval.c (rb_call0): insecure calling should be checked for non NODE_SCOPE method invocations too. * eval.c (rb_alias): should preserve the current safe level as well as method definition. * process.c (rb_f_sleep): remove RDoc description about SIGALRM which is not valid on the current implementation. [ruby-dev:28464] Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp> * eval.c (method_missing): should support argument splat in super. a bug in combination of super, splat and method_missing. [ruby-talk:185438] * configure.in: Solaris SunPro compiler -rapth patch from <kuwa at labs.fujitsu.com>. [ruby-dev:28443] * configure.in: remove enable_rpath=no for Solaris. [ruby-dev:28440] * ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby String object. * ruby.1: a clarification patch from David Lutterkort <dlutter at redhat.com>. [ruby-core:7508] * lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems directories. a patch from Eric Hodel <drbrain at segment7.net>. [ruby-core:07423] * eval.c (rb_clear_cache_by_class): clearing wrong cache. * ext/extmk.rb: use :remove_destination to install extension libraries to avoid SEGV. [ruby-dev:28417] * eval.c (rb_thread_fd_writable): should not re-schedule output from KILLED thread (must be error printing). * array.c (rb_ary_flatten_bang): allow specifying recursion level. [ruby-talk:182170] * array.c (rb_ary_flatten): ditto. * gc.c (add_heap): a heap_slots may overflow. a patch from Stefan Weil <weil at mail.berlios.de>. * eval.c (rb_call): use separate cache for fcall/vcall invocation. * eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local functions. * eval.c (rb_mod_local): a new method to specify newly added visibility "local". * eval.c (search_method): search for local methods which are visible only from the current class. * class.c (rb_class_local_methods): a method to list local methods. * object.c (Init_Object): add BasicObject class as a top level BlankSlate class. * ruby.h (SYM2ID): should not cast to signed long. [ruby-core:07414] * class.c (rb_include_module): allow module duplication. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
470 lines
9.5 KiB
Ruby
470 lines
9.5 KiB
Ruby
require 'test/unit'
|
|
|
|
class Array
|
|
def iter_test1
|
|
collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}
|
|
end
|
|
def iter_test2
|
|
a = collect{|e| [e, yield(e)]}
|
|
a.sort{|a,b|a[1]<=>b[1]}
|
|
end
|
|
end
|
|
|
|
class TestIterator < Test::Unit::TestCase
|
|
def ttt
|
|
assert(iterator?)
|
|
end
|
|
|
|
def test_iterator
|
|
assert(!iterator?)
|
|
|
|
ttt{}
|
|
|
|
# yield at top level !! here's not toplevel
|
|
assert(!defined?(yield))
|
|
end
|
|
|
|
def test_array
|
|
$x = [1, 2, 3, 4]
|
|
$y = []
|
|
|
|
# iterator over array
|
|
for i in $x
|
|
$y.push i
|
|
end
|
|
assert_equal($x, $y)
|
|
end
|
|
|
|
def tt
|
|
1.upto(10) {|i|
|
|
yield i
|
|
}
|
|
end
|
|
|
|
def tt2(dummy)
|
|
yield 1
|
|
end
|
|
|
|
def tt3(&block)
|
|
tt2(raise(ArgumentError,""),&block)
|
|
end
|
|
|
|
def test_nested_iterator
|
|
i = 0
|
|
tt{|i| break if i == 5}
|
|
assert_equal(5, i)
|
|
|
|
assert_raises(ArgumentError) do
|
|
tt3{}
|
|
end
|
|
end
|
|
|
|
def tt4 &block
|
|
tt2(raise(ArgumentError,""),&block)
|
|
end
|
|
|
|
def test_block_argument_without_paren
|
|
assert_raises(ArgumentError) do
|
|
tt4{}
|
|
end
|
|
end
|
|
|
|
# iterator break/redo/next/retry
|
|
def test_break
|
|
done = true
|
|
loop{
|
|
break
|
|
done = false # should not reach here
|
|
}
|
|
assert(done)
|
|
|
|
done = false
|
|
$bad = false
|
|
loop {
|
|
break if done
|
|
done = true
|
|
next
|
|
$bad = true # should not reach here
|
|
}
|
|
assert(!$bad)
|
|
|
|
done = false
|
|
$bad = false
|
|
loop {
|
|
break if done
|
|
done = true
|
|
redo
|
|
$bad = true # should not reach here
|
|
}
|
|
assert(!$bad)
|
|
|
|
$x = []
|
|
for i in 1 .. 7
|
|
$x.push i
|
|
end
|
|
assert_equal(7, $x.size)
|
|
assert_equal([1, 2, 3, 4, 5, 6, 7], $x)
|
|
|
|
$done = false
|
|
$x = []
|
|
for i in 1 .. 7 # see how retry works in iterator loop
|
|
if i == 4 and not $done
|
|
$done = true
|
|
retry
|
|
end
|
|
$x.push(i)
|
|
end
|
|
assert_equal(10, $x.size)
|
|
assert_equal([1, 2, 3, 1, 2, 3, 4, 5, 6, 7], $x)
|
|
end
|
|
|
|
def test_append_method_to_built_in_class
|
|
$x = [[1,2],[3,4],[5,6]]
|
|
assert_equal($x.iter_test1{|x|x}, $x.iter_test2{|x|x})
|
|
end
|
|
|
|
class IterTest
|
|
def initialize(e); @body = e; end
|
|
|
|
def each0(&block); @body.each(&block); end
|
|
def each1(&block); @body.each {|*x| block.call(*x) } end
|
|
def each2(&block); @body.each {|*x| block.call(x) } end
|
|
def each3(&block); @body.each {|x| block.call(*x) } end
|
|
def each4(&block); @body.each {|x| block.call(x) } end
|
|
def each5; @body.each {|*x| yield(*x) } end
|
|
def each6; @body.each {|*x| yield(x) } end
|
|
def each7; @body.each {|x| yield(*x) } end
|
|
def each8; @body.each {|x| yield(x) } end
|
|
|
|
def f(a)
|
|
a
|
|
end
|
|
end
|
|
|
|
def test_itertest
|
|
assert_equal([1], IterTest.new(nil).method(:f).to_proc.call([1]))
|
|
m = /\w+/.match("abc")
|
|
assert_equal([m], IterTest.new(nil).method(:f).to_proc.call([m]))
|
|
|
|
IterTest.new([0]).each0 {|x| assert_equal(0, x)}
|
|
IterTest.new([1]).each1 {|x| assert_equal(1, x)}
|
|
IterTest.new([2]).each2 {|x| assert_equal([2], x)}
|
|
IterTest.new([4]).each4 {|x| assert_equal(4, x)}
|
|
IterTest.new([5]).each5 {|x| assert_equal(5, x)}
|
|
IterTest.new([6]).each6 {|x| assert_equal(6, x)}
|
|
IterTest.new([8]).each8 {|x| assert_equal(8, x)}
|
|
|
|
IterTest.new([[0]]).each0 {|x| assert_equal(0, x)}
|
|
IterTest.new([[1]]).each1 {|x| assert_equal(1, x)}
|
|
IterTest.new([[2]]).each2 {|x| assert_equal([2], x)}
|
|
IterTest.new([[3]]).each3 {|x| assert_equal(3, x)}
|
|
IterTest.new([[4]]).each4 {|x| assert_equal(4, x)}
|
|
IterTest.new([[5]]).each5 {|x| assert_equal(5, x)}
|
|
IterTest.new([[6]]).each6 {|x| assert_equal(6, x)}
|
|
IterTest.new([[7]]).each7 {|x| assert_equal(7, x)}
|
|
IterTest.new([[8]]).each8 {|x| assert_equal(8, x)}
|
|
|
|
IterTest.new([[0,0]]).each0 {|*x| assert_equal([0,0], x)}
|
|
IterTest.new([[8,8]]).each8 {|*x| assert_equal([8], x)}
|
|
end
|
|
|
|
def m(var)
|
|
var
|
|
end
|
|
|
|
def m1
|
|
m(block_given?)
|
|
end
|
|
|
|
def m2
|
|
m(block_given?,&proc{})
|
|
end
|
|
|
|
def test_block_given
|
|
assert(m1{p 'test'})
|
|
assert(m2{p 'test'})
|
|
assert(!m1())
|
|
assert(!m2())
|
|
end
|
|
|
|
def m3(var, &block)
|
|
m(yield(var), &block)
|
|
end
|
|
|
|
def m4(&block)
|
|
m(m1(), &block)
|
|
end
|
|
|
|
def test_block_passing
|
|
assert(!m4())
|
|
assert(!m4 {})
|
|
assert_equal(100, m3(10) {|x|x*x})
|
|
end
|
|
|
|
class C
|
|
include Enumerable
|
|
def initialize
|
|
@a = [1,2,3]
|
|
end
|
|
def each(&block)
|
|
@a.each(&block)
|
|
end
|
|
end
|
|
|
|
def test_collect
|
|
assert_equal([1,2,3], C.new.collect{|n| n})
|
|
end
|
|
|
|
def test_proc
|
|
assert_instance_of(Proc, lambda{})
|
|
assert_instance_of(Proc, Proc.new{})
|
|
lambda{|a|assert_equal(a, 1)}.call(1)
|
|
end
|
|
|
|
def test_block
|
|
assert_instance_of(NilClass, get_block)
|
|
assert_instance_of(Proc, get_block{})
|
|
end
|
|
|
|
def test_argument
|
|
assert_nothing_raised {lambda{||}.call}
|
|
assert_raises(ArgumentError) {lambda{||}.call(1)}
|
|
assert_nothing_raised {lambda{|a,|}.call(1)}
|
|
assert_raises(ArgumentError) {lambda{|a,|}.call()}
|
|
assert_raises(ArgumentError) {lambda{|a,|}.call(1,2)}
|
|
end
|
|
|
|
def get_block(&block)
|
|
block
|
|
end
|
|
|
|
def test_get_block
|
|
assert_instance_of(Proc, get_block{})
|
|
assert_nothing_raised {get_block{||}.call()}
|
|
assert_nothing_raised {get_block{||}.call(1)}
|
|
assert_nothing_raised {get_block{|a,|}.call(1)}
|
|
assert_nothing_raised {get_block{|a,|}.call()}
|
|
assert_nothing_raised {get_block{|a,|}.call(1,2)}
|
|
|
|
assert_nothing_raised {get_block(&lambda{||}).call()}
|
|
assert_raises(ArgumentError) {get_block(&lambda{||}).call(1)}
|
|
assert_nothing_raised {get_block(&lambda{|a,|}).call(1)}
|
|
assert_raises(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)}
|
|
|
|
block = get_block{11}
|
|
assert_instance_of(Proc, block)
|
|
assert_instance_of(Proc, block.to_proc)
|
|
assert_equal(block.clone.call, 11)
|
|
assert_instance_of(Proc, get_block(&block))
|
|
|
|
lmd = lambda{44}
|
|
assert_instance_of(Proc, lmd)
|
|
assert_instance_of(Proc, lmd.to_proc)
|
|
assert_equal(lmd.clone.call, 44)
|
|
assert_instance_of(Proc, get_block(&lmd))
|
|
|
|
assert_equal(1, Proc.new{|a,| a}.call(1,2,3))
|
|
assert_nothing_raised {Proc.new{|a,|}.call(1,2)}
|
|
end
|
|
|
|
def return1_test
|
|
Proc.new {
|
|
return 55
|
|
}.call + 5
|
|
end
|
|
|
|
def test_return1
|
|
assert_equal(55, return1_test())
|
|
end
|
|
|
|
def return2_test
|
|
lambda {
|
|
return 55
|
|
}.call + 5
|
|
end
|
|
|
|
def test_return2
|
|
assert_equal(60, return2_test())
|
|
end
|
|
|
|
def proc_call(&b)
|
|
b.call
|
|
end
|
|
def proc_yield()
|
|
yield
|
|
end
|
|
def proc_return1
|
|
proc_call{return 42}+1
|
|
end
|
|
|
|
def test_proc_return1
|
|
assert_equal(42, proc_return1())
|
|
end
|
|
|
|
def proc_return2
|
|
proc_yield{return 42}+1
|
|
end
|
|
|
|
def test_proc_return2
|
|
assert_equal(42, proc_return2())
|
|
end
|
|
|
|
def test_ljump
|
|
assert_raises(LocalJumpError) {get_block{break}.call}
|
|
|
|
# cannot use assert_nothing_raised due to passing block.
|
|
begin
|
|
val = lambda{break 11}.call
|
|
rescue LocalJumpError
|
|
assert(false, "LocalJumpError occurred from break in lambda")
|
|
else
|
|
assert(11, val)
|
|
end
|
|
|
|
block = get_block{11}
|
|
lmd = lambda{44}
|
|
assert_equal(0, block.arity)
|
|
assert_equal(0, lmd.arity)
|
|
assert_equal(0, lambda{||}.arity)
|
|
assert_equal(1, lambda{|a|}.arity)
|
|
assert_equal(1, lambda{|a,|}.arity)
|
|
assert_equal(2, lambda{|a,b|}.arity)
|
|
end
|
|
|
|
def marity_test(m)
|
|
mobj = method(m)
|
|
assert_equal(mobj.arity, mobj.to_proc.arity)
|
|
end
|
|
|
|
def test_marity
|
|
marity_test(:assert)
|
|
marity_test(:marity_test)
|
|
marity_test(:p)
|
|
|
|
lambda(&method(:assert)).call(true)
|
|
lambda(&get_block{|a,n| assert(a,n)}).call(true, "marity")
|
|
end
|
|
|
|
def foo
|
|
yield(:key, :value)
|
|
end
|
|
def bar(&blk)
|
|
blk.call(:key, :value)
|
|
end
|
|
|
|
def test_yield_vs_call
|
|
foo{|k,v| assert_equal([:key, :value], [k,v])}
|
|
bar{|k,v| assert_equal([:key, :value], [k,v])}
|
|
end
|
|
|
|
class H
|
|
def each
|
|
yield :key, :value
|
|
end
|
|
end
|
|
|
|
def test_assoc_yield
|
|
[{:key=>:value}, H.new].each {|h|
|
|
h.each{|a| assert_equal(:key, a)}
|
|
h.each{|*a| assert_equal([:key, :value], a)}
|
|
h.each{|k,v| assert_equal([:key, :value], [k,v])}
|
|
}
|
|
end
|
|
|
|
class ITER_TEST1
|
|
def a
|
|
block_given?
|
|
end
|
|
end
|
|
|
|
class ITER_TEST2 < ITER_TEST1
|
|
include Test::Unit::Assertions
|
|
def a
|
|
assert(super)
|
|
super
|
|
end
|
|
end
|
|
|
|
def test_iter_test2
|
|
assert(ITER_TEST2.new.a {})
|
|
end
|
|
|
|
class ITER_TEST3
|
|
def foo x
|
|
return yield if block_given?
|
|
x
|
|
end
|
|
end
|
|
|
|
class ITER_TEST4 < ITER_TEST3
|
|
include Test::Unit::Assertions
|
|
def foo x
|
|
assert_equal(super, yield)
|
|
assert_equal(x, super(x, &nil))
|
|
end
|
|
end
|
|
|
|
def test_iter4
|
|
ITER_TEST4.new.foo(44){55}
|
|
end
|
|
|
|
def test_break__nested_loop1
|
|
_test_break__nested_loop1 do
|
|
break
|
|
end
|
|
end
|
|
|
|
def _test_break__nested_loop1
|
|
while true
|
|
yield
|
|
end
|
|
assert(false, "must not reach here")
|
|
end
|
|
|
|
def test_break__nested_loop2
|
|
_test_break__nested_loop2 do
|
|
break
|
|
end
|
|
end
|
|
|
|
def _test_break__nested_loop2
|
|
until false
|
|
yield
|
|
end
|
|
assert(false, "must not reach here")
|
|
end
|
|
|
|
def test_break__nested_loop3
|
|
_test_break__nested_loop3 do
|
|
break
|
|
end
|
|
end
|
|
|
|
def _test_break__nested_loop3
|
|
loop do
|
|
yield
|
|
end
|
|
assert(false, "must not reach here")
|
|
end
|
|
|
|
def test_break_from_enum
|
|
result = ["a"].inject("ng") {|x,y| break "ok"}
|
|
assert_equal("ok", result)
|
|
end
|
|
|
|
def _test_return_trace_func(x)
|
|
set_trace_func(proc {})
|
|
[].fetch(2) {return x}
|
|
ensure
|
|
set_trace_func(nil)
|
|
end
|
|
|
|
def test_return_trace_func
|
|
ok = "returned gracefully"
|
|
result = "skipped"
|
|
result = _test_return_trace_func(ok)
|
|
ensure
|
|
assert_equal(ok, result)
|
|
return
|
|
end
|
|
end
|