Starting with Ruby 2.4, the integer class will change, but you need to be careful especially if you are writing a C extension.
Of course, there are integers in the Ruby world, but until now (from the Ruby side), under the abstract class ʻInteger,
Fixnumfor integers with small absolute values, and
Bignumfor those that do not fit in it. It was divided into a concrete class called
. About this, I think that the article I wrote before will be helpful.
There were some problems with this shape.
Fixnum
and Bignum
are different implementation details, so there is no need to see the difference from the Ruby side.Fixnum
and Bignum
even though they are the same integer **Fixnum
differs depending on the environment (poor portability)For that reason, from Ruby 2.4, both will be integrated into ʻInteger`.
Normally, when writing a program, there were few situations where you would use Fixnum
or Bignum
directly in the first place, and I don't think it would be a big problem, but there are some points to note. ..
For compatibility with existing programs, the constants Fixnum
and Bignum
will continue to exist, but both will be ** ʻInteger aliases **. Even if each is an open class, it will be like changing ʻInteger
directly (it is better to modify it properly).
And if you check if it fits in Fixnum
likefoo.is_a? (Fixnum)
, it will be regarded asfoo.is_a? (Integer)
in Ruby 2.4, and if it is an integer, it will always be true. I will. The intent of checking for Fixnum
(except in situations where C extensions are involved) is fundamentally a problem, so let's fix it to check the range properly.
Also, this may actually affect in some cases, but if you use the constants Fixnum
and Bignum
as part of the DSL, they will be the same value as ʻInteger`, so it works well. It will not work. Follow the instructions for the gem you are using and replace it appropriately.
In Ruby, the distinction between Fixnum
and Bignum
has been abolished, but in the C language world, the two types of internal structures still exist. So, it doesn't mean that you need to rewrite all the parts that handle integers.
However, in C language, rb_cFixnum
and rb_cBignum
, which represent Fixnum
and Bignum
, are ** obsolete **. If you use these constants, you will get a compile error. As an alternative
FIXNUM_P
[^ 1] or RB_TYPE_P
. The T_BIGNUM
to indicate the internal data structure is alive and well. (
rb_cInteger). If there are separate functions for
Fixnum and
Bignum`, it will be necessary to sort them internally.In addition, RUBY_INTEGER_UNIFICATION
is defined as a constant to support these distributions. Let's separate with #ifdef RUBY_INTEGER_UNIFICATION
.
Check the code for the previously made jkr2255 / bit_utils (Explanation) I tried, but internally there are methods for Fixnum
and Bignum
,
Fixnum
… Throwing Bignum
will result in an errorBignum
... It works with Fixnum
, but a little extra processing is includedIt was like that. And, except when opening Fixnum
and using it, I used it as it is for Bignum
, and even in the open class, I went in the order of Fixnum
→ Bignum
, so everything works fine as it is. It was a flow like going. It worked fine with Ruby 2.4.0-preview2.
However, opening both Fixnum
and Bignum
is bad manners, so I plan to rewrite it.
PDF of slides presented at RubyKaigi
[^ 1]: Very fast because it only looks at one bit.
Recommended Posts