Is it possible to "blackbox" libraries when using Pry?
I like to walk the stack when I hit a breakpoint, but I really don't care about active-record transactions management and such. In fact, it even makes walking the stack completely useless sometimes.
In javascript, it's easy to add scripts to an ignore list and they are just skipped during debugging. Is there a way to achieve a similar behavior with Pry?
Additionnal details
What i mean by stack walk, is using "up" to move to the calling source code line which moves the source code marker to the previous stack frame.
I want to ignore frames that are outside my own code, like ActiveRecord and most third-party gems. I don't mind using either a blacklist or a whitelist.
Bundle gives me these gem versions:
Using byebug 9.0.6
Using pry 0.12.2
Using pry-byebug 3.4.3
The requested functionality does not exist in pry-byebug. You can add your +1 (or write some code) on the following GitHub issue for pry-byebug:
My question/suggestion is that if there's a way to filter or skip over external library, or a setting to step into the next line that belongs to a script within the current application. For example, step into a method call will skip over any Rails's internal script or any currently-used gem and stop at the next line of the file that's inside the application.
As well as this GitHub issue:
I think it would be super useful to have a command that lets you run until you hit the next line of non-Rails/non-gem code.
As the original issue has been open for nearly six years, I think your best bet will be to help build the feature vs. adding a +1 on the existing issues.
The author of pry-byebug also offers this workaround in another SO answer to a very similar question:
you need to manually set breakpoints to jump from controller to view and the other way around
Related
So I started working on my first open-source contribution in ruby. There I have the library I'm working on in the /lib/ folder. Now when I tried changing the code, my program (which uses the library) still uses the old code.
For example: Broke a function on purpose by deleting its end keyword (which should be causing an immediate crash), but it kept working perfectly after I did.
Another example was changing the code in such a way it should still work (mutating the output string) but it still returned the old string.
user~$ bin/ruby-hyphen -V "this is a test sentence"
this is a test sen-tence
Does anyone know if I have to tell the runtime to refresh it or something along those lines?
I found out why that happened. The file has a *.gemspec, which made it act as if it was a gem. To see the changes I needed to enter:
gem build *.gemspec
bundle exec rake install
Or, if you want to develop quicker: change everywhere you require it into a require_relative. That should also fix it. I hope this question helps someone in the future!
I'm trying to set up a working ruby project with guard-rspec.
I've mixed together the general method of a tutsplus tutorial with some new syntax as described in the RSpec videos and another post. The project can be found in the stack-overflow-question branch on github.
I'm also trying to practice namespacing as described in Programming Ruby 1.9. So eventually I'd like to have example.rb in my lib/example/ directory.
There's 4 questions I have about my project:
What do I need to put in my Guardfile to watch specific directories in my project for changes? I've several different ways which can be seen in my Guardfile as comments labelled like:
# Watch Specific Directory Attempt X
What is the difference between uncommenting lines 8 and 9 in my Guardfile (bellow Uncomment and set this to only include directories you want to watch) and adding "named group captures" like watch(%r{^lib/(?<path>.+)\.rb$}) { |m| "spec/lib/#{m[:path]}_spec.rb" } as described here
Where do I need to put the --clear option to make it persistent? I know I can run it with my binstub like bin/guard --clear and I've tried putting that in my Guardfile however it didn't work.
Are there any glaring convention, syntax, or clarity mistakes that you see in my project? I feel like I'm duck taping this whole thing together and I'd appreciate some guidance in piecing this thing together in a sensible way.
I'll answer the question in the title and cover the "sub-questions" as I go.
The best way to set up a project (as of now) is to use bundle exec guard --init rspec. This should give reasonable defaults to start work immediately. It's not perfect, but there is a lot of work planed to improve things, so do ask questions on GitHub instead (makes more sense).
Guard has to maintain backward compatibility, so there are some "non-intuitive" things for now and skimming through all the docs first (and wiki) is a good investment to quickly know what's available and where. Asking when confused or in doubt is also a good idea (one issue per question is best).
Guard uses a DSL to simplify setting up listeners. This is a bit non-intuitive and clunky at times, but it does help organize actions into groups, which can help maintain complex workflows. The DSL's command for e.g. clearing the terminal automatically is: (clearing: on). (This answers question 3).
There are all kinds of uses and scenarios, so Guard tries hard to make everyone happy and on every platform too. Guard uses Listen, which watches directories recursively (due to restrictions on OSX mostly). This usually isn't a problem, but for huge directions on OSX this can be very, very slow. That's why Guard lets you select which top directories to watch (like 'lib', 'app', etc.). Watching the whole project directory is very convenient, so that is still the default. More info on this is at the Listen project. So by default all directories (:directories statement) are "physically watched" (take up operating resources), though in Guard you only configure which changes you want to respond to (which is what watch statements do).
The words chosen are a bit misleading at times. E.g. watch in the DSL actually means: "out of all the changes happening, select changes matching ...". The block passed to watch is given the results of the match. That block should return a list of files for the current guard plugin to run. So "watch" probably is more misleading than helpful. "match" would probably be a better choice and it might replace "watch" in the future.
The guard-rspec project runs RSpec on changed files. You can see the exact RSpec commands if you run guard with the debugging option on, e.g. bundle exec guard -d. To simplify setup, Guard::RSpec uses a DSL that should work out-of-the-box if your project follows a given setup. E.g. dsl.watch_spec_files_for(ruby.lib_files) is defined here: so it pretty much already should do what you want if you put all your tested source files in lib. For other folders, you can add your own. E.g. Rails projects typically have sources also in an app directory, so in the default Guard::RSpec template there's an statement: dsl.watch_spec_files_for(rails.app_files) with the pattern defined as: rails.app_files = %r{^app/(.+)\.rb$} If you have a typical case that isn't covered, open an issue in that project. (covers question 2).
Everything looks fine in the example project and suggestions are mostly based on taste or preference. E.g.
Instead of let (:greeter) { Example::RSpecGreeter.new }, I'd use RSpec's implicit subject (but some may argue that it's less explicit and less readable)
if you're testing Example::RSpecGreeter, I'd recommend putting that class in a separate file and including it instead (require 'example/rspec_greeter')
you might add RubCop/Guard::RuboCop for detecting convention issues (covers 4th question)
you might want to check out Guard's own Guardfile used to test itself for a more "real-life" setup without the documentation clutter.
for best results I think it's best to copy a whole existing project and rename the parts you want to change. Usually there are many hours spent still fine-tuning things like alternate RSpec configs for Travis, special gem release tasks, certain workarounds and conveniences, etc.
When I start debugging using:
ruby -rdebug file.rb
and place break points:
b path:linenumber
before it gets to my break point, it stops at many other points in the imported libraries.
Does any one know how to prevent that?
Note: I already know I can place debugger points in the code which works well, but I do not want to do that since I keep forgetting to remove them.
I'm more thinking of a solution like using an option to prevent stopping at any module under /usr/lib/ruby.
I haven't used rdebug at all yet, but I've been having a great experience using Pry (http://pryrepl.org/). You simply stick a binding.pry anywhere in your code and upon execution you'll get dropped into the context of your binding.pry. You can then inspect variables, methods, navigate to different contexts using ls and cd, etc.
Sorry if this isn't what you were looking for!
In my Rails app, using Ruby 2.0.0-p0 and Rails 3.2.13, I also use the gem debugger for debugging purpose. If I have to debug an area in my source code, for e.g. a controller method, I will put debugger inbetween and when I execute the action, it will go to the source code and then travserse through the framework code a lot and that really mess-up the normal debugging. I can see many commands through help, but don't know how to handle with that.
I just want to traverse through the source code only..
Please help me to have a solution. Thanks :)-
Use byebug instead. It was created to overcome debugger's problems with ruby-2.0.0, like the one that makes it "step" when you use command "next", unexpectedly leading you to framework sources.
Disclaimer: I'm byebug's author
You have some code you want to remove associated with an obsolete piece of functionality from a ruby project. How do ensure that you get rid of all of the code?
Some guidelines that usually help in refactoring ruby apply, but there are added challenges because having code that isn't being called by anything won't break any unit tests.
Update: Has anyone written anything that allows you to guess based on your version control history if there are commits where you have since deleted most, but not all, of the code and can point out the remaining code?
Current thoughts:
Identify the outermost part of the stack associated with the obsolete functionality: the binary script calling it, or the unit tests calling it.
Look for methods that are only called by methods associated with the obsolete functionality. I often use git grep for this.
In theory, running mutation testing and looking for code that used to be mutation resistant when the old test suite applied, but is now mutation prone might help. It only helps if your code was well-tested in the first place! (Or you can use code coverage tools such as rcov rather than mutation testing)
Running test suites will ensure you haven't removed anything you shouldn't have!
Using autotest can save you time if you're constantly running tests.
If your code was well-structured, it should be easier to find related methods that need to be removed.
Especially in a dynamically typed language, there is no easy way to do this. If you have unittests, thank the developer that wrote them because it will help you remove the code correctly. But you're basically SOL. Remove the code, if it breaks, put it back, figure out where it broke, attempt to work around it, and repeat.
Look at your code coverage. Any code which isn't covered may be part of the code you have left to remove (if any). (Just be sure you have removed you tests. =])