Sha256: 8013aad384e476b4485a0aad4e7f1f50d5a440d41f297ac865a72e15770a1e76

Contents?: true

Size: 1.69 KB

Versions: 6

Compression:

Stored size: 1.69 KB

Contents

require 'ripper'
require 'pp'
class Proc

  TOKEN_PAIRS = {[:on_lbrace, '{']  => [:on_rbrace, '}'],
                 [:on_kw, 'do']     => [:on_kw, 'end'],
                 [:on_tlambeg, '{'] => [:on_rbrace, '}']}

  # Make a best effort to provide the original source for a block
  # based on extracting a string from the file identified in
  # Proc#source_location using Ruby's tokenizer.
  #
  # This works for first block declared on a line in a source
  # file.  If additional blocks are specified inside the first block
  # on the same line as the start of the block, only the outer-most
  # block declaration will be identified as a the block we want.
  #
  # If you require only the source of blocks-within-other-blocks, start them
  # on a new line as would be best practice for clarity and readability.
  def source
    file, line_no = source_location
    raise "no line number provided for source_location: #{self}" if line_no.nil?
    tokens =  Ripper.lex File.read(file)
    tokens_on_line = tokens.select {|pos, lbl, str| pos[0].eql?(line_no) }
    starting_token = tokens_on_line.detect do |pos, lbl, str| 
      TOKEN_PAIRS.keys.include? [lbl, str] 
    end
    starting_token_type = [starting_token[1], starting_token[2]]
    ending_token_type = TOKEN_PAIRS[starting_token_type]
    source_str = ""
    remaining_tokens = tokens.slice(tokens.index(starting_token)..-1)
    nesting = -1
    while token = remaining_tokens.shift
      source_str << token[2]
      nesting += 1 if [token[1], token[2]] == starting_token_type
      is_ending_token = [token[1], token[2]].eql?(ending_token_type)
      break if is_ending_token && nesting.eql?(0)
      nesting -= 1 if is_ending_token
    end
    source_str
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
express_templates-0.2.7 lib/core_extensions/proc.rb
express_templates-0.2.6 lib/core_extensions/proc.rb
express_templates-0.2.5 lib/core_extensions/proc.rb
express_templates-0.2.4 lib/core_extensions/proc.rb
express_templates-0.2.3 lib/core_extensions/proc.rb
express_templates-0.2.2 lib/core_extensions/proc.rb