module MethodIntrospection::CodeHelpers
Public Instance Methods
#¶ ↑
comment_describing
¶ ↑
This method will retrieve the comment describing the expression on the given line of the given file.
This is useful to get the module or method documentation, in String format.
@param [Array<String>, File, String] file The file to parse, either as a File or as
a String or an Array of lines.
@param [Fixnum] line_number The line number at which to look.
NOTE: The first line in a file is line 1!
@return [String] The comment
#¶ ↑
# File lib/method_introspection/code_helpers.rb, line 52 def comment_describing(file, line_number) if file.is_a? Array lines = file else lines = file.each_line.to_a end # ======================================================================= # # At this point, lines is now an Array. We extract the proper lines # by making use of the line number. # ======================================================================= # extract_last_comment(lines[0..(line_number - 2)]) end
#¶ ↑
complete_expression?¶ ↑
Determine if a string of code is a complete Ruby expression.
@param [String] code The code to validate. @return [Boolean] Whether or not the code is a complete Ruby expression. @raise [SyntaxError] Any SyntaxError that does not represent incompleteness.
@Usage examples
complete_expression?("class Hello") # => false complete_expression?("class Hello; end") # => true complete_expression?("class 123") # => SyntaxError: unexpected tINTEGER
#¶ ↑
# File lib/method_introspection/code_helpers.rb, line 134 def complete_expression?(i) old_verbose = $VERBOSE $VERBOSE = nil catch(:valid) { eval("BEGIN{throw :valid}\n#{i}") } # Assert that a line which ends with a , or \ is incomplete. i !~ /[,\\]\s*\z/ rescue IncompleteExpression false ensure $VERBOSE = old_verbose # Reinstate the old verbosity level here. end
#¶ ↑
expression_at
¶ ↑
Retrieve the first expression starting on the given line of the given file.
This is useful to get module or method source code.
@param [Array<String>, File, String] file The file to parse, either as a File or as
@param [Fixnum] line_number The line number at which to look.
NOTE: The first line in a file is line 1!
@param [Hash] options The optional configuration parameters.
@option options [Boolean] :strict If set to true, then only completely
valid expressions are returned. Otherwise heuristics are used to extract expressions that may have been valid inside an eval.
@option options [Fixnum] :consume A number of lines to automatically
consume (add to the expression buffer) without checking for validity.
@return [String] The first complete expression
@raise [SyntaxError] If the first complete expression can't be identified
#¶ ↑
# File lib/method_introspection/code_helpers.rb, line 91 def expression_at( file, line_number, options = {} ) options = { :strict => false, :consume => 0 }.merge!(options) if file.is_a? Array lines = file else lines = file.each_line.to_a end relevant_lines = lines[(line_number - 1)..-1] || [] extract_first_expression(relevant_lines, options[:consume]) rescue SyntaxError => e raise if options[:strict] begin extract_first_expression(relevant_lines) { |code| code.gsub(/\#\{.*?\}/, "temp") } rescue SyntaxError raise e end end
Private Instance Methods
#¶ ↑
extract_first_expression
¶ ↑
Get the first expression from the input.
@param [Array<String>] lines @param [Fixnum] consume A number of lines to automatically
consume (add to the expression buffer) without checking for validity.
@yield a clean-up function to run before checking for complete_expression @return [String] a valid ruby expression @raise [SyntaxError]
#¶ ↑
# File lib/method_introspection/code_helpers.rb, line 160 def extract_first_expression(lines, consume = 0, &block) code = consume.zero? ? '' : lines.slice!(0..(consume - 1)).join lines.each { |entry| code << entry return code if complete_expression?(block ? block.call(code) : code) } raise SyntaxError, "unexpected $end" end
#¶ ↑
extract_last_comment
¶ ↑
Get the last comment from the input. We will build up the result.
@param [Array<String>] lines @return [String]
#¶ ↑
# File lib/method_introspection/code_helpers.rb, line 17 def extract_last_comment(lines) result = '' lines.each { |line| # ===================================================================== # # Add any line that is a valid ruby comment but stop the moment # we hit a non-comment line. # ===================================================================== # if (line =~ /^\s*#/) || (line =~ /^\s*$/) # =================================================================== # # Append onto result next. In the past we called .lstrip() here but # this is no longer legal as we modify the original comment. # =================================================================== # result << line else result.replace("") end } return result end