1
0
Fork 0
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:
matz 2004-07-14 14:51:42 +00:00
parent 1a760a6f76
commit 6c6a24826c
7 changed files with 113 additions and 25 deletions

View file

@ -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
View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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);