From 3dccb716daaee74d2ae00a5766fe1779fe220a81 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Sat, 17 Feb 2024 23:28:00 +0900 Subject: [PATCH] Use `defined?(yield)` and `SIZED_ENUMERATOR` Prefer built-in features over method calls that may be overridden. --- array.rb | 2 +- kernel.rb | 8 ++++---- numeric.c | 6 ++++++ numeric.rb | 4 ++-- object.c | 6 ++++++ 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/array.rb b/array.rb index 59008b01b1..8e809b35c9 100644 --- a/array.rb +++ b/array.rb @@ -44,7 +44,7 @@ class Array def each Primitive.attr! :inline_block unless defined?(yield) - return to_enum(:each) { self.length } + return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, ary_enum_length)' end _i = 0 value = nil diff --git a/kernel.rb b/kernel.rb index 5fa8a0d826..9b853e9560 100644 --- a/kernel.rb +++ b/kernel.rb @@ -129,7 +129,7 @@ module Kernel # def then Primitive.attr! :inline_block - unless block_given? + unless defined?(yield) return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)' end yield(self) @@ -145,7 +145,7 @@ module Kernel # def yield_self Primitive.attr! :inline_block - unless block_given? + unless defined?(yield) return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)' end yield(self) @@ -182,8 +182,8 @@ module Kernel # } #=> :ok def loop Primitive.attr! :inline_block - unless block_given? - return enum_for(:loop) { Float::INFINITY } + unless defined?(yield) + return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size)' end begin diff --git a/numeric.c b/numeric.c index 5a8d40101d..5c28618a1a 100644 --- a/numeric.c +++ b/numeric.c @@ -5664,6 +5664,12 @@ int_downto(VALUE from, VALUE to) return from; } +static VALUE +int_dotimes_size(VALUE num, VALUE args, VALUE eobj) +{ + return int_neg_p(num) ? INT2FIX(0) : num; +} + /* * call-seq: * round(ndigits= 0, half: :up) -> integer diff --git a/numeric.rb b/numeric.rb index c99a75a910..4dc406fd23 100644 --- a/numeric.rb +++ b/numeric.rb @@ -230,8 +230,8 @@ class Integer # With no block given, returns an Enumerator. def times Primitive.attr! :inline_block - unless block_given? - return to_enum(:times) { self < 0 ? 0 : self } + unless defined?(yield) + return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, int_dotimes_size)' end i = 0 while i < self diff --git a/object.c b/object.c index 9f397b7a70..69602ac8d0 100644 --- a/object.c +++ b/object.c @@ -3988,6 +3988,12 @@ f_sprintf(int c, const VALUE *v, VALUE _) return rb_f_sprintf(c, v); } +static VALUE +rb_f_loop_size(VALUE self, VALUE args, VALUE eobj) +{ + return DBL2NUM(HUGE_VAL); +} + /* * Document-class: Class *