-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ruby 2.7: Better support of Integer#[] with range arguments #2182
Changes from 6 commits
f77f2a2
cda845a
5a7bbb8
61f2703
1382260
a260037
f427326
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,6 +38,7 @@ | |
Object.deprecate_constant :Fixnum, :Bignum | ||
|
||
class Integer < Numeric | ||
FIXNUM_MAX = 0x3fffffff | ||
|
||
# Have a copy in Integer of the Numeric version, as MRI does | ||
alias_method :remainder, :remainder | ||
|
@@ -59,9 +60,57 @@ def **(o) | |
redo_coerced :**, o | ||
end | ||
|
||
def [](index) | ||
def [](index, len = undefined) | ||
if index.kind_of?(Range) | ||
handle_range(index) | ||
else | ||
handle_aref(index, len) | ||
end | ||
end | ||
|
||
private def handle_aref(index, len) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't have extra methods on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I addressed all the comments apart from this one, not sure what I can do here. More general question, trying to avoid creating extra private methods is dictated by how truffleruby treats such code or it's code style preference? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's because a Ruby program might notice this, e.g. some Ruby program would defined a |
||
index = Primitive.rb_to_int(index) | ||
index < 0 ? 0 : (self >> index) & 1 | ||
if Primitive.undefined?(len) | ||
index < 0 ? 0 : (self >> index) & 1 | ||
else | ||
num = self >> index | ||
mask = (1 << len) - 1 | ||
|
||
num & mask | ||
end | ||
end | ||
|
||
private def handle_range(range) | ||
validate_range(range) | ||
|
||
if !Primitive.nil?(range.begin) && !Primitive.nil?(range.end) | ||
len = range.end - range.begin | ||
num = self >> range.begin | ||
mask = mask(range, len) | ||
|
||
range.end < range.begin ? num : num & mask | ||
elsif Primitive.nil? range.end | ||
|
||
return self >> range.begin | ||
else | ||
result = self & mask(range, range.end) | ||
raise ArgumentError, 'The beginless range for Integer#[] results in infinity' if result != 0 && range.end >= 0 | ||
|
||
0 | ||
end | ||
end | ||
|
||
private def validate_range(index) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you inline this method? |
||
raise FloatDomainError , 'Infinity' if index.begin == Float::INFINITY || index.end == Float::INFINITY | ||
raise FloatDomainError , '-Infinity' if index.begin == -Float::INFINITY || index.end == -Float::INFINITY | ||
end | ||
|
||
private def mask(range, idx) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you move this logic in the two callers, and e.g. do |
||
if range.exclude_end? | ||
(1 << idx) - 1 | ||
else | ||
(1 << (idx +1)) - 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
end | ||
end | ||
|
||
def allbits?(mask) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eregon not sure that it's safe to hardcode this value, but I did't find better solution, mb you know?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems odd to me we even need this value to implement Integer#[], do you know which arguments return it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this anymore.