If I defined a Ruby method in IRB, how do I edit that method without retyping everything?
Asked Answered
U

6

20

Say I am running IRB and I type this into the console:

def full_name(first, last)
   puts "Your full name is: #{first, ' ', last}"
end

Say, that I wanted to edit that to include the parameter middle, how would I just bring back up that same method and edit the parameter list and edit the puts statement without having to retype the entire method?

P.S. I know that this example is simple and I could easily just retype the method, but I have much larger methods I am experimenting with and I am using this simple one for brevity.

Thanks.

Uniformize answered 12/3, 2012 at 22:58 Comment(1)
i don't think it is possible. it is just a interpreter, running your code line by line.Jamima
H
17

You can't. Other than retyping/repasting it, or pressing to get all the previous statements, but for longer methods this can be very confusing.

Why not type your code in an editor, and then do load 'mycode.rb' in IRb? This is essentially equivalent to copy-and-pasting the text in, and calling load 'myfile.rb' again will, as usual, override the existing method definitions.

Or, even better, use Pry instead of IRB as suggested by bannister below (I completely replaced IRB with Pry long ago myself).

Hinman answered 12/3, 2012 at 23:4 Comment(5)
This is perfect. Is there anyway to force IRB to reload my file once I make a change and save it in my text editor? Or do I have to 're-load' it?Uniformize
@Uniformize Not that I know of, you'd probably have to monkey-patch IRb to do something like that unless there's already a Gem to do so.Hinman
@marcamillion: You could use a hack like running IRB in a GNU screen session and making your editor inject the code after every save. People have done it.Freeforall
@NiklasB. Wow that just seems crazy. I don't think I ever do enough messing around with large functions in IRb to ever even want to do that. Running !ruby % in Vim is so much easier :).Hinman
@Andrew as you might notice, it's kind of awkward to do this in IRB ;) note my answer below for how to do it in Pry, which naturally supports this kind of thing :)Twophase
T
13

You can do this easily in Pry (a much more powerful alternative to IRB), simply use the edit-method command to reopen the method in an editor as follows:

[19] (pry) main: 0> def full_name(first, last)
[19] (pry) main: 0*   puts "Your full name is: #{first + '' + last}"  
[19] (pry) main: 0* end  
=> nil
[20] (pry) main: 0> edit full_name
Waiting for Emacs...
=> nil
[21] (pry) main: 0> show-method full_name

From: (pry) @ line 32:
Number of lines: 3
Owner: Object
Visibility: public

def full_name(first, middle, last)
  puts "Your full name is: #{first + middle + last}"
end
[22] (pry) main: 0> full_name "Stephen ", "william ", "Hawking"
Your full name is: Stephen william Hawking
=> nil
[23] (pry) main: 0> 

Pry automatically reloads the method after editing is complete (the editor pry uses can also be configured)

Twophase answered 13/3, 2012 at 0:47 Comment(0)
F
6

I don't think you have a lot of options here. What I usually do is to place the code I'm playing with in a file and use load '/path/to/file.rb' to reload it whenever I change something.

You can also try the interactive_editor gem which allows you to use a full-blown text editor for text editing inside an IRB session.

Freeforall answered 12/3, 2012 at 23:4 Comment(7)
+1 Since our answers were essentially the same and at the same time :).Hinman
@Niklas, for an alternative to IRB that naturally supports this kind of thing (and much more powerful than interactive_editor) check out PryTwophase
@banister: I know about pry, but it also doesn't support multiline editing. edit-method is in fact less effective than the interactive_editor approach, IMHOFreeforall
@Niklas how exactly is the interactive_editor approach more effective? :). Also do you know about the edit command as well? No pure-readline approach can support 'true' multiline editing, but pry does the best possible, IMO. And for the OP's particular question, I believe edit-method is the best solution.Twophase
@banister: Nobody said anything about pure-readline. zsh and IPython manage to provide true multiline editing, so it's at least possible. rb-readline could in theory be adapted to do this. interactive_editor is in my opinion a bit more effective because you don't have to supply the method name. You just open up the editor and edit whatever class or function you want to change, then close the editor again. In VIM or EMACS, I can work blazingly fast.Freeforall
@NiklasB, without wanting to drag the point on for too long --- you simply do not know about Pry, you appear to think edit-method is the only form of editor support it has, this is false. edit-method is just the most appropriate form for the OP. Read the docs. Also (as i mentinoed above) IPython does not provide 'true multiline' support, see the following issue: github.com/ipython/ipython/issues/571 (though it appears they may have reenabled it in some of the recent commits).Twophase
@banister: I use pry a lot, especially for interaction with a running application. It's great, but it's not fundamentally different from IRB when it comes to multiline editing or editor integration (given that IRB is armed with the right set of plugins). zsh does a much better job at multiline-editing, although it's not even needed very often.Freeforall
C
3

Check out the pry gem - a great replacement for IRB. This features might be helpful:

  • hist - replaying history of commands
  • amend-line - changing a line in a mulit-line entry

They are well documented on the pry wiki

Corespondent answered 13/3, 2012 at 0:5 Comment(5)
@Niklas he doesn't want 'multiline editing' he wants to re-edit a method definition. edit-method lets him do this. It appears to be exactly what he wants.Twophase
@banister: I think what he really wants is something like zsh- or IPython-like multiline editing editing, not using an external editor. Neither IRB nor Pry support this (and this answer also doesn't even mention edit-method, so it's not very helpful).Freeforall
@Niklas Your solution uses an external editor, too. My argument is just that edit-method is more on-point (regarding the question) than a more general 'external editor' solution. Also IPython (readline-based) no longer supports that 'multiline editing' -- for the simple reason it's not real multiline; it's squashing multiple lines into a single line and it's awkward to navigate.Twophase
@Niklas I only gave the link to pry since it has a lot of great documentation. IMHO there is no point in copy-pasting contents from other resources. If you consulted the pry wiki you would find, that you are wrong (check for hist and amend-line).Corespondent
@AleksanderPohl: I didn't know about amend-line, this is a great feature :) Thanks for pointing it out. (+1)Freeforall
M
2

Starting with the Ruby version 2.7.0-preview1, it is possible to edit in IRB sessions if you press the button:

irb multiline edit

Source: https://www.ruby-lang.org/en/news/2019/05/30/ruby-2-7-0-preview1-released/

Mikes answered 14/7, 2019 at 10:24 Comment(0)
L
1

You can edit this via irb or pry (which I would strongly recommend) - but you'll need to retype the whole thing. If you think about it one method isn't that difficult to type out :P However, if you have more than one method enclosed in a class, it can be very tedious to retype the entire class and corresponding methods. What you can do in that case is use class_evals.

Class Name
     def full_name(first, last)
       puts "Your full name is: #{first + ' ' + last}"
    end
end

# NEW Edited Code

Name.class_eval do 
  def full_name(first, middle, last)
    puts "Your full name is: #{first + ' ' + middle + ' ' + last}"
  end 
end

Here's a good resource to read about re-opening classes/monkeypatching and here's another that warns about the bad effects of monkeypatching

Lithea answered 6/2, 2014 at 19:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.