mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
1a760a6f76
commit
6c6a24826c
7 changed files with 113 additions and 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
|
||||
|
|
102
enum.c
102
enum.c
|
@ -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;
|
||||
|
@ -756,6 +742,92 @@ enum_max(obj)
|
|||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
9
parse.y
9
parse.y
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue