In IRB, can I view the source of a method I defined earlier?
Asked Answered
G

5

21

If I define a method in IRB, is there any way to review its source later in the session?

> def my_method
>   puts "hi"
> end

Several screens of output later I'd like to be able to write something like

> source my_method

and get back:

=> def my_method; puts "hi"; end;

Is this possible?

Glottis answered 25/8, 2011 at 12:15 Comment(0)
C
17

Try pry. There is a railscast about it (released this same week!) and it shows you how to show the code by using show-method.

Childhood answered 25/8, 2011 at 12:20 Comment(0)
M
20

Not in IRB but in Pry this feature is built-in.

Behold:

pry(main)> def hello
pry(main)*   puts "hello my friend, it's a strange world we live in"
pry(main)*   puts "yes! the rich give their mistresses tiny, illuminated dying things"
pry(main)*   puts "and life is neither sacred, nor noble, nor good"
pry(main)* end
=> nil
pry(main)> show-method hello

From: (pry) @ line 1:
Number of lines: 5

def hello
  puts "hello my friend, it's a strange world we live in"
  puts "yes! the rich give their mistresses tiny, illuminated dying things"
  puts "and life is neither sacred, nor noble, nor good"
end
pry(main)> 
Maxie answered 25/8, 2011 at 13:27 Comment(3)
irb implements this feature in 2022. See my answer for details.Wakerife
yeah, it stole pry's code with no attributionMaxie
This is not an appropriate place to discuss such a thing, but AFAIK the code of irb and that of pry are different enough... I'm not sure why you've used such a strong word.Wakerife
C
17

Try pry. There is a railscast about it (released this same week!) and it shows you how to show the code by using show-method.

Childhood answered 25/8, 2011 at 12:20 Comment(0)
L
5

If you use Ruby 1.9.2 and a newer version of the sourcify gem than available on Rubygems.org (e.g. build the source from GitHub), you can do this:

>> require 'sourcify'
=> true
>> 
..   class MyMath
..     def self.sum(x, y)
..         x + y # (blah)
..       end
..   end
=> nil
>> 
..   MyMath.method(:sum).to_source
=> "def sum(x, y)\n  (x + y)\nend"
>> MyMath.method(:sum).to_raw_source
=> "def sum(x, y)\n    x + y # (blah)\n  end"

Edit: also check out method_source, which is what pry uses internally.

Leap answered 25/8, 2011 at 12:48 Comment(1)
As I said you need Ruby 1.9.2 and a version of sourcify that's newer than the one currently available on Rubygems.org (I built mine from the Git repo). I updated my post to make this more clear.Leap
H
5

What I use is method_source I have method code which is basically my wrapper for this gem. Add method_source in Gemfile for Rails apps. And create initializer with following code.

  # Takes instance/class, method and displays source code and comments
  def code(ints_or_clazz, method)
    method = method.to_sym
    clazz = ints_or_clazz.is_a?(Class) ? ints_or_clazz : ints_or_clazz.class
    puts "** Comments: "
    clazz.instance_method(method).comment.display
    puts "** Source:"
    clazz.instance_method(method).source.display
  end

Usage is:

code Foo, :bar

or with instance

code foo_instance, :bar

Better approach is to have class with in /lib folder with your irb extension, than you just require it in one of initializers (or create your own)

Hirai answered 19/4, 2012 at 15:45 Comment(1)
Super handy, thanks! Portable & self-contained, will work regardless of whether or not pry happens to be installedSunny
W
0

After irb v1.3.5, irb itself implements show_source and its alias $. You can show method definitions like the following.

irb(main):001> IRB::VERSION
=> "1.12.0"
irb(main):002* def foo
irb(main):003*   puts "hi"
irb(main):004> end
=> :foo
irb(main):005> show_source foo

From: (irb):2

def foo
  puts "hi"
end

=> nil
irb(main):006> $ foo

From: (irb):2

def foo
  puts "hi"
end

=> nil
irb(main):007> # For instance methods
=> nil
irb(main):008* class A
irb(main):009*   def bar
irb(main):010*     puts "hello from A"
irb(main):011*   end
irb(main):012> end
=> :bar
irb(main):013* class B < A
irb(main):014*   def bar
irb(main):015*     puts "hello from B"
irb(main):016*     super
irb(main):017*   end
irb(main):018> end
=> :bar
irb(main):019> $ B#bar

From: (irb):14

def bar
    puts "hello from B"
    super
  end

=> nil
irb(main):020> $ B#bar --super

From: (irb):9

def bar
    puts "hello from A"
  end

=> nil
Wakerife answered 26/3 at 0:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.