4d1c9dad17af98e55cb65b4efce27c42

this code evaluates a string as the argument array. so ":abc, :def => 123" would be sent to line_eval as [:abc, {:def => 123}]. The while loop makes sure ":abc, [:def, :ghi], :jkl" is evaluated as [:abc, [:def, :ghi], :jki], not [:abc, :def, :ghi, :jkl]. It's dirty.

def args_eval(line)
  tokens = []
  while(data = line.match(/\[.*\]/))
    data.pre_match.split(',').each {|s| tokens << s}
    tokens << tokens.pop + data[0]
    line = data.post_match
  end
  
  line.split(',').each {|s| tokens << s}
  hash_tokens = []
  
  tokens.reverse.each do |token|
    break unless token =~ /=>/
    
    hash_tokens << tokens.pop
  end
  
  if tokens.empty?
    tokens = hash_tokens.pop.split(/=>/)
  end
  
  line_eval("[#{tokens.join(',')}#{', ' unless tokens.empty? || hash_tokens.empty?}#{hash_tokens.empty? ? '' : "{#{hash_tokens.reverse.join(',')}}"}]")
end

Refactorings

No refactoring yet !

7c45f63f61e478233f0c2ad3006b178c

michiel

October 23, 2007, October 23, 2007 11:33, permalink

No rating. Login to rate!

And you don't use "eval" because you don't trust the caller? What does "line_eval" do?
Also, use "scan" to break up the entire line in tokens (square brackets, commas, => and others).
You could even use something like Racc (http://i.loveruby.net/en/projects/racc/doc/) to generate a parser for you. Overkill, I know, but a nice exercise, and with only four tokens it can't be hard.

Your refactoring





Format Copy from initial code

or Cancel