[前][次][番号順一覧][スレッド一覧]

ruby-changes:66154

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Wed, 12 May 2021 10:31:08 +0900 (JST)
Subject: [ruby-changes:66154] 2bc293e899 (master): cdhash_cmp: can take rational literals

https://git.ruby-lang.org/ruby.git/commit/?id=2bc293e899

From 2bc293e899c9d32dcd794a73de8925c49ecf8f15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Fri, 7 May 2021 10:04:08 +0900
Subject: cdhash_cmp: can take rational literals

Rational literals are those integers suffixed with `r`.  They tend to
be a part of more complex expressions like `123/456r`, but in theory
they can live alone.  When such "bare" rational literals are passed to
case-when branch, we have to take care of them.  Fixes [Bug #17854]
---
 common.mk                  |  1 +
 compile.c                  |  7 +++++++
 internal/rational.h        |  1 +
 rational.c                 | 13 ++++++++++---
 test/ruby/test_rational.rb |  7 +++++++
 5 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/common.mk b/common.mk
index f3aa284..5310173 100644
--- a/common.mk
+++ b/common.mk
@@ -2807,6 +2807,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/hash.h https://github.com/ruby/ruby/blob/trunk/common.mk#L2807
 compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
 compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h
 compile.$(OBJEXT): $(top_srcdir)/internal/object.h
+compile.$(OBJEXT): $(top_srcdir)/internal/rational.h
 compile.$(OBJEXT): $(top_srcdir)/internal/re.h
 compile.$(OBJEXT): $(top_srcdir)/internal/serial.h
 compile.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
diff --git a/compile.c b/compile.c
index a3a828f..9001fd1 100644
--- a/compile.c
+++ b/compile.c
@@ -28,6 +28,7 @@ https://github.com/ruby/ruby/blob/trunk/compile.c#L28
 #include "internal/hash.h"
 #include "internal/numeric.h"
 #include "internal/object.h"
+#include "internal/rational.h"
 #include "internal/re.h"
 #include "internal/symbol.h"
 #include "internal/thread.h"
@@ -2004,6 +2005,10 @@ cdhash_cmp(VALUE val, VALUE lit) https://github.com/ruby/ruby/blob/trunk/compile.c#L2005
     else if (tlit == T_FLOAT) {
         return rb_float_cmp(lit, val);
     }
+    else if (tlit ==  T_RATIONAL) {
+        /* Rational literals don't have fractions. */
+        return cdhash_cmp(val, rb_rational_num(lit));
+    }
     else {
         UNREACHABLE_RETURN(-1);
     }
@@ -2022,6 +2027,8 @@ cdhash_hash(VALUE a) https://github.com/ruby/ruby/blob/trunk/compile.c#L2027
         return FIX2LONG(rb_big_hash(a));
       case T_FLOAT:
         return rb_dbl_long_hash(RFLOAT_VALUE(a));
+      case T_RATIONAL:
+        return rb_rational_hash(a);
       default:
         UNREACHABLE_RETURN(0);
     }
diff --git a/internal/rational.h b/internal/rational.h
index e53ee7b..6bbd2a9 100644
--- a/internal/rational.h
+++ b/internal/rational.h
@@ -33,6 +33,7 @@ VALUE rb_rational_div(VALUE self, VALUE other); https://github.com/ruby/ruby/blob/trunk/internal/rational.h#L33
 VALUE rb_lcm(VALUE x, VALUE y);
 VALUE rb_rational_reciprocal(VALUE x);
 VALUE rb_cstr_to_rat(const char *, int);
+VALUE rb_rational_hash(VALUE self);
 VALUE rb_rational_abs(VALUE self);
 VALUE rb_rational_cmp(VALUE self, VALUE other);
 VALUE rb_rational_pow(VALUE self, VALUE other);
diff --git a/rational.c b/rational.c
index c7437df..846e8bd 100644
--- a/rational.c
+++ b/rational.c
@@ -1742,8 +1742,8 @@ nurat_rationalize(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/rational.c#L1742
 }
 
 /* :nodoc: */
-static VALUE
-nurat_hash(VALUE self)
+st_index_t
+rb_rational_hash(VALUE self)
 {
     st_index_t v, h[2];
     VALUE n;
@@ -1754,9 +1754,16 @@ nurat_hash(VALUE self) https://github.com/ruby/ruby/blob/trunk/rational.c#L1754
     n = rb_hash(dat->den);
     h[1] = NUM2LONG(n);
     v = rb_memhash(h, sizeof(h));
-    return ST2FIX(v);
+    return v;
+}
+
+static VALUE
+nurat_hash(VALUE self)
+{
+    return ST2FIX(rb_rational_hash(self));
 }
 
+
 static VALUE
 f_format(VALUE self, VALUE (*func)(VALUE))
 {
diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb
index fe9de64..d7f4961 100644
--- a/test/ruby/test_rational.rb
+++ b/test/ruby/test_rational.rb
@@ -830,6 +830,13 @@ class Rational_Test < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rational.rb#L830
     assert_raise(ZeroDivisionError) {Rational("1/0")}
   end
 
+  def test_cdhash
+    assert_separately([], <<-RUBY)
+      n = case 1 when 2r then false else true end
+      assert_equal(n, true, '[ruby-core:103759] [Bug #17854]')
+    RUBY
+  end
+
   def test_Rational_with_invalid_exception
     assert_raise(ArgumentError) {
       Rational("1/1", exception: 1)
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]