Skip to content
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

TypeError Regexp#match?(nil) in Ruby Head #37504

Merged
merged 1 commit into from Nov 4, 2019

Conversation

utilum
Copy link
Contributor

@utilum utilum commented Oct 18, 2019

Aa of ruby/ruby@2a22a6b calling
Regexp#match?(nil) raises an exception.

This fixes instances instances raised by the test suite.

@kaspth
Copy link
Contributor

kaspth commented Oct 19, 2019

What would the perf/memory impact be of using to_s for some of these? Or what about swapping the order so we can do nil&.match?(/regexp/)?

@utilum
Copy link
Contributor Author

utilum commented Oct 19, 2019

I'll have a look.

@@ -346,7 +346,7 @@ def check_part(name, part, path_params, hash)
end

def split_to(to)
if /#/.match?(to)
if !to.nil? && /#/.match?(to)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simplify to if to && /#/.match?(to) here and other places.
If to was false, it would already raise a TypeError in <=2.6.

@@ -355,7 +355,7 @@ def split_to(to)

def add_controller_module(controller, modyoule)
if modyoule && !controller.is_a?(Regexp)
if %r{\A/}.match?(controller)
if !controller.nil? && %r{\A/}.match?(controller)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if controller && controller.start_with?('/') would be more readable here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using start_with? here should have been enforced by RuboCop in #32695, but wasn't due to a bug (rubocop/rubocop#7464).

In any case, I think this patch should only contain changes required for compatibility with ruby/ruby#1506, no matter how tempting adjacent refactorings may be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, it's probably safer to just directly fix the compatibility with ruby-head in this PR.

@@ -280,7 +280,11 @@ def layout(layout, conditions = {})
def _write_layout_method # :nodoc:
silence_redefinition_of_method(:_layout)

prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
if _implied_layout_name.nil?
["layouts"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not assigned to prefixes.
It seems better to keep the condition together:

prefixes = if _implied_layout_name && /\blayouts/.match?(_implied_layout_name)
  []
else
  ["layouts"]
end

@@ -620,7 +620,7 @@ def extract_default_function(default_value, default)
end

def has_default_function?(default_value, default)
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
!default.nil? && !default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this to keep closer to the original code and avoid double negation:

Suggested change
!default.nil? && !default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
!default_value && default && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)

Copy link
Contributor

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@utilum utilum force-pushed the no_implicit_conversion_of_nil branch 4 times, most recently from c328207 to 32e4e0c Compare October 28, 2019 06:31
Copy link
Member

@rafaelfranca rafaelfranca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion this is a backward incompatible change in Ruby and should be fixed there.

@eregon
Copy link
Contributor

eregon commented Nov 1, 2019

Discussion on the Ruby tracker: https://bugs.ruby-lang.org/issues/13083

It still seems unintentional to me to pass nil to match/match? so I think this would be useful to change in Rails whether that behavior is deprecated or raises.

@rafaelfranca
Copy link
Member

I'm fine with changing the code to avoid deprecation but I think we can avoid that this change break apps.

@eugeneius
Copy link
Member

There's one more match? call that needs to be fixed:

if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)

It currently causes the Active Record test suite to fail when run with the mysql2 adapter:

$ bundle exec rake test:mysql2
# ...
/Users/eugene/lib/rails/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb:165:in `match?': no implicit conversion of nil into String (TypeError)
rake aborted!

Aa of ruby/ruby@2a22a6b calling
`Regexp#match?(nil)` raises an exception.

[utilum, eregon, eugeneius]
@utilum utilum force-pushed the no_implicit_conversion_of_nil branch from 32e4e0c to 2ca6830 Compare November 3, 2019 09:26
@eugeneius
Copy link
Member

@utilum did you explore @kaspth's suggestion of using the safe navigation operator here? It looks like it could be applied uniformly, instead of the current approach that solves each one slightly differently (switching unless to if, replacing ternaries, adding branches to conditionals, etc.)

@eugeneius
Copy link
Member

ruby/ruby#2637 was merged, so Regexp#match?(nil) will no longer raise in Ruby 2.7, but this patch is still useful to avoid the deprecation warnings.

@rafaelfranca rafaelfranca merged commit 4e10538 into rails:master Nov 4, 2019
rafaelfranca added a commit that referenced this pull request Nov 4, 2019
TypeError Regexp#match?(nil) in Ruby Head
@utilum utilum deleted the no_implicit_conversion_of_nil branch November 4, 2019 20:36
rafaelfranca added a commit that referenced this pull request Dec 9, 2019
…of_nil"

This reverts commit 4e10538, reversing
changes made to 62b4383.

The change in Ruby that made those changes required was reverted in
https://bugs.ruby-lang.org/projects/ruby-trunk/repository/git/revisions/8852fa876039ed177fd5e867f36177d8a9ff411c
rafaelfranca added a commit that referenced this pull request Dec 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants