Robert A Henru
Robert A Henru

Reputation: 2272

Can I repeat command in irb?

Is there an easy way to repeat a previous command in Ruby irb? I wish to have something like using exclamation mark (!) in Unix.

Thank you.

Upvotes: 6

Views: 3567

Answers (8)

Kenneth Wagner
Kenneth Wagner

Reputation: 121

You can also backtrace commands in irb by starting it with

irb --tracer

Now the up arrow will go back thru the irb commands. (Using Ruby 2.3.3)

Upvotes: 0

horseyguy
horseyguy

Reputation: 29915

Aside from pressing up arrow and enter, the Pry REPL let's you reply entire expressions (rather than just lines) using the play -i command:

see here:

[31] (pry) main: 0> (1..5).map do |v|
[31] (pry) main: 0*   v * 2
[31] (pry) main: 0* end  
=> [2, 4, 6, 8, 10]
[32] (pry) main: 0> play -i 31
=> [2, 4, 6, 8, 10]
[33] (pry) main: 0> 

You simply pass to play -i the expression number (the number in [] adjacent to the prompt) for the code you want to replay.

For more info on the play command see the wiki page also check out the Entering input for other tricks related to using and manipulating input history

Alternatively, if you want to just replay individual lines of history, you can first view history using the hist command and then replay it using hist --replay as follows:

[37] (pry) main: 0> puts "hello world"
hello world
=> nil
[38] (pry) main: 0> hist --tail
9699: _file_
9700: (1..10).map do |v|
9701: (1..5).map do |v|
9702:   v * 2
9703: end
9704: play -i 31
9705: _
9706: hist --tail
9707: hist -r
9708: puts "hello world"
[39] (pry) main: 0> hist --replay 9708
hello world
=> nil
[41] (pry) main: 0> 

Alternatively, if you just want to replay the last line input, and you don't want to use up arrow (for whatever reason) then simply use: hist --replay -1. As always the wiki contains more info on the hist command.

Upvotes: 6

shime
shime

Reputation: 9018

Somewhat related.

In IRB, the result of the last executed command is saved in _. You can also use that one.

Example

1.9.3p194 :001 > 2 + 2
 => 4 
1.9.3p194 :002 > _
 => 4 
1.9.3p194 :003 > _ * 3
 => 12 
1.9.3p194 :004 > _
 => 12 

This proved to be very useful for me, especially in rails console.

Upvotes: 3

Lars Haugseth
Lars Haugseth

Reputation: 14881

The quickest way to repeat (or modify) an earlier command that is more than just a couple of steps back in the history, is to search for it by typing Ctrl+R followed by some substring of the command in question.

For more keyboard shortcuts provided by the GNU Readline library, look here. They are supported by many shells and other applications as well.

Upvotes: 3

kfb
kfb

Reputation: 6532

I don't think there's any kind of numbered history support (such as like gdb), but you can use the arrow keys to navigate through history, the same as you can in the shell.

Update

Turns out I'm completely wrong, and Hooopo is right; you can access the history via the IRB.CurrentContext.io.line method, so

eval IRB.CurrentContext.io.line <line number>

will repeat the command. As Hooopo also says, wrapping this in a method works correctly:

def r(number)
  eval IRB.CurrentContext.io.line number
end

then

ruby-1.9.3-p0 :004 > puts "hello"
hello
 => nil 
ruby-1.9.3-p0 :005 > r 004 # (or 'r 4')
hello
 => nil 

Upvotes: 2

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84433

The irb REPL doesn't natively support history expansion, which is what you seem to be looking for. For a solid alternative, the pry REPL offers the replay command.

Upvotes: 1

Hooopo
Hooopo

Reputation: 1400

def repeat_last_irb
  eval(IRB.CurrentContext.io.line(-2))
end

then you can use replat_last_irb in you irb console to run last input.

IRB.CurrentContext.io is like this below:

ruby-1.9.3-p0 :001 > def hello
ruby-1.9.3-p0 :002?>   end
 => nil 
ruby-1.9.3-p0 :003 > IRB.CurrentContext.io
 => #<IRB::ReadlineInputMethod:0x00000001c7b860 @file_name="(line)", @line_no=3, @line=[nil, "def hello\n", "end\n", "IRB.CurrentContext.io\n"], @eof=false, @stdin=#<IO:fd 0>, @stdout=#<IO:fd 1>, @prompt="ruby-1.9.3-p0 :003 > "> 

this Object save irb all io info, and with a line method to get every line you input.

so, we can use eval to repeat last input.

Upvotes: 11

seph
seph

Reputation: 6076

Up arrow gets you history line by line. Pry has more goodies but I haven't tried it yet.

Upvotes: 8

Related Questions