diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-07-14 14:51:42 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-07-14 14:51:42 +0000 |
commit | 6c6a24826c5fda68e04e71ac17620b0e70bca265 (patch) | |
tree | c2692457fbae375c8a38fd64a90a852365e331fc | |
parent | 1a760a6f76e5b2fad343fce10ebf831fe22286b4 (diff) | |
download | ruby-6c6a24826c5fda68e04e71ac17620b0e70bca265.tar.gz |
* enum.c (enum_min_by): new method Enum#min_by. added Enum#max_by
as well.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6629 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | enum.c | 102 | ||||
-rw-r--r-- | lib/cgi/session.rb | 4 | ||||
-rw-r--r-- | lib/date.rb | 8 | ||||
-rw-r--r-- | lib/thread.rb | 9 | ||||
-rw-r--r-- | lib/timeout.rb | 1 | ||||
-rw-r--r-- | parse.y | 9 |
7 files changed, 113 insertions, 25 deletions
@@ -1,3 +1,8 @@ +Wed Jul 14 23:49:30 2004 Yukihiro Matsumoto <matz@ruby-lang.org> + + * enum.c (enum_min_by): new method Enum#min_by. added Enum#max_by + as well. + Wed Jul 14 18:05:21 2004 GOTOU Yuuzou <gotoyuzo@notwork.org> * ext/openssl/ossl_asn1.c (ossl_asn1cons_to_der): fix type of @@ -677,20 +677,6 @@ enum_min(obj) return result; } -/* - * call-seq: - * enum.max => obj - * enum.max {| a,b | block } => obj - * - * Returns the object in <i>enum</i> with the maximum value. The - * first form assumes all objects implement <code>Comparable</code>; - * the second uses the block to return <em>a <=> b</em>. - * - * a = %w(albatross dog horse) - * a.max #=> "horse" - * a.max {|a,b| a.length <=> b.length } #=> "albatross" - */ - static VALUE max_i(i, memo) VALUE i; @@ -757,6 +743,92 @@ enum_max(obj) } static VALUE +min_by_i(i, memo) + VALUE i; + NODE *memo; +{ + VALUE v; + + v = rb_yield(i); + if (NIL_P(memo->u1.value)) { + memo->u1.value = v; + memo->u2.value = i; + } + else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo->u1.value), v, memo->u1.value) < 0) { + memo->u1.value = v; + memo->u2.value = i; + } + return Qnil; +} + +/* + * call-seq: + * enum.min_by {| obj| block } => obj + * + * Returns the object in <i>enum</i> that gives the minimum + * value from the given block. + * + * a = %w(albatross dog horse) + * a.min_by {|x| x.length } #=> "dog" + */ + +static VALUE +enum_min_by(obj) + VALUE obj; +{ + VALUE result; + NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0); + + rb_iterate(rb_each, obj, min_by_i, (VALUE)memo); + result = memo->u2.value; + rb_gc_force_recycle((VALUE)memo); + return result; +} + +static VALUE +max_by_i(i, memo) + VALUE i; + NODE *memo; +{ + VALUE v; + + v = rb_yield(i); + if (NIL_P(memo->u1.value)) { + memo->u1.value = v; + memo->u2.value = i; + } + else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo->u1.value), v, memo->u1.value) > 0) { + memo->u1.value = v; + memo->u2.value = i; + } + return Qnil; +} + +/* + * call-seq: + * enum.max_by {| obj| block } => obj + * + * Returns the object in <i>enum</i> that gives the maximum + * value from the given block. + * + * a = %w(albatross dog horse) + * a.max_by {|x| x.length } #=> "albatross" + */ + +static VALUE +enum_max_by(obj) + VALUE obj; +{ + VALUE result; + NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0); + + rb_iterate(rb_each, obj, max_by_i, (VALUE)memo); + result = memo->u2.value; + rb_gc_force_recycle((VALUE)memo); + return result; +} + +static VALUE member_i(item, memo) VALUE item; NODE *memo; @@ -933,6 +1005,8 @@ Init_Enumerable() rb_define_method(rb_mEnumerable,"any?", enum_any, 0); rb_define_method(rb_mEnumerable,"min", enum_min, 0); rb_define_method(rb_mEnumerable,"max", enum_max, 0); + rb_define_method(rb_mEnumerable,"min_by", enum_min_by, 0); + rb_define_method(rb_mEnumerable,"max_by", enum_max_by, 0); rb_define_method(rb_mEnumerable,"member?", enum_member, 1); rb_define_method(rb_mEnumerable,"include?", enum_member, 1); rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, 0); diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb index cd6ce95f4d..a44de7cb81 100644 --- a/lib/cgi/session.rb +++ b/lib/cgi/session.rb @@ -365,7 +365,6 @@ class CGI raise ArgumentError, "session_id `%s' is invalid" % id end @path = dir+"/"+prefix+id - @path.untaint unless File::exist? @path @hash = {} end @@ -413,7 +412,8 @@ class CGI # Close and delete the session's FileStore file. def delete - File::unlink @path + File::unlink @path + rescue Errno::ENOENT end end diff --git a/lib/date.rb b/lib/date.rb index b50e987852..b8c15a420a 100644 --- a/lib/date.rb +++ b/lib/date.rb @@ -711,7 +711,13 @@ class Date alias_method :__#{id.to_i}__, :#{id.to_s} private :__#{id.to_i}__ def #{id.to_s}(*args, &block) - (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0] + if @__#{id.to_i}__ + @__#{id.to_i}__ + elsif ! self.frozen? + @__#{id.to_i}__ ||= __#{id.to_i}__(*args, &block) + else + __#{id.to_i}__(*args, &block) + end end end; end diff --git a/lib/thread.rb b/lib/thread.rb index 8b27356c48..a069c4680a 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -69,7 +69,7 @@ class Mutex # Returns +true+ if this lock is currently held by some thread. # def locked? - @locked + @locked && true end # @@ -80,7 +80,7 @@ class Mutex result = false Thread.critical = true unless @locked - @locked = true + @locked = Thread.current result = true end Thread.critical = false @@ -92,10 +92,13 @@ class Mutex # def lock while (Thread.critical = true; @locked) + if @locked == Thread.current + raise ThreadError, "deadlock; recursive locking" + end @waiting.push Thread.current Thread.stop end - @locked = true + @locked = Thread.current Thread.critical = false self end diff --git a/lib/timeout.rb b/lib/timeout.rb index 0ba5293d1d..7e3ee81ed0 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -35,6 +35,7 @@ module Timeout def timeout(sec, exception=Error) return yield if sec == nil or sec.zero? + raise ThreadError, "timeout within critical session" if Thread.critical begin x = Thread.current y = Thread.start { @@ -5391,11 +5391,10 @@ static NODE* cond0(node) NODE *node; { - enum node_type type = nd_type(node); - + if (node == 0) return 0; assign_in_cond(node); - switch (type) { + switch (nd_type(node)) { case NODE_DSTR: case NODE_EVSTR: case NODE_STR: @@ -5419,8 +5418,8 @@ cond0(node) case NODE_DOT3: node->nd_beg = range_op(node->nd_beg); node->nd_end = range_op(node->nd_end); - if (type == NODE_DOT2) nd_set_type(node,NODE_FLIP2); - else if (type == NODE_DOT3) nd_set_type(node, NODE_FLIP3); + if (nd_type(node) == NODE_DOT2) nd_set_type(node,NODE_FLIP2); + else if (nd_type(node) == NODE_DOT3) nd_set_type(node, NODE_FLIP3); node->nd_cnt = local_append(internal_id()); if (!e_option_supplied()) { int b = literal_node(node->nd_beg); |