Skip to content

Instantly share code, notes, and snippets.

@lsegal
Created April 6, 2010 05:49
Show Gist options
  • Select an option

  • Save lsegal/357264 to your computer and use it in GitHub Desktop.

Select an option

Save lsegal/357264 to your computer and use it in GitHub Desktop.
require 'yard'
class IncrementalArray
def initialize(block)
@block = block
@buffer = YARD::Parser::Ruby::Legacy::TokenList.new
end
def shift; fill_buffer; @buffer.shift end
def first; fill_buffer; @buffer.first end
def [](index) fill_buffer; @buffer[index] end
private
def fill_buffer
@buffer.push(@block.call) if @buffer.empty?
end
end
class IncrementalParser < YARD::Parser::Ruby::Legacy::StatementList
def initialize(&block) @tokens = IncrementalArray.new(block) end
public :next_statement
end
module YardObject
def source
return @source if @source
methname = owner.name + '#' + name.to_s
fname, line = *source_location
@@file_cache ||= {}
@@file_cache[fname] ||= File.readlines(fname)
@@method_cache ||= {}
if @@method_cache[methname]
@source = @@method_cache[methname]
else
ws = @@file_cache[fname][line-1][/^(\s+)/, 1]
parser = IncrementalParser.new { l = @@file_cache[fname][line-1]; line += 1; l }
@source = ws + parser.next_statement.to_s
end
end
end
class Method; include YardObject end
class UnboundMethod; include YardObject end
class Foo
# A docstring!
def foo
10.times do |i|
puts "hello world #{i}"
end
end
end
f = Foo.new
puts f.method(:foo).source
# def foo
# 10.times do |i|
# puts "hello world #{i}"
# end
# end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment