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

adding the -s flag to show_source #770

Merged
merged 1 commit into from
Nov 28, 2023

Conversation

paulreece
Copy link
Contributor

@paulreece paulreece commented Nov 19, 2023

This enhancement allows a user to add the -s flag if they want to access a methods origin definition. It allows for chaining of multiple esses to further go up the classes as needed.

With the following code:

class Foo
  def foo
  end
end

class Bar < Foo
  def foo
    super
  end
end

If you call show_source Bar#foo -s it will return:

From: test.rb:4

  def foo
  end

Closes #718.

@paulreece paulreece changed the title adding the s flag to show_source Nov 19, 2023
@paulreece paulreece force-pushed the add_s_to_show_source branch 6 times, most recently from 5f8bc7a to e42514d Compare November 19, 2023 16:05
@paulreece
Copy link
Contributor Author

Sorry for all of the pushes! My test file had a namespace clash with the Foo class that was being used by the other tests. I just changed it to Baz instead. :)

@paulreece paulreece changed the title adding the s flag to show_source adding the -s flag to show_source Nov 19, 2023
Copy link
Member

@st0012 st0012 left a comment

Choose a reason for hiding this comment

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

Thank you for the PR! Just few comments about testing.

test/irb/test_cmd.rb Outdated Show resolved Hide resolved
test/irb/test_cmd.rb Outdated Show resolved Hide resolved
test/irb/test_cmd.rb Show resolved Hide resolved
@st0012 st0012 added the enhancement New feature or request label Nov 19, 2023
@paulreece paulreece force-pushed the add_s_to_show_source branch 3 times, most recently from 117aa20 to 2839617 Compare November 20, 2023 22:30
test/irb/test_cmd.rb Outdated Show resolved Hide resolved
lib/irb/source_finder.rb Outdated Show resolved Hide resolved
lib/irb/source_finder.rb Outdated Show resolved Hide resolved
@@ -26,6 +31,13 @@ def find_source(signature)
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
owner = eval(Regexp.last_match[:owner], context_binding)
method = Regexp.last_match[:method]
if esses
super_owner = owner
s_count.times {|s| super_owner = super_owner.superclass}
Copy link
Member

@tompng tompng Nov 23, 2023

Choose a reason for hiding this comment

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

If there are too many -ssss, super_owner.superclass raises undefined method `superclass' for nil:NilClass. Adding this to test code would be great

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added this test in there already in the previous commit:

    def test_show_source_method_exceeds_super_chain
      code = <<~RUBY
        class Baz
          def foo
          end
        end
      
        class Bar < Baz
          def foo
            super
          end
        end
      RUBY
      File.write("#{@tmpdir}/bazbar.rb", code)
      out, err = execute_lines(
        "irb_load '#{@tmpdir}/bazbar.rb'\n",
        "show_source Bar#foo -ss",
      )
      assert_match(%r[Error: Couldn't locate a definition for Bar#foo -ss\n=> nil\n], out)
    end

Does that cover the use case you're referring to? If not I'm happy to add another.

lib/irb/source_finder.rb Outdated Show resolved Hide resolved
@paulreece paulreece force-pushed the add_s_to_show_source branch 2 times, most recently from 7476427 to ee22f4a Compare November 24, 2023 17:53
@paulreece
Copy link
Contributor Author

FYI: the truffleruby tests seem to be erroring out with some gem dependency errors

lib/irb/cmd/show_source.rb Outdated Show resolved Hide resolved
@paulreece paulreece force-pushed the add_s_to_show_source branch 2 times, most recently from 1918cfa to 631de04 Compare November 25, 2023 18:38
Copy link
Member

@st0012 st0012 left a comment

Choose a reason for hiding this comment

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

I have a few ideas for small improvements and adopting the same flag to edit. But I think it's good to merge now. I'll let @tompng do another pass before pushing the button though.

@paulreece Thank you so much for the work on this PR, as well as all the feedback you provided during RubyConf ❤️

@paulreece
Copy link
Contributor Author

@paulreece Thank you so much for the work on this PR, as well as all the feedback you provided during RubyConf ❤️

@st0012 you're welcome! It was a pleasure working with you and @tompng on this PR. I'm happy to try to address other items from the RubyConf issues or other open bug issues if you'd like. I really enjoy how constructive working in this repo is. :)

@st0012
Copy link
Member

st0012 commented Nov 25, 2023

@paulreece It's not listed in the issues yet, but I'd really like to make show_source command provide more metadata about the method, like the ones from Pry:

Visibility: public
Signature: baz()
Number of lines: 3

You are definitely welcome to work on any other issues :-) But this one just came up to me today.

@paulreece
Copy link
Contributor Author

It's not listed in the issues yet, but I'd really like to make show_source command provide more metadata about the method, like the ones from Pry:

Visibility: public
Signature: baz()
Number of lines: 3

Awesome! I'll get started on this one!

lib/irb/source_finder.rb Outdated Show resolved Hide resolved
end
methods = owner.instance_methods + owner.private_instance_methods
file, line = owner.instance_method(method).source_location if methods.include?(method.to_sym)
Copy link
Member

Choose a reason for hiding this comment

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

Sorry that I only found this now: I think it's also possible to get the method through super_method? Something like:

target_method = owner.instance_method(method)

s_count.times do |s|
  target_method = target_method.super_method if target_method
end

file, line = target_method.source_location if target_method

end
methods = owner.instance_methods + owner.private_instance_methods
file, line = owner.instance_method(method).source_location if methods.include?(method.to_sym)
when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
receiver = eval(Regexp.last_match[:receiver] || 'self', context_binding)
Copy link
Member

Choose a reason for hiding this comment

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

If we can use the above approach, we can support these signatures too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just so I'm understanding this correctly. We would be combining the two different case statements here when I implement the above approach? Or would I be adding this target_method logic into each one?

 when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method

 when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ 

Copy link
Member

Choose a reason for hiding this comment

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

Not combining the case statements. I imagine you can extract the super lookup logic into a private method and use it in both cases instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Implemented this and refactored find_source a bit as well. Lmk what you think!

"irb_load '#{@tmpdir}/bazbar.rb'\n",
"show_source Bar#foo -s",
)
assert_match(%r[Error: Couldn't locate a super definition for Bar#foo\n], out)
Copy link
Member

Choose a reason for hiding this comment

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

CI (ruby-core setup) is failing in this line.
You can reproduce it by removing def test_show_source_method_multiple_s and run rake test TEST=test/irb/test_cmd.rb in local.

The problem is that after other test, Object::Baz still remains with method foo defined.
In this case, class Baz; end is not a class definition but an open-class.
The test accidentally passed in other CI because source_location file bazbarbob.rb was already deleted.

I think the easiest way to fix this is to add these in all added tests

ensure
  Object.remove_const :Bar
  Object.remove_const :Baz
  Object.remove_const :Bob
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ended up just changing the method names in each test since it wouldn't let me access the remove_const method now these pass even when commenting out def test_show_source_method_multiple_s

TruffleRuby CI is failing because of a gem I believe:

In Gemfile:
  debug was resolved to 1.8.0, which depends on
    irb was resolved to 1.9.1, which depends on
      rdoc was resolved to 6.6.0, which depends on
        psych was resolved to 5.1.1.1, which depends on
          stringio
Error: The process '/home/runner/.rubies/truffleruby-head/bin/bundle' failed with exit code 5

Copy link
Member

Choose a reason for hiding this comment

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

(Don't worry about truffleruby for now, we're aware of the problem and have contacted related teams)

…ess a methods origin definition. It allows for chaining of multiple esses to further go up the classes as needed.
Copy link
Member

@st0012 st0012 left a comment

Choose a reason for hiding this comment

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

Thank you so much!

@st0012 st0012 merged commit eec1329 into ruby:master Nov 28, 2023
22 of 24 checks passed
matzbot pushed a commit to ruby/ruby that referenced this pull request Nov 28, 2023
want to access a methods origin definition.  It allows for chaining
of multiple esses to further go up the classes as needed.
(ruby/irb#770)

ruby/irb@eec1329d5a
@jemmaissroff
Copy link

👋 Looks like this PR has introduced test failures in the ruby/ruby master build (https://github.com/ruby/ruby/commits/master). Flagging in case you weren't aware

@st0012
Copy link
Member

st0012 commented Nov 28, 2023

Thanks for flagging it. I've just addressed the issues (hopefully) in #793. But I think the commit was not synced to ruby/ruby?

@jemmaissroff
Copy link

Hmm interesting, it does seem it wasn't synced. Oddly too, it doesn't appear in the #alerts-sync channel in RubyLang slack which usually indicates sync failures. Perhaps we can try syncing it manually?

@paulreece
Copy link
Contributor Author

Sorry about that y'all. @st0012 Do you have any suggestions for the next PR I open in order to avoid the bug issues that the tests caused on this one? Maybe I setup the tests a bit differently?

@st0012
Copy link
Member

st0012 commented Nov 28, 2023

Just add new tests to the new file added in #793 should be enough 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

Support -s option in edit and show_source commands
5 participants