How to see the source code for an "update!' method - ruby

I have a web site that is killed due to a memory overflow. It is triggered during a PUT request coming from a users web browser. Unfortunately, the logs are not helpful in this case. I have traced the issue down to this method definition:
# app/controllers/registrations/profiles_controller.rb
def update
update! do |success, failure|
success.html { redirect_to edit_registration_diagnosis_path }
failure.html do
build_diagnosis
render 'edit'
end
end
end
I want to see the source code for this update! method. How do I ask ruby or rails or bash/grep to show me this source code?
I tried:
git grep 'def update!' # no results
My env:
$ rails --version
Rails 3.2.22.5
$ ruby --version
ruby 1.9.3p551

The libraries are not in the same directory as your Rails app, they'll be wherever your Ruby versions are, which differs depending on which version manager you used to install it.
The Rails docs are online at http://api.rubyonrails.org/, or you could use a gem like pry-byebug to step into the method during execution. As Ruby is object oriented and uses an inheritance chain to find an object that responds to a given message, this is the best way to really know which method is being called at any given point in the application's execution.
Add gem 'pry-byebug' to your gemfile, bundle install and then insert binding.pry at the top of your update method. Once execution pauses you can easily step into the method.

You can use byebug gem to see what is happening at each step in your method.

As others have said, the code in your app is not the full set of code that is running. So grep won't work here. You may also run into the issue where the same method is defined multiple times, and grep won't help there, either.
The best solution I've found is using pry. It looks like this is a Rails project, so you can get results most easily by adding the following to your Gemfile:
# Gemfile
gem "pry-rails"
gem "pry-doc"
At this point, the world is your oyster.
The easiest way to start learning how to use this is to add a binding.pry in your code execution where you want to explore. Then run the code in test or development environments, and your server will stop and give you a console at that line. Then you just show-source update! and you'll see where the method is defined.
So step 1, use pry and explore its many plugin libraries.
Step 2 is to try out solargraph in your text editor. It's not as powerful as pry, but it can help you jump to method definitions within your project easily. https://solargraph.org
Step 3 check out the premium text editor RubyMine, as it has support for this sort of thing and much more, though it's not free. https://www.jetbrains.com/help/ruby/getting-started.html

Related

NoMethodError 'route' for main:Object in Sinatra app (Ruby 2.0.0p481)

I'm working on a Sinatra app (not one that I developed) in Ruby 2.0.0p481, as the title says. When I try to run the program to test my controller method, I get an undefined method 'route' error.
require 'sinatra'
...
route :get, :post, '/parsedresume' do
I know the code functions in production, but when I try to test it on my local machine, it's causing nothing but problems, and I'm not sure where to start. I think it's probably something silly and dumb that I'm forgetting, but I've exercised the full might of my google-fu and haven't found anything.
Thanks for the help!
Refactoring is hard as hell.
route :get, :post ... doesn't look as Sinatra route. Usually routes in pure Sinatra application defined as get '/' do ... or post '/' do .... Not sure about that, but such method isn't mentioned in Sintra Documentation. May be is there another framework on top of Sinatra?
I'm not sure where to start
Try to start with the following.
Reproduce production environment as precise as you can.
I mean:
Ruby version as first step. Should be same. On production Ruby may be the part of system i.e. installed via packages. You may use rvm or rbenv or etc on your dev environment. Make sure you have checked ps auxww | grep -i ruby output, in order to be confident that your production uses Ruby you have found before. It's not joke. System Ruby may be installed, however e.g. JRuby may be used in project...
Versions of gems. Should be the same. You are lucky of project has Gemfile.lock. If it doesn't, you can only rely on output of gem list. Try to examine dependencies of Application and install exact versions of packeges.
Hardcoded paths in Application. Sad but true. It is up to you: change them in code, or spoof on dev environment.
This is not so comprehensive answer, hope is may be good starting point for your situation. Feel free to ask more. By the way, Ruby stack trace may be very helpful.
Good luck!

Ruby code auto-reloaded without Rails

Working with Rails, Sinatra, Padrino... I got used to my code being auto-reloaded when I made modifications.
How can I get the same behavior while working on plain Ruby gem projects which are not a Rack based web framework.
I would like to just launch a pry console and inmediatly being able to test the latest modifications of my source code.
You just need to define a method somewhere that clears the old stuff from memory, and re-load all of the files that comprise your gem:
def reload!
Object.send(:remove_const, :ProjectNamespace)
path = File.expand_path("../", __FILE__)
Dir.glob("#{path}/**/*.rb") { |f| load f }
end
Since you're using Pry, you can define this in your project's .pryrc if you'd like to keep it out of your the code base.
You can even define the reload logic within your inside your module, and for as long as its included among the files you're reloading, all will be well:
module ProjectNamespace
module_function
def reload!
# Reload code
end
end
ProjectNamespace.reload!
If you're in need of a more managed solution (e.g. timed reloads) you should look into a library like Rubyworks' autoreload.
I would create a run.rb script that forks a process and runs your code in that separate process. Using https://github.com/thibaudgg/rb-fsevent in the parent process to watch your file system for changes, kill the child process whenever a FS change is detected and fork a new child with your updated code.
After some exploration and trying the given answers, I realized that I was thinking about my problem the wrong way.
Although it is nice having a project reload, this requires certain preparation.
For Ruby I find far more convenient having a custom shortcut on my editor to:
save file
send a load file/path.rb command to my Pry session
That does not require any type of extra code or configuration for each project. However the other answers can be combined with Guard to have auto-reloads. That was actually the title of my question, but now I realized that one keystroke solution is more practical.

How to traverse through Source code only using debugger - Rails 3.2.13

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

Use Pry in gems without modifying the Gemfile or using `require`

I am trying to debug a gem that's used by a Rails app.
I cloned the Gem locally to go prying around (and also allows me to do nice things such as git bisect, etc.)
# Gemfile
gem "active_admin", path: "~/dev-forks/active_admin"
However, I am often stuck with adding Pry to a Gemfile somewhere to be able to use it, or calling require "pry" live in the code even though I don't want it in there. For example, I will sometimes forget about it, fix the bug, and then commit to the project with Pry in the Gemfile.
Should I not do that, a LoadError will arise, cannot load such file -- pry (LoadError).
I have to admin I'm a bit lost between the different contexts (Rails project, Gem, local Ruby) and actual gems (Gemfile, require, installed).
How can I use binding.pry in a Gem within Rails, without intervention of the Gemfiles?
Jon from the past! As you know, I have the answers to (almost) all your problems.
In this case, you're actually describing two problems: (a) you can't require 'pry' when Pry is not in the Gemfile, (b) you can't use Pry if you don't require it.
What Bundler does, as Conrad Irwin writes:
Bundler is an awesome gem that gives you a good degree of confidence that "if it works in development, it works in production". It can do this by being vicious about gem dependencies: if it's not in the Gemfile, it's not getting required. It also ensures that everyone's development environment is identical, no more does "it works on my machine" cut it as an excuse.
There are circumstances when this dogmatic dedication to duty can get in the way. In particular all good developers have set up their development environment very personally. Obviously, it's not important that my local tools work in production, and it's positively bad for productivity if everyone is forced to have an identicial development setup.
So in doing all the good things Bundler does for us Ruby developers, it comes by design with a caveat: "what's outside the bundle/Gemfile (eg system gems) doesn't exist anymore." How it does that is by redefining the require process and changes your PATH so that it only sees what's in the bundle.
That means you can't use Pry at all without polluting the Gemfile, you say, right? Not so fast. Conrad Irwin being the smart little cookie that he is, came up with a solution and made Pry Debundle, a gem that temporarily reverses the patches Bundler made to our require.
So all you have to do is just require 'pry-debundle' then, right? Oh... wait. Yep, Debundle is probably not in the Gemfile.
The monkey fix is to hard copy the source of pry-debundle.rb to ~/debundle.rb, and then load that. (For now, you'll need Pry loaded to run that source file, but you can run only the debundle! method to get there, require Pry, and go prying around. A little monkeypatching is needed, but I'm working on a PR.)
if you want to use and debug a gem in your rails app, then it should be in the development and test group of the Gemfile in your app.
you can use tools like pry-debugger https://github.com/nixme/pry-debugger to set breakpoints in your pry session break SomeClass#run.
i think it's valid to add pry to every project that i fork to fix a bug or contribute stuff. just don't put it in the .gemspec files.
if you are pushing binding.pry changes to your repo, you should add commit hooks like Jim pointed out. i don't think that this is a pry related issue, it's dependent on how much care you take when reviewing your diff before pushing it out.

Ruby beginner - using /modifying existing gems in single project

As the title states, I'm a beginner in Ruby.
My project uses 2 existing gems - which I want to modify.
I've forked the gems on GitHub and put them as modules in my repo and they show up as a subdirectory.
I've tried researching this, but I keep on getting lost - I'm thinking I'm missing some basic concepts/knowledge here.
My questions:
Am I going about this right/wrong?
Is it even possible to include the code of those (forked) gems in my actual project, or should I update them separately and just use them as actual gems with require (this seems very cumbersome)
If these gems are part of my project, how do I use them properly, I assume I don't need the require piece? If not, how do I access/use them?
Thanks!
BTW, using Ruby 1.9.2-p194 on Ubuntu with RubyMine as the IDE.
Probably wrong. Ruby is a very flexible language, and has what are called open classes. This means that you can open up and change classes at run-time. Doing this on an external library is called monkey patching. So instead of having to replicate all of the code you want to stay consistent, you can just modify the classes and override any methods you want.
A simple example:
class Fixnum
def is_multiple_of_three?
self % 3 == 0
end
end
However, if the changes you want are really significant, it could make sense to fork the gem.
I recommend the bundler gem. This will let you make a Gemfile which lists all of your dependencies. You can list a github repository as a source for the gem, like so:
gem 'gem_name_here', :git => 'git://github.com/username_here/gem_name_here.git'
and then run bundle install to install your dependencies.
If you install the gems with bundler, it acts just like any other gem you have installed.

Resources